From 68e81c796c08d397e8f573b7401b1e5c0452ac1e Mon Sep 17 00:00:00 2001 From: abessen Date: Wed, 19 Oct 2016 13:10:35 -0400 Subject: [PATCH 1/6] Do not call Decref if self.repr is still IntPtr.Zero --- src/runtime/constructorbinding.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/runtime/constructorbinding.cs b/src/runtime/constructorbinding.cs index e2eda0685..59fc8d825 100644 --- a/src/runtime/constructorbinding.cs +++ b/src/runtime/constructorbinding.cs @@ -30,7 +30,7 @@ internal class ConstructorBinding : ExtensionType public ConstructorBinding(Type type, IntPtr pyTypeHndl, ConstructorBinder ctorBinder) : base() { this.type = type; - Runtime.XIncref(pyTypeHndl); + Runtime.Incref(pyTypeHndl); this.pyTypeHndl = pyTypeHndl; this.ctorBinder = ctorBinder; repr = IntPtr.Zero; @@ -73,7 +73,7 @@ public static IntPtr tp_descr_get(IntPtr op, IntPtr instance, IntPtr owner) return Exceptions.RaiseTypeError("How in the world could that happen!"); } }*/ - Runtime.XIncref(self.pyHandle); // Decref'd by the interpreter. + Runtime.Incref(self.pyHandle); // Decref'd by the interpreter. return self.pyHandle; } @@ -108,7 +108,7 @@ public static IntPtr mp_subscript(IntPtr op, IntPtr key) BoundContructor boundCtor = new BoundContructor(self.type, self.pyTypeHndl, self.ctorBinder, ci); /* Since nothing's chached, do we need the increment??? - Runtime.XIncref(boundCtor.pyHandle); // Decref'd by the interpreter??? */ + Runtime.Incref(boundCtor.pyHandle); // Decref'd by the interpreter??? */ return boundCtor.pyHandle; } @@ -121,7 +121,7 @@ public static IntPtr tp_repr(IntPtr ob) ConstructorBinding self = (ConstructorBinding)GetManagedObject(ob); if (self.repr != IntPtr.Zero) { - Runtime.XIncref(self.repr); + Runtime.Incref(self.repr); return self.repr; } MethodBase[] methods = self.ctorBinder.GetMethods(); @@ -136,7 +136,7 @@ public static IntPtr tp_repr(IntPtr ob) doc += String.Format("{0}{1}", name, str.Substring(idx)); } self.repr = Runtime.PyString_FromString(doc); - Runtime.XIncref(self.repr); + Runtime.Incref(self.repr); return self.repr; } @@ -147,8 +147,8 @@ public static IntPtr tp_repr(IntPtr ob) public static new void tp_dealloc(IntPtr ob) { ConstructorBinding self = (ConstructorBinding)GetManagedObject(ob); - Runtime.XDecref(self.repr); - Runtime.XDecref(self.pyTypeHndl); + Runtime.Decref(self.repr); + Runtime.Decref(self.pyTypeHndl); ExtensionType.FinalizeObject(self); } } @@ -173,7 +173,7 @@ public BoundContructor(Type type, IntPtr pyTypeHndl, ConstructorBinder ctorBinde : base() { this.type = type; - Runtime.XIncref(pyTypeHndl); + Runtime.Incref(pyTypeHndl); this.pyTypeHndl = pyTypeHndl; this.ctorBinder = ctorBinder; ctorInfo = ci; @@ -217,7 +217,7 @@ public static IntPtr tp_repr(IntPtr ob) BoundContructor self = (BoundContructor)GetManagedObject(ob); if (self.repr != IntPtr.Zero) { - Runtime.XIncref(self.repr); + Runtime.Incref(self.repr); return self.repr; } string name = self.type.FullName; @@ -225,7 +225,7 @@ public static IntPtr tp_repr(IntPtr ob) int idx = str.IndexOf("("); str = String.Format("returns a new {0}{1}", name, str.Substring(idx)); self.repr = Runtime.PyString_FromString(str); - Runtime.XIncref(self.repr); + Runtime.Incref(self.repr); return self.repr; } From 60c5a96d780a8d44999dc82f09c6082c37b5eb50 Mon Sep 17 00:00:00 2001 From: abessen Date: Thu, 20 Oct 2016 11:51:37 -0400 Subject: [PATCH 2/6] Same self.repr null check in ConstructorBinding.tp_dealloc --- src/runtime/constructorbinding.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/runtime/constructorbinding.cs b/src/runtime/constructorbinding.cs index 59fc8d825..d425c6030 100644 --- a/src/runtime/constructorbinding.cs +++ b/src/runtime/constructorbinding.cs @@ -147,7 +147,8 @@ public static IntPtr tp_repr(IntPtr ob) public static new void tp_dealloc(IntPtr ob) { ConstructorBinding self = (ConstructorBinding)GetManagedObject(ob); - Runtime.Decref(self.repr); + if (self.repr != IntPtr.Zero) + Runtime.Decref(self.repr); Runtime.Decref(self.pyTypeHndl); ExtensionType.FinalizeObject(self); } From 81958b267e83b44438332c189d59a48d53cf8acc Mon Sep 17 00:00:00 2001 From: abessen Date: Wed, 26 Oct 2016 23:50:52 -0400 Subject: [PATCH 3/6] Rename Runtime.Incref/Decref to XIncref/XDecref to signal that they check for NULL Remove NULL check debug print in Decref Remove added NULL checks for self.repr in constructorbinding.cs --- src/runtime/constructorbinding.cs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/runtime/constructorbinding.cs b/src/runtime/constructorbinding.cs index d425c6030..d53580390 100644 --- a/src/runtime/constructorbinding.cs +++ b/src/runtime/constructorbinding.cs @@ -30,7 +30,7 @@ internal class ConstructorBinding : ExtensionType public ConstructorBinding(Type type, IntPtr pyTypeHndl, ConstructorBinder ctorBinder) : base() { this.type = type; - Runtime.Incref(pyTypeHndl); + Runtime.XIncref(pyTypeHndl); this.pyTypeHndl = pyTypeHndl; this.ctorBinder = ctorBinder; repr = IntPtr.Zero; @@ -73,7 +73,7 @@ public static IntPtr tp_descr_get(IntPtr op, IntPtr instance, IntPtr owner) return Exceptions.RaiseTypeError("How in the world could that happen!"); } }*/ - Runtime.Incref(self.pyHandle); // Decref'd by the interpreter. + Runtime.XIncref(self.pyHandle); // Decref'd by the interpreter. return self.pyHandle; } @@ -121,7 +121,7 @@ public static IntPtr tp_repr(IntPtr ob) ConstructorBinding self = (ConstructorBinding)GetManagedObject(ob); if (self.repr != IntPtr.Zero) { - Runtime.Incref(self.repr); + Runtime.XIncref(self.repr); return self.repr; } MethodBase[] methods = self.ctorBinder.GetMethods(); @@ -136,7 +136,7 @@ public static IntPtr tp_repr(IntPtr ob) doc += String.Format("{0}{1}", name, str.Substring(idx)); } self.repr = Runtime.PyString_FromString(doc); - Runtime.Incref(self.repr); + Runtime.XIncref(self.repr); return self.repr; } @@ -147,9 +147,8 @@ public static IntPtr tp_repr(IntPtr ob) public static new void tp_dealloc(IntPtr ob) { ConstructorBinding self = (ConstructorBinding)GetManagedObject(ob); - if (self.repr != IntPtr.Zero) - Runtime.Decref(self.repr); - Runtime.Decref(self.pyTypeHndl); + Runtime.XDecref(self.repr); + Runtime.XDecref(self.pyTypeHndl); ExtensionType.FinalizeObject(self); } } @@ -174,7 +173,7 @@ public BoundContructor(Type type, IntPtr pyTypeHndl, ConstructorBinder ctorBinde : base() { this.type = type; - Runtime.Incref(pyTypeHndl); + Runtime.XIncref(pyTypeHndl); this.pyTypeHndl = pyTypeHndl; this.ctorBinder = ctorBinder; ctorInfo = ci; @@ -218,7 +217,7 @@ public static IntPtr tp_repr(IntPtr ob) BoundContructor self = (BoundContructor)GetManagedObject(ob); if (self.repr != IntPtr.Zero) { - Runtime.Incref(self.repr); + Runtime.XIncref(self.repr); return self.repr; } string name = self.type.FullName; @@ -226,7 +225,7 @@ public static IntPtr tp_repr(IntPtr ob) int idx = str.IndexOf("("); str = String.Format("returns a new {0}{1}", name, str.Substring(idx)); self.repr = Runtime.PyString_FromString(str); - Runtime.Incref(self.repr); + Runtime.XIncref(self.repr); return self.repr; } From 1445a79dac67d2d603bd57e3c7f305b8adfb62c9 Mon Sep 17 00:00:00 2001 From: abessen Date: Wed, 26 Oct 2016 23:59:20 -0400 Subject: [PATCH 4/6] Add missing changes for Python 2 --- src/runtime/constructorbinding.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/constructorbinding.cs b/src/runtime/constructorbinding.cs index d53580390..e2eda0685 100644 --- a/src/runtime/constructorbinding.cs +++ b/src/runtime/constructorbinding.cs @@ -108,7 +108,7 @@ public static IntPtr mp_subscript(IntPtr op, IntPtr key) BoundContructor boundCtor = new BoundContructor(self.type, self.pyTypeHndl, self.ctorBinder, ci); /* Since nothing's chached, do we need the increment??? - Runtime.Incref(boundCtor.pyHandle); // Decref'd by the interpreter??? */ + Runtime.XIncref(boundCtor.pyHandle); // Decref'd by the interpreter??? */ return boundCtor.pyHandle; } From c40d859c0dacf9bfbe2fe1ac9c1e3afeb07ef94e Mon Sep 17 00:00:00 2001 From: abessen Date: Wed, 16 Nov 2016 09:47:53 -0500 Subject: [PATCH 5/6] Implement comparison operations --- src/runtime/classbase.cs | 133 ++++++++++++++++++++++++++++----------- src/runtime/runtime.cs | 1 + src/tests/test_class.py | 47 +++++++++++++- 3 files changed, 142 insertions(+), 39 deletions(-) diff --git a/src/runtime/classbase.cs b/src/runtime/classbase.cs index 7214a7ba1..da7c57789 100644 --- a/src/runtime/classbase.cs +++ b/src/runtime/classbase.cs @@ -69,44 +69,105 @@ public virtual IntPtr type_subscript(IntPtr idx) //==================================================================== #if (PYTHON32 || PYTHON33 || PYTHON34 || PYTHON35) public static IntPtr tp_richcompare(IntPtr ob, IntPtr other, int op) { - if (op != Runtime.Py_EQ && op != Runtime.Py_NE) + CLRObject co1; + CLRObject co2; + switch (op) { - Runtime.XIncref(Runtime.PyNotImplemented); - return Runtime.PyNotImplemented; + case Runtime.Py_EQ: + case Runtime.Py_NE: + IntPtr pytrue = Runtime.PyTrue; + IntPtr pyfalse = Runtime.PyFalse; + + // swap true and false for NE + if (op != Runtime.Py_EQ) + { + pytrue = Runtime.PyFalse; + pyfalse = Runtime.PyTrue; + } + + if (ob == other) + { + Runtime.XIncref(pytrue); + return pytrue; + } + + co1 = GetManagedObject(ob) as CLRObject; + co2 = GetManagedObject(other) as CLRObject; + if (null == co2) + { + Runtime.XIncref(pyfalse); + return pyfalse; + } + + Object o1 = co1.inst; + Object o2 = co2.inst; + + if (Object.Equals(o1, o2)) + { + Runtime.XIncref(pytrue); + return pytrue; + } + + Runtime.XIncref(pyfalse); + return pyfalse; + case Runtime.Py_LT: + case Runtime.Py_LE: + case Runtime.Py_GT: + case Runtime.Py_GE: + co1 = GetManagedObject(ob) as CLRObject; + co2 = GetManagedObject(other) as CLRObject; + if(co1 == null || co2 == null) + return Exceptions.RaiseTypeError("Cannot get managed object"); + var co1Comp = co1.inst as IComparable; + if (co1Comp == null) + return Exceptions.RaiseTypeError("Cannot convert object of type " + co1.GetType() + " to IComparable"); + try + { + var cmp = co1Comp.CompareTo(co2.inst); + + IntPtr pyCmp; + if (cmp < 0) + { + if (op == Runtime.Py_LT || op == Runtime.Py_LE) + { + pyCmp = Runtime.PyTrue; + } + else + { + pyCmp = Runtime.PyFalse; + } + } + else if (cmp == 0) + { + if (op == Runtime.Py_LE || op == Runtime.Py_GE) + { + pyCmp = Runtime.PyTrue; + } + else + { + pyCmp = Runtime.PyFalse; + } + } + else + { + if (op == Runtime.Py_GE || op == Runtime.Py_GT) { + pyCmp = Runtime.PyTrue; + } + else { + pyCmp = Runtime.PyFalse; + } + } + Runtime.XIncref(pyCmp); + return pyCmp; + } + catch (ArgumentException e) + { + return Exceptions.RaiseTypeError(e.Message); + } + default: + Runtime.XIncref(Runtime.PyNotImplemented); + return Runtime.PyNotImplemented; } - - IntPtr pytrue = Runtime.PyTrue; - IntPtr pyfalse = Runtime.PyFalse; - - // swap true and false for NE - if (op != Runtime.Py_EQ) - { - pytrue = Runtime.PyFalse; - pyfalse = Runtime.PyTrue; - } - - if (ob == other) { - Runtime.XIncref(pytrue); - return pytrue; - } - - CLRObject co1 = GetManagedObject(ob) as CLRObject; - CLRObject co2 = GetManagedObject(other) as CLRObject; - if (null == co2) { - Runtime.XIncref(pyfalse); - return pyfalse; - } - - Object o1 = co1.inst; - Object o2 = co2.inst; - - if (Object.Equals(o1, o2)) { - Runtime.XIncref(pytrue); - return pytrue; - } - - Runtime.XIncref(pyfalse); - return pyfalse; } #else public static int tp_compare(IntPtr ob, IntPtr other) diff --git a/src/runtime/runtime.cs b/src/runtime/runtime.cs index 6c9087169..e83752f9c 100644 --- a/src/runtime/runtime.cs +++ b/src/runtime/runtime.cs @@ -396,6 +396,7 @@ internal static int AtExit() internal const int Py_EQ = 2; internal const int Py_NE = 3; internal const int Py_GT = 4; + internal const int Py_GE = 5; internal static IntPtr _PyObject_NextNotImplemented; #endif diff --git a/src/tests/test_class.py b/src/tests/test_class.py index fe8fc982b..194c61b18 100644 --- a/src/tests/test_class.py +++ b/src/tests/test_class.py @@ -1,9 +1,12 @@ -from System.Collections import Hashtable -from Python.Test import ClassTest -import sys, os, string, unittest, types +import clr +import types +import unittest + import Python.Test as Test import System import six +from Python.Test import ClassTest +from System.Collections import Hashtable if six.PY3: DictProxyType = type(object.__dict__) @@ -198,6 +201,44 @@ def __setitem__(self, key, value): self.assertTrue(table.Count == 3) + def testComparisons(self): + from System import DateTimeOffset + + d1 = DateTimeOffset.Parse("2016-11-14") + d2 = DateTimeOffset.Parse("2016-11-15") + + self.assertEqual(d1 == d2, False) + self.assertEqual(d1 != d2, True) + + self.assertEqual(d1 < d2, True) + self.assertEqual(d1 <= d2, True) + self.assertEqual(d1 >= d2, False) + self.assertEqual(d1 > d2, False) + + self.assertEqual(d1 == d1, True) + self.assertEqual(d1 != d1, False) + + self.assertEqual(d1 < d1, False) + self.assertEqual(d1 <= d1, True) + self.assertEqual(d1 >= d1, True) + self.assertEqual(d1 > d1, False) + + self.assertEqual(d2 == d1, False) + self.assertEqual(d2 != d1, True) + + self.assertEqual(d2 < d1, False) + self.assertEqual(d2 <= d1, False) + self.assertEqual(d2 >= d1, True) + self.assertEqual(d2 > d1, True) + + self.assertRaises(TypeError, lambda: d1 < None) + self.assertRaises(TypeError, lambda: d1 < System.Guid()) + + # ClassTest does not implement IComparable + c1 = ClassTest() + c2 = ClassTest() + self.assertRaises(TypeError, lambda: c1 < c2) + class ClassicClass: def kind(self): From 81e9d61a112feb02145a5f7ffc43f92968b917a0 Mon Sep 17 00:00:00 2001 From: abessen Date: Wed, 16 Nov 2016 10:04:06 -0500 Subject: [PATCH 6/6] Disable tests for Python 2 --- src/tests/test_class.py | 45 +++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/tests/test_class.py b/src/tests/test_class.py index 194c61b18..b027ef98a 100644 --- a/src/tests/test_class.py +++ b/src/tests/test_class.py @@ -210,34 +210,39 @@ def testComparisons(self): self.assertEqual(d1 == d2, False) self.assertEqual(d1 != d2, True) - self.assertEqual(d1 < d2, True) - self.assertEqual(d1 <= d2, True) - self.assertEqual(d1 >= d2, False) - self.assertEqual(d1 > d2, False) + if six.PY3: + self.assertEqual(d1 < d2, True) + self.assertEqual(d1 <= d2, True) + self.assertEqual(d1 >= d2, False) + self.assertEqual(d1 > d2, False) self.assertEqual(d1 == d1, True) self.assertEqual(d1 != d1, False) - self.assertEqual(d1 < d1, False) - self.assertEqual(d1 <= d1, True) - self.assertEqual(d1 >= d1, True) - self.assertEqual(d1 > d1, False) + if six.PY3: + self.assertEqual(d1 < d1, False) + self.assertEqual(d1 <= d1, True) + self.assertEqual(d1 >= d1, True) + self.assertEqual(d1 > d1, False) self.assertEqual(d2 == d1, False) self.assertEqual(d2 != d1, True) - self.assertEqual(d2 < d1, False) - self.assertEqual(d2 <= d1, False) - self.assertEqual(d2 >= d1, True) - self.assertEqual(d2 > d1, True) - - self.assertRaises(TypeError, lambda: d1 < None) - self.assertRaises(TypeError, lambda: d1 < System.Guid()) - - # ClassTest does not implement IComparable - c1 = ClassTest() - c2 = ClassTest() - self.assertRaises(TypeError, lambda: c1 < c2) + if six.PY3: + self.assertEqual(d2 < d1, False) + self.assertEqual(d2 <= d1, False) + self.assertEqual(d2 >= d1, True) + self.assertEqual(d2 > d1, True) + + if six.PY3: + self.assertRaises(TypeError, lambda: d1 < None) + self.assertRaises(TypeError, lambda: d1 < System.Guid()) + + if six.PY3: + # ClassTest does not implement IComparable + c1 = ClassTest() + c2 = ClassTest() + self.assertRaises(TypeError, lambda: c1 < c2) class ClassicClass: pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy