Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 40f7086

Browse files
abessenfilmor
abessen
authored andcommitted
Implement comparison operators.
1 parent fb23dd1 commit 40f7086

File tree

3 files changed

+142
-39
lines changed

3 files changed

+142
-39
lines changed

src/runtime/classbase.cs

Lines changed: 97 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -69,44 +69,105 @@ public virtual IntPtr type_subscript(IntPtr idx)
6969
//====================================================================
7070
#if (PYTHON32 || PYTHON33 || PYTHON34 || PYTHON35)
7171
public static IntPtr tp_richcompare(IntPtr ob, IntPtr other, int op) {
72-
if (op != Runtime.Py_EQ && op != Runtime.Py_NE)
72+
CLRObject co1;
73+
CLRObject co2;
74+
switch (op)
7375
{
74-
Runtime.XIncref(Runtime.PyNotImplemented);
75-
return Runtime.PyNotImplemented;
76+
case Runtime.Py_EQ:
77+
case Runtime.Py_NE:
78+
IntPtr pytrue = Runtime.PyTrue;
79+
IntPtr pyfalse = Runtime.PyFalse;
80+
81+
// swap true and false for NE
82+
if (op != Runtime.Py_EQ)
83+
{
84+
pytrue = Runtime.PyFalse;
85+
pyfalse = Runtime.PyTrue;
86+
}
87+
88+
if (ob == other)
89+
{
90+
Runtime.XIncref(pytrue);
91+
return pytrue;
92+
}
93+
94+
co1 = GetManagedObject(ob) as CLRObject;
95+
co2 = GetManagedObject(other) as CLRObject;
96+
if (null == co2)
97+
{
98+
Runtime.XIncref(pyfalse);
99+
return pyfalse;
100+
}
101+
102+
Object o1 = co1.inst;
103+
Object o2 = co2.inst;
104+
105+
if (Object.Equals(o1, o2))
106+
{
107+
Runtime.XIncref(pytrue);
108+
return pytrue;
109+
}
110+
111+
Runtime.XIncref(pyfalse);
112+
return pyfalse;
113+
case Runtime.Py_LT:
114+
case Runtime.Py_LE:
115+
case Runtime.Py_GT:
116+
case Runtime.Py_GE:
117+
co1 = GetManagedObject(ob) as CLRObject;
118+
co2 = GetManagedObject(other) as CLRObject;
119+
if(co1 == null || co2 == null)
120+
return Exceptions.RaiseTypeError("Cannot get managed object");
121+
var co1Comp = co1.inst as IComparable;
122+
if (co1Comp == null)
123+
return Exceptions.RaiseTypeError("Cannot convert object of type " + co1.GetType() + " to IComparable");
124+
try
125+
{
126+
var cmp = co1Comp.CompareTo(co2.inst);
127+
128+
IntPtr pyCmp;
129+
if (cmp < 0)
130+
{
131+
if (op == Runtime.Py_LT || op == Runtime.Py_LE)
132+
{
133+
pyCmp = Runtime.PyTrue;
134+
}
135+
else
136+
{
137+
pyCmp = Runtime.PyFalse;
138+
}
139+
}
140+
else if (cmp == 0)
141+
{
142+
if (op == Runtime.Py_LE || op == Runtime.Py_GE)
143+
{
144+
pyCmp = Runtime.PyTrue;
145+
}
146+
else
147+
{
148+
pyCmp = Runtime.PyFalse;
149+
}
150+
}
151+
else
152+
{
153+
if (op == Runtime.Py_GE || op == Runtime.Py_GT) {
154+
pyCmp = Runtime.PyTrue;
155+
}
156+
else {
157+
pyCmp = Runtime.PyFalse;
158+
}
159+
}
160+
Runtime.XIncref(pyCmp);
161+
return pyCmp;
162+
}
163+
catch (ArgumentException e)
164+
{
165+
return Exceptions.RaiseTypeError(e.Message);
166+
}
167+
default:
168+
Runtime.XIncref(Runtime.PyNotImplemented);
169+
return Runtime.PyNotImplemented;
76170
}
77-
78-
IntPtr pytrue = Runtime.PyTrue;
79-
IntPtr pyfalse = Runtime.PyFalse;
80-
81-
// swap true and false for NE
82-
if (op != Runtime.Py_EQ)
83-
{
84-
pytrue = Runtime.PyFalse;
85-
pyfalse = Runtime.PyTrue;
86-
}
87-
88-
if (ob == other) {
89-
Runtime.XIncref(pytrue);
90-
return pytrue;
91-
}
92-
93-
CLRObject co1 = GetManagedObject(ob) as CLRObject;
94-
CLRObject co2 = GetManagedObject(other) as CLRObject;
95-
if (null == co2) {
96-
Runtime.XIncref(pyfalse);
97-
return pyfalse;
98-
}
99-
100-
Object o1 = co1.inst;
101-
Object o2 = co2.inst;
102-
103-
if (Object.Equals(o1, o2)) {
104-
Runtime.XIncref(pytrue);
105-
return pytrue;
106-
}
107-
108-
Runtime.XIncref(pyfalse);
109-
return pyfalse;
110171
}
111172
#else
112173
public static int tp_compare(IntPtr ob, IntPtr other)

