From cff4f4fb4eeef67d7e0ff995b8d52190d9a62c2a Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Tue, 15 Sep 2020 19:43:59 -0500 Subject: [PATCH 1/7] fix compiler warning --- src/runtime/pyansistring.cs | 28 ++++++++----- src/runtime/pydict.cs | 6 +-- src/runtime/pyfloat.cs | 46 +++++++++++++-------- src/runtime/pyint.cs | 48 ++++++++++++++-------- src/runtime/pyiter.cs | 17 +++++--- src/runtime/pylist.cs | 45 ++++++++++++--------- src/runtime/pylong.cs | 79 ++++++++++++++++++++++--------------- src/runtime/pynumber.cs | 6 --- src/runtime/pyobject.cs | 11 ------ src/runtime/pysequence.cs | 4 -- src/runtime/pystring.cs | 28 ++++++++----- src/runtime/pytuple.cs | 44 ++++++++++++--------- 12 files changed, 207 insertions(+), 155 deletions(-) diff --git a/src/runtime/pyansistring.cs b/src/runtime/pyansistring.cs index 185cc6c94..1035e4945 100644 --- a/src/runtime/pyansistring.cs +++ b/src/runtime/pyansistring.cs @@ -17,6 +17,16 @@ public PyAnsiString(IntPtr ptr) : base(ptr) } + private static IntPtr FromObject(PyObject o) + { + if (!IsStringType(o)) + { + throw new ArgumentException("object is not a string"); + } + Runtime.XIncref(o.obj); + return o.obj; + } + /// /// PyString Constructor /// @@ -25,14 +35,14 @@ public PyAnsiString(IntPtr ptr) : base(ptr) /// An ArgumentException will be thrown if the given object is not /// a Python string object. /// - public PyAnsiString(PyObject o) + public PyAnsiString(PyObject o) : base(FromObject(o)) { - if (!IsStringType(o)) - { - throw new ArgumentException("object is not a string"); - } - Runtime.XIncref(o.obj); - obj = o.obj; + } + private static IntPtr FromString(string s) + { + IntPtr val = Runtime.PyString_FromString(s); + PythonException.ThrowIfIsNull(val); + return val; } @@ -42,10 +52,8 @@ public PyAnsiString(PyObject o) /// /// Creates a Python string from a managed string. /// - public PyAnsiString(string s) + public PyAnsiString(string s) : base(FromString(s)) { - obj = Runtime.PyString_FromString(s); - PythonException.ThrowIfIsNull(obj); } diff --git a/src/runtime/pydict.cs b/src/runtime/pydict.cs index 7ff7a83c8..265b6c419 100644 --- a/src/runtime/pydict.cs +++ b/src/runtime/pydict.cs @@ -29,9 +29,8 @@ public PyDict(IntPtr ptr) : base(ptr) /// /// Creates a new Python dictionary object. /// - public PyDict() + public PyDict() : base(Runtime.PyDict_New()) { - obj = Runtime.PyDict_New(); if (obj == IntPtr.Zero) { throw new PythonException(); @@ -47,14 +46,13 @@ public PyDict() /// ArgumentException will be thrown if the given object is not a /// Python dictionary object. /// - public PyDict(PyObject o) + public PyDict(PyObject o) : base(o.obj) { if (!IsDictType(o)) { throw new ArgumentException("object is not a dict"); } Runtime.XIncref(o.obj); - obj = o.obj; } diff --git a/src/runtime/pyfloat.cs b/src/runtime/pyfloat.cs index d6fb55f26..640acaf4e 100644 --- a/src/runtime/pyfloat.cs +++ b/src/runtime/pyfloat.cs @@ -4,7 +4,6 @@ namespace Python.Runtime { /// /// Represents a Python float object. See the documentation at - /// PY2: https://docs.python.org/2/c-api/float.html /// PY3: https://docs.python.org/3/c-api/float.html /// for details. /// @@ -31,14 +30,8 @@ public PyFloat(IntPtr ptr) : base(ptr) /// ArgumentException will be thrown if the given object is not a /// Python float object. /// - public PyFloat(PyObject o) + public PyFloat(PyObject o) : base(FromObject(o)) { - if (!IsFloatType(o)) - { - throw new ArgumentException("object is not a float"); - } - Runtime.XIncref(o.obj); - obj = o.obj; } @@ -48,12 +41,36 @@ public PyFloat(PyObject o) /// /// Creates a new Python float from a double value. /// - public PyFloat(double value) + public PyFloat(double value) : base(FromDouble(value)) + { + } + + private static IntPtr FromObject(PyObject o) + { + if (!IsFloatType(o)) + { + throw new ArgumentException("object is not a float"); + } + Runtime.XIncref(o.obj); + return o.obj; + } + + private static IntPtr FromDouble(double value) { - obj = Runtime.PyFloat_FromDouble(value); - PythonException.ThrowIfIsNull(obj); + IntPtr val = Runtime.PyFloat_FromDouble(value); + PythonException.ThrowIfIsNull(val); + return val; } + private static IntPtr FromString(string value) + { + using (var s = new PyString(value)) + { + IntPtr val = Runtime.PyFloat_FromString(s.obj, IntPtr.Zero); + PythonException.ThrowIfIsNull(val); + return val; + } + } /// /// PyFloat Constructor @@ -61,13 +78,8 @@ public PyFloat(double value) /// /// Creates a new Python float from a string value. /// - public PyFloat(string value) + public PyFloat(string value) : base(FromString(value)) { - using (var s = new PyString(value)) - { - obj = Runtime.PyFloat_FromString(s.obj, IntPtr.Zero); - PythonException.ThrowIfIsNull(obj); - } } diff --git a/src/runtime/pyint.cs b/src/runtime/pyint.cs index 31295c899..7f05d08cd 100644 --- a/src/runtime/pyint.cs +++ b/src/runtime/pyint.cs @@ -31,16 +31,26 @@ public PyInt(IntPtr ptr) : base(ptr) /// ArgumentException will be thrown if the given object is not a /// Python int object. /// - public PyInt(PyObject o) + public PyInt(PyObject o) : base(FromObject(o)) + { + } + + private static IntPtr FromObject(PyObject o) { if (!IsIntType(o)) { throw new ArgumentException("object is not an int"); } Runtime.XIncref(o.obj); - obj = o.obj; + return o.obj; } + private static IntPtr FromInt(int value) + { + IntPtr val = Runtime.PyInt_FromInt32(value); + PythonException.ThrowIfIsNull(val); + return val; + } /// /// PyInt Constructor @@ -48,10 +58,8 @@ public PyInt(PyObject o) /// /// Creates a new Python int from an int32 value. /// - public PyInt(int value) + public PyInt(int value) : base(FromInt(value)) { - obj = Runtime.PyInt_FromInt32(value); - PythonException.ThrowIfIsNull(obj); } @@ -62,10 +70,8 @@ public PyInt(int value) /// Creates a new Python int from a uint32 value. /// [CLSCompliant(false)] - public PyInt(uint value) + public PyInt(uint value) : base(FromLong(value)) { - obj = Runtime.PyInt_FromInt64(value); - PythonException.ThrowIfIsNull(obj); } @@ -75,10 +81,15 @@ public PyInt(uint value) /// /// Creates a new Python int from an int64 value. /// - public PyInt(long value) + public PyInt(long value) : base(FromLong(value)) { - obj = Runtime.PyInt_FromInt64(value); - PythonException.ThrowIfIsNull(obj); + } + + private static IntPtr FromLong(long value) + { + IntPtr val = Runtime.PyInt_FromInt64(value); + PythonException.ThrowIfIsNull(val); + return val; } @@ -89,10 +100,8 @@ public PyInt(long value) /// Creates a new Python int from a uint64 value. /// [CLSCompliant(false)] - public PyInt(ulong value) + public PyInt(ulong value) : base(FromLong((long)value)) { - obj = Runtime.PyInt_FromInt64((long)value); - PythonException.ThrowIfIsNull(obj); } @@ -142,16 +151,21 @@ public PyInt(sbyte value) : this((int)value) } + private static IntPtr FromString(string value) + { + IntPtr val = Runtime.PyInt_FromString(value, IntPtr.Zero, 0); + PythonException.ThrowIfIsNull(val); + return val; + } + /// /// PyInt Constructor /// /// /// Creates a new Python int from a string value. /// - public PyInt(string value) + public PyInt(string value) : base(FromString(value)) { - obj = Runtime.PyInt_FromString(value, IntPtr.Zero, 0); - PythonException.ThrowIfIsNull(obj); } diff --git a/src/runtime/pyiter.cs b/src/runtime/pyiter.cs index ee07bcecf..eb85f53e2 100644 --- a/src/runtime/pyiter.cs +++ b/src/runtime/pyiter.cs @@ -25,19 +25,24 @@ public PyIter(IntPtr ptr) : base(ptr) { } + private static IntPtr FromObject(PyObject iterable) + { + IntPtr val = Runtime.PyObject_GetIter(iterable.obj); + if (val == IntPtr.Zero) + { + throw new PythonException(); + } + return val; + } + /// /// PyIter Constructor /// /// /// Creates a Python iterator from an iterable. Like doing "iter(iterable)" in python. /// - public PyIter(PyObject iterable) + public PyIter(PyObject iterable) : base(FromObject(iterable)) { - obj = Runtime.PyObject_GetIter(iterable.obj); - if (obj == IntPtr.Zero) - { - throw new PythonException(); - } } protected override void Dispose(bool disposing) diff --git a/src/runtime/pylist.cs b/src/runtime/pylist.cs index 80267d81a..0ab8256e4 100644 --- a/src/runtime/pylist.cs +++ b/src/runtime/pylist.cs @@ -28,6 +28,16 @@ public PyList(IntPtr ptr) : base(ptr) internal PyList(BorrowedReference reference) : base(reference) { } + private static IntPtr FromObject(PyObject o) + { + if (!IsListType(o)) + { + throw new ArgumentException("object is not a list"); + } + Runtime.XIncref(o.obj); + return o.obj; + } + /// /// PyList Constructor /// @@ -36,14 +46,8 @@ internal PyList(BorrowedReference reference) : base(reference) { } /// ArgumentException will be thrown if the given object is not a /// Python list object. /// - public PyList(PyObject o) + public PyList(PyObject o) : base(FromObject(o)) { - if (!IsListType(o)) - { - throw new ArgumentException("object is not a list"); - } - Runtime.XIncref(o.obj); - obj = o.obj; } @@ -53,36 +57,39 @@ public PyList(PyObject o) /// /// Creates a new empty Python list object. /// - public PyList() + public PyList() : base(Runtime.PyList_New(0)) { - obj = Runtime.PyList_New(0); if (obj == IntPtr.Zero) { throw new PythonException(); } } - - /// - /// PyList Constructor - /// - /// - /// Creates a new Python list object from an array of PyObjects. - /// - public PyList(PyObject[] items) + private static IntPtr FromArray(PyObject[] items) { int count = items.Length; - obj = Runtime.PyList_New(count); + IntPtr val = Runtime.PyList_New(count); for (var i = 0; i < count; i++) { IntPtr ptr = items[i].obj; Runtime.XIncref(ptr); - int r = Runtime.PyList_SetItem(obj, i, ptr); + int r = Runtime.PyList_SetItem(val, i, ptr); if (r < 0) { throw new PythonException(); } } + return val; + } + + /// + /// PyList Constructor + /// + /// + /// Creates a new Python list object from an array of PyObjects. + /// + public PyList(PyObject[] items) : base(FromArray(items)) + { } diff --git a/src/runtime/pylong.cs b/src/runtime/pylong.cs index fc101105f..f1d87a78a 100644 --- a/src/runtime/pylong.cs +++ b/src/runtime/pylong.cs @@ -31,16 +31,26 @@ public PyLong(IntPtr ptr) : base(ptr) /// ArgumentException will be thrown if the given object is not a /// Python long object. /// - public PyLong(PyObject o) + public PyLong(PyObject o) : base(FromObject(o)) + { + } + + private static IntPtr FromObject(PyObject o) { if (!IsLongType(o)) { throw new ArgumentException("object is not a long"); } Runtime.XIncref(o.obj); - obj = o.obj; + return o.obj; } + private static IntPtr FromInt(int value) + { + IntPtr val = Runtime.PyLong_FromLong(value); + PythonException.ThrowIfIsNull(val); + return val; + } /// /// PyLong Constructor @@ -48,10 +58,8 @@ public PyLong(PyObject o) /// /// Creates a new PyLong from an int32 value. /// - public PyLong(int value) + public PyLong(int value) : base(FromInt(value)) { - obj = Runtime.PyLong_FromLong(value); - PythonException.ThrowIfIsNull(obj); } @@ -62,25 +70,34 @@ public PyLong(int value) /// Creates a new PyLong from a uint32 value. /// [CLSCompliant(false)] - public PyLong(uint value) + public PyLong(uint value) : base(FromInt((int)value)) { - obj = Runtime.PyLong_FromLong(value); - PythonException.ThrowIfIsNull(obj); } + private static IntPtr FromLong(long value) + { + IntPtr val = Runtime.PyLong_FromLongLong(value); + PythonException.ThrowIfIsNull(val); + return val; + } + /// /// PyLong Constructor /// /// /// Creates a new PyLong from an int64 value. /// - public PyLong(long value) + public PyLong(long value) : base(FromLong(value)) { - obj = Runtime.PyLong_FromLongLong(value); - PythonException.ThrowIfIsNull(obj); } + private static IntPtr FromULong(ulong value) + { + IntPtr val = Runtime.PyLong_FromUnsignedLongLong(value); + PythonException.ThrowIfIsNull(val); + return val; + } /// /// PyLong Constructor @@ -89,10 +106,8 @@ public PyLong(long value) /// Creates a new PyLong from a uint64 value. /// [CLSCompliant(false)] - public PyLong(ulong value) + public PyLong(ulong value) : base(FromULong(value)) { - obj = Runtime.PyLong_FromUnsignedLongLong(value); - PythonException.ThrowIfIsNull(obj); } @@ -102,10 +117,8 @@ public PyLong(ulong value) /// /// Creates a new PyLong from an int16 value. /// - public PyLong(short value) + public PyLong(short value) : base(FromInt((int)value)) { - obj = Runtime.PyLong_FromLong(value); - PythonException.ThrowIfIsNull(obj); } @@ -116,10 +129,8 @@ public PyLong(short value) /// Creates a new PyLong from an uint16 value. /// [CLSCompliant(false)] - public PyLong(ushort value) + public PyLong(ushort value) : base(FromInt((int)value)) { - obj = Runtime.PyLong_FromLong(value); - PythonException.ThrowIfIsNull(obj); } @@ -129,10 +140,8 @@ public PyLong(ushort value) /// /// Creates a new PyLong from a byte value. /// - public PyLong(byte value) + public PyLong(byte value) : base(FromInt((int)value)) { - obj = Runtime.PyLong_FromLong(value); - PythonException.ThrowIfIsNull(obj); } @@ -143,12 +152,16 @@ public PyLong(byte value) /// Creates a new PyLong from an sbyte value. /// [CLSCompliant(false)] - public PyLong(sbyte value) + public PyLong(sbyte value) : base(FromInt((int)value)) { - obj = Runtime.PyLong_FromLong(value); - PythonException.ThrowIfIsNull(obj); } + private static IntPtr FromDouble(double value) + { + IntPtr val = Runtime.PyLong_FromDouble(value); + PythonException.ThrowIfIsNull(val); + return val; + } /// /// PyLong Constructor @@ -156,12 +169,16 @@ public PyLong(sbyte value) /// /// Creates a new PyLong from an double value. /// - public PyLong(double value) + public PyLong(double value) : base(FromDouble(value)) { - obj = Runtime.PyLong_FromDouble(value); - PythonException.ThrowIfIsNull(obj); } + private static IntPtr FromString(string value) + { + IntPtr val = Runtime.PyLong_FromString(value, IntPtr.Zero, 0); + PythonException.ThrowIfIsNull(val); + return val; + } /// /// PyLong Constructor @@ -169,10 +186,8 @@ public PyLong(double value) /// /// Creates a new PyLong from a string value. /// - public PyLong(string value) + public PyLong(string value) : base(FromString(value)) { - obj = Runtime.PyLong_FromString(value, IntPtr.Zero, 0); - PythonException.ThrowIfIsNull(obj); } diff --git a/src/runtime/pynumber.cs b/src/runtime/pynumber.cs index 4f7373a8c..1af67b4e0 100644 --- a/src/runtime/pynumber.cs +++ b/src/runtime/pynumber.cs @@ -5,7 +5,6 @@ namespace Python.Runtime /// /// Represents a generic Python number. The methods of this class are /// equivalent to the Python "abstract number API". See - /// PY2: https://docs.python.org/2/c-api/number.html /// PY3: https://docs.python.org/3/c-api/number.html /// for details. /// @@ -18,11 +17,6 @@ protected PyNumber(IntPtr ptr) : base(ptr) { } - protected PyNumber() - { - } - - /// /// IsNumberType Method /// diff --git a/src/runtime/pyobject.cs b/src/runtime/pyobject.cs index f456fd69d..5458e0d87 100644 --- a/src/runtime/pyobject.cs +++ b/src/runtime/pyobject.cs @@ -69,17 +69,6 @@ internal PyObject(BorrowedReference reference) #endif } - // Protected default constructor to allow subclasses to manage - // initialization in different ways as appropriate. - [Obsolete("Please, always use PyObject(*Reference)")] - protected PyObject() - { - Finalizer.Instance.ThrottledCollect(); -#if TRACE_ALLOC - Traceback = new StackTrace(1); -#endif - } - // Ensure that encapsulated Python object is decref'ed appropriately // when the managed wrapper is garbage-collected. ~PyObject() diff --git a/src/runtime/pysequence.cs b/src/runtime/pysequence.cs index 8df13f737..1850ef7de 100644 --- a/src/runtime/pysequence.cs +++ b/src/runtime/pysequence.cs @@ -18,10 +18,6 @@ protected PySequence(IntPtr ptr) : base(ptr) internal PySequence(BorrowedReference reference) : base(reference) { } - protected PySequence() - { - } - /// /// IsSequenceType Method diff --git a/src/runtime/pystring.cs b/src/runtime/pystring.cs index cb18024c5..808015263 100644 --- a/src/runtime/pystring.cs +++ b/src/runtime/pystring.cs @@ -26,6 +26,16 @@ public PyString(IntPtr ptr) : base(ptr) } + private static IntPtr FromObject(PyObject o) + { + if (!IsStringType(o)) + { + throw new ArgumentException("object is not a string"); + } + Runtime.XIncref(o.obj); + return o.obj; + } + /// /// PyString Constructor /// @@ -34,27 +44,25 @@ public PyString(IntPtr ptr) : base(ptr) /// An ArgumentException will be thrown if the given object is not /// a Python string object. /// - public PyString(PyObject o) + public PyString(PyObject o) : base(FromObject(o)) { - if (!IsStringType(o)) - { - throw new ArgumentException("object is not a string"); - } - Runtime.XIncref(o.obj); - obj = o.obj; } + private static IntPtr FromString(string s) + { + IntPtr val = Runtime.PyUnicode_FromUnicode(s, s.Length); + PythonException.ThrowIfIsNull(val); + return val; + } /// /// PyString Constructor /// /// /// Creates a Python string from a managed string. /// - public PyString(string s) + public PyString(string s) : base(FromString(s)) { - obj = Runtime.PyUnicode_FromUnicode(s, s.Length); - PythonException.ThrowIfIsNull(obj); } diff --git a/src/runtime/pytuple.cs b/src/runtime/pytuple.cs index 259d7ae0f..3eeb32798 100644 --- a/src/runtime/pytuple.cs +++ b/src/runtime/pytuple.cs @@ -31,6 +31,15 @@ public PyTuple(IntPtr ptr) : base(ptr) /// internal PyTuple(BorrowedReference reference) : base(reference) { } + private static IntPtr FromObject(PyObject o) + { + if (!IsTupleType(o)) + { + throw new ArgumentException("object is not a tuple"); + } + Runtime.XIncref(o.obj); + return o.obj; + } /// /// PyTuple Constructor @@ -40,14 +49,8 @@ internal PyTuple(BorrowedReference reference) : base(reference) { } /// ArgumentException will be thrown if the given object is not a /// Python tuple object. /// - public PyTuple(PyObject o) + public PyTuple(PyObject o) : base(FromObject(o)) { - if (!IsTupleType(o)) - { - throw new ArgumentException("object is not a tuple"); - } - Runtime.XIncref(o.obj); - obj = o.obj; } @@ -57,12 +60,24 @@ public PyTuple(PyObject o) /// /// Creates a new empty PyTuple. /// - public PyTuple() + public PyTuple() : base(Runtime.PyTuple_New(0)) { - obj = Runtime.PyTuple_New(0); PythonException.ThrowIfIsNull(obj); } + private static IntPtr FromArray(PyObject[] items) + { + int count = items.Length; + IntPtr val = Runtime.PyTuple_New(count); + for (var i = 0; i < count; i++) + { + IntPtr ptr = items[i].obj; + Runtime.XIncref(ptr); + int res = Runtime.PyTuple_SetItem(val, i, ptr); + PythonException.ThrowIfIsNotZero(res); + } + return val; + } /// /// PyTuple Constructor @@ -73,17 +88,8 @@ public PyTuple() /// See caveats about PyTuple_SetItem: /// https://www.coursehero.com/file/p4j2ogg/important-exceptions-to-this-rule-PyTupleSetItem-and-PyListSetItem-These/ /// - public PyTuple(PyObject[] items) + public PyTuple(PyObject[] items) : base(FromArray(items)) { - int count = items.Length; - obj = Runtime.PyTuple_New(count); - for (var i = 0; i < count; i++) - { - IntPtr ptr = items[i].obj; - Runtime.XIncref(ptr); - int res = Runtime.PyTuple_SetItem(obj, i, ptr); - PythonException.ThrowIfIsNotZero(res); - } } From 945db38af4b5f53f4a454283c77d0500ab378e91 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Thu, 17 Sep 2020 21:05:37 -0500 Subject: [PATCH 2/7] respond to PR review --- src/runtime/pyansistring.cs | 2 +- src/runtime/pydict.cs | 2 +- src/runtime/pyfloat.cs | 2 +- src/runtime/pyint.cs | 2 +- src/runtime/pyiter.cs | 23 ++++++++++++++++++++--- src/runtime/pylist.cs | 3 ++- src/runtime/pylong.cs | 2 +- src/runtime/pyobject.cs | 2 +- src/runtime/pystring.cs | 2 +- src/runtime/pytuple.cs | 2 +- 10 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/runtime/pyansistring.cs b/src/runtime/pyansistring.cs index 1035e4945..8a27104b1 100644 --- a/src/runtime/pyansistring.cs +++ b/src/runtime/pyansistring.cs @@ -19,7 +19,7 @@ public PyAnsiString(IntPtr ptr) : base(ptr) private static IntPtr FromObject(PyObject o) { - if (!IsStringType(o)) + if (o == null || !IsStringType(o)) { throw new ArgumentException("object is not a string"); } diff --git a/src/runtime/pydict.cs b/src/runtime/pydict.cs index 265b6c419..ade873f7a 100644 --- a/src/runtime/pydict.cs +++ b/src/runtime/pydict.cs @@ -48,11 +48,11 @@ public PyDict() : base(Runtime.PyDict_New()) /// public PyDict(PyObject o) : base(o.obj) { + Runtime.XIncref(o.obj); if (!IsDictType(o)) { throw new ArgumentException("object is not a dict"); } - Runtime.XIncref(o.obj); } diff --git a/src/runtime/pyfloat.cs b/src/runtime/pyfloat.cs index 640acaf4e..b07b95de1 100644 --- a/src/runtime/pyfloat.cs +++ b/src/runtime/pyfloat.cs @@ -47,7 +47,7 @@ public PyFloat(double value) : base(FromDouble(value)) private static IntPtr FromObject(PyObject o) { - if (!IsFloatType(o)) + if (o == null || !IsFloatType(o)) { throw new ArgumentException("object is not a float"); } diff --git a/src/runtime/pyint.cs b/src/runtime/pyint.cs index 7f05d08cd..e49e62a8a 100644 --- a/src/runtime/pyint.cs +++ b/src/runtime/pyint.cs @@ -37,7 +37,7 @@ public PyInt(PyObject o) : base(FromObject(o)) private static IntPtr FromObject(PyObject o) { - if (!IsIntType(o)) + if (o == null || !IsIntType(o)) { throw new ArgumentException("object is not an int"); } diff --git a/src/runtime/pyiter.cs b/src/runtime/pyiter.cs index eb85f53e2..8c050f455 100644 --- a/src/runtime/pyiter.cs +++ b/src/runtime/pyiter.cs @@ -27,6 +27,10 @@ public PyIter(IntPtr ptr) : base(ptr) private static IntPtr FromObject(PyObject iterable) { + if (iterable == null) + { + throw new NullReferenceException(); + } IntPtr val = Runtime.PyObject_GetIter(iterable.obj); if (val == IntPtr.Zero) { @@ -35,14 +39,27 @@ private static IntPtr FromObject(PyObject iterable) return val; } + /// - /// PyIter Constructor + /// PyIter factory function. /// /// - /// Creates a Python iterator from an iterable. Like doing "iter(iterable)" in python. + /// Create a new PyIter from a given iterable. Like doing "iter(iterable)" in python. /// - public PyIter(PyObject iterable) : base(FromObject(iterable)) + /// + /// + public static PyIter GetIter(PyObject iterable) { + if (iterable == null) + { + throw new NullReferenceException(); + } + IntPtr val = Runtime.PyObject_GetIter(iterable.obj); + if (val == IntPtr.Zero) + { + throw new PythonException(); + } + return new PyIter(val); } protected override void Dispose(bool disposing) diff --git a/src/runtime/pylist.cs b/src/runtime/pylist.cs index 0ab8256e4..dcb0ea78f 100644 --- a/src/runtime/pylist.cs +++ b/src/runtime/pylist.cs @@ -30,7 +30,7 @@ internal PyList(BorrowedReference reference) : base(reference) { } private static IntPtr FromObject(PyObject o) { - if (!IsListType(o)) + if (o == null || !IsListType(o)) { throw new ArgumentException("object is not a list"); } @@ -76,6 +76,7 @@ private static IntPtr FromArray(PyObject[] items) int r = Runtime.PyList_SetItem(val, i, ptr); if (r < 0) { + Runtime.Py_DecRef(val); throw new PythonException(); } } diff --git a/src/runtime/pylong.cs b/src/runtime/pylong.cs index f1d87a78a..87cc7d2a5 100644 --- a/src/runtime/pylong.cs +++ b/src/runtime/pylong.cs @@ -37,7 +37,7 @@ public PyLong(PyObject o) : base(FromObject(o)) private static IntPtr FromObject(PyObject o) { - if (!IsLongType(o)) + if (o == null || !IsLongType(o)) { throw new ArgumentException("object is not a long"); } diff --git a/src/runtime/pyobject.cs b/src/runtime/pyobject.cs index 5458e0d87..a7f5e8305 100644 --- a/src/runtime/pyobject.cs +++ b/src/runtime/pyobject.cs @@ -699,7 +699,7 @@ public PyObject GetIterator() /// public IEnumerator GetEnumerator() { - return new PyIter(this); + return PyIter.GetIter(this); } diff --git a/src/runtime/pystring.cs b/src/runtime/pystring.cs index 808015263..b3d0dc86d 100644 --- a/src/runtime/pystring.cs +++ b/src/runtime/pystring.cs @@ -28,7 +28,7 @@ public PyString(IntPtr ptr) : base(ptr) private static IntPtr FromObject(PyObject o) { - if (!IsStringType(o)) + if (o == null || !IsStringType(o)) { throw new ArgumentException("object is not a string"); } diff --git a/src/runtime/pytuple.cs b/src/runtime/pytuple.cs index 3eeb32798..7f3f1d09c 100644 --- a/src/runtime/pytuple.cs +++ b/src/runtime/pytuple.cs @@ -33,7 +33,7 @@ internal PyTuple(BorrowedReference reference) : base(reference) { } private static IntPtr FromObject(PyObject o) { - if (!IsTupleType(o)) + if (o == null || !IsTupleType(o)) { throw new ArgumentException("object is not a tuple"); } From 0c6a7e2a3f0235b5cd65cd12d4d9ab8b5abb017c Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Thu, 17 Sep 2020 21:07:48 -0500 Subject: [PATCH 3/7] changelog for PyIter change --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b62b291fc..0d7dd6115 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][]. - `clr.AddReference` may now throw errors besides `FileNotFoundException`, that provide more details about the cause of the failure - `clr.AddReference` no longer adds ".dll" implicitly +- `PyIter(PyObject)` constructor replaced with static `PyIter.GetIter(PyObject)` method ### Fixed From 8d74e1c3488244a626c951b56b700f1804d14737 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Sat, 19 Sep 2020 21:05:30 -0500 Subject: [PATCH 4/7] Fix issues --- src/runtime/pyiter.cs | 22 ++-------------------- src/runtime/pythonexception.cs | 3 ++- src/runtime/pytuple.cs | 2 +- 3 files changed, 5 insertions(+), 22 deletions(-) diff --git a/src/runtime/pyiter.cs b/src/runtime/pyiter.cs index 8c050f455..4ad761db7 100644 --- a/src/runtime/pyiter.cs +++ b/src/runtime/pyiter.cs @@ -25,21 +25,6 @@ public PyIter(IntPtr ptr) : base(ptr) { } - private static IntPtr FromObject(PyObject iterable) - { - if (iterable == null) - { - throw new NullReferenceException(); - } - IntPtr val = Runtime.PyObject_GetIter(iterable.obj); - if (val == IntPtr.Zero) - { - throw new PythonException(); - } - return val; - } - - /// /// PyIter factory function. /// @@ -52,13 +37,10 @@ public static PyIter GetIter(PyObject iterable) { if (iterable == null) { - throw new NullReferenceException(); + throw new ArgumentNullException(); } IntPtr val = Runtime.PyObject_GetIter(iterable.obj); - if (val == IntPtr.Zero) - { - throw new PythonException(); - } + PythonException.ThrowIfIsNull(val); return new PyIter(val); } diff --git a/src/runtime/pythonexception.cs b/src/runtime/pythonexception.cs index b69ac34e4..9cc1b9811 100644 --- a/src/runtime/pythonexception.cs +++ b/src/runtime/pythonexception.cs @@ -261,10 +261,11 @@ internal static void ThrowIfIsNull(BorrowedReference reference) } } - public static void ThrowIfIsNotZero(int value) + public static void ThrowIfIsNotZero(int value, Action onBeforeThrow = null) { if (value != 0) { + onBeforeThrow?.Invoke(); throw new PythonException(); } } diff --git a/src/runtime/pytuple.cs b/src/runtime/pytuple.cs index 7f3f1d09c..57ae7cbef 100644 --- a/src/runtime/pytuple.cs +++ b/src/runtime/pytuple.cs @@ -74,7 +74,7 @@ private static IntPtr FromArray(PyObject[] items) IntPtr ptr = items[i].obj; Runtime.XIncref(ptr); int res = Runtime.PyTuple_SetItem(val, i, ptr); - PythonException.ThrowIfIsNotZero(res); + PythonException.ThrowIfIsNotZero(res, () => Runtime.Py_DecRef(val)); } return val; } From fb4123f8ad58f481cb8d2ba9f70b953fae9fe3c1 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Sun, 20 Sep 2020 14:20:15 -0500 Subject: [PATCH 5/7] remove action --- src/runtime/pythonexception.cs | 3 +-- src/runtime/pytuple.cs | 6 +++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/runtime/pythonexception.cs b/src/runtime/pythonexception.cs index 9cc1b9811..b69ac34e4 100644 --- a/src/runtime/pythonexception.cs +++ b/src/runtime/pythonexception.cs @@ -261,11 +261,10 @@ internal static void ThrowIfIsNull(BorrowedReference reference) } } - public static void ThrowIfIsNotZero(int value, Action onBeforeThrow = null) + public static void ThrowIfIsNotZero(int value) { if (value != 0) { - onBeforeThrow?.Invoke(); throw new PythonException(); } } diff --git a/src/runtime/pytuple.cs b/src/runtime/pytuple.cs index 57ae7cbef..7186cebce 100644 --- a/src/runtime/pytuple.cs +++ b/src/runtime/pytuple.cs @@ -74,7 +74,11 @@ private static IntPtr FromArray(PyObject[] items) IntPtr ptr = items[i].obj; Runtime.XIncref(ptr); int res = Runtime.PyTuple_SetItem(val, i, ptr); - PythonException.ThrowIfIsNotZero(res, () => Runtime.Py_DecRef(val)); + if (res == 0) + { + Runtime.Py_DecRef(val); + PythonException.ThrowIfIsNotZero(res); + } } return val; } From f9216a28bb3f8bb89495e20ec86ce0e6ea3321dc Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Sun, 20 Sep 2020 15:06:08 -0500 Subject: [PATCH 6/7] just throw --- src/runtime/pytuple.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/pytuple.cs b/src/runtime/pytuple.cs index 7186cebce..4d051536c 100644 --- a/src/runtime/pytuple.cs +++ b/src/runtime/pytuple.cs @@ -77,7 +77,7 @@ private static IntPtr FromArray(PyObject[] items) if (res == 0) { Runtime.Py_DecRef(val); - PythonException.ThrowIfIsNotZero(res); + throw new PythonException(); } } return val; From ce9a592011b1fdba2f81719425af7a1791a7efa2 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Mon, 21 Sep 2020 06:56:17 -0500 Subject: [PATCH 7/7] fix --- src/runtime/pytuple.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/pytuple.cs b/src/runtime/pytuple.cs index 4d051536c..530ced3d2 100644 --- a/src/runtime/pytuple.cs +++ b/src/runtime/pytuple.cs @@ -74,7 +74,7 @@ private static IntPtr FromArray(PyObject[] items) IntPtr ptr = items[i].obj; Runtime.XIncref(ptr); int res = Runtime.PyTuple_SetItem(val, i, ptr); - if (res == 0) + if (res != 0) { Runtime.Py_DecRef(val); throw new PythonException();