src/runtime/runtime.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ internal static int AtExit()
404404
internal const int Py_EQ = 2;
405405
internal const int Py_NE = 3;
406406
internal const int Py_GT = 4;
407+
internal const int Py_GE = 5;
407408
internal static IntPtr _PyObject_NextNotImplemented;
408409
#endif
409410

src/tests/test_class.py

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
from System.Collections import Hashtable
2-
from Python.Test import ClassTest
3-
import sys, os, string, unittest, types
1+
import clr
2+
import types
3+
import unittest
4+
45
import Python.Test as Test
56
import System
67
import six
8+
from Python.Test import ClassTest
9+
from System.Collections import Hashtable
710

811
if six.PY3:
912
DictProxyType = type(object.__dict__)
@@ -209,6 +212,44 @@ def testAddAndRemoveClassAttribute(self):
209212
del TimeSpan.new_method
210213
self.assertFalse(hasattr(ts, "new_method"))
211214

215+
def testComparisons(self):
216+
from System import DateTimeOffset
217+
218+
d1 = DateTimeOffset.Parse("2016-11-14")
219+
d2 = DateTimeOffset.Parse("2016-11-15")
220+
221+
self.assertEqual(d1 == d2, False)
222+
self.assertEqual(d1 != d2, True)
223+
224+
self.assertEqual(d1 < d2, True)
225+
self.assertEqual(d1 <= d2, True)
226+
self.assertEqual(d1 >= d2, False)
227+
self.assertEqual(d1 > d2, False)
228+
229+
self.assertEqual(d1 == d1, True)
230+
self.assertEqual(d1 != d1, False)
231+
232+
self.assertEqual(d1 < d1, False)
233+
self.assertEqual(d1 <= d1, True)
234+
self.assertEqual(d1 >= d1, True)
235+
self.assertEqual(d1 > d1, False)
236+
237+
self.assertEqual(d2 == d1, False)
238+
self.assertEqual(d2 != d1, True)
239+
240+
self.assertEqual(d2 < d1, False)
241+
self.assertEqual(d2 <= d1, False)
242+
self.assertEqual(d2 >= d1, True)
243+
self.assertEqual(d2 > d1, True)
244+
245+
self.assertRaises(TypeError, lambda: d1 < None)
246+
self.assertRaises(TypeError, lambda: d1 < System.Guid())
247+
248+
# ClassTest does not implement IComparable
249+
c1 = ClassTest()
250+
c2 = ClassTest()
251+
self.assertRaises(TypeError, lambda: c1 < c2)
252+
212253

213254
class ClassicClass:
214255
def kind(self):

0 commit comments

Comments
 (0)