Skip to content

Commit 0b0a6c0

Browse files
committed
[GR-10084] List doesn't support <= and >= comparation.
PullRequest: graalpython/67
2 parents b491dab + 2579feb commit 0b0a6c0

File tree

4 files changed

+257
-63
lines changed

4 files changed

+257
-63
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Copyright (c) 2018, Oracle and/or its affiliates.
2+
#
3+
# The Universal Permissive License (UPL), Version 1.0
4+
#
5+
# Subject to the condition set forth below, permission is hereby granted to any
6+
# person obtaining a copy of this software, associated documentation and/or data
7+
# (collectively the "Software"), free of charge and under any and all copyright
8+
# rights in the Software, and any and all patent rights owned or freely
9+
# licensable by each licensor hereunder covering either (i) the unmodified
10+
# Software as contributed to or provided by such licensor, or (ii) the Larger
11+
# Works (as defined below), to deal in both
12+
#
13+
# (a) the Software, and
14+
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
15+
# one is included with the Software (each a "Larger Work" to which the
16+
# Software is contributed by such licensors),
17+
#
18+
# without restriction, including without limitation the rights to copy, create
19+
# derivative works of, display, perform, and distribute the Software and make,
20+
# use, sell, offer for sale, import, export, have made, and have sold the
21+
# Software and the Larger Work(s), and to sublicense the foregoing rights on
22+
# either these or other terms.
23+
#
24+
# This license is subject to the following condition:
25+
#
26+
# The above copyright notice and either this complete permission notice or at a
27+
# minimum a reference to the UPL must be included in all copies or substantial
28+
# portions of the Software.
29+
#
30+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36+
# SOFTWARE.
37+
38+
import unittest
39+
40+
class CompareTest(unittest.TestCase):
41+
42+
def comp_eq(self, left, right):
43+
self.assertFalse(left < right)
44+
self.assertTrue(left<=right)
45+
self.assertTrue(left==right)
46+
self.assertFalse(left!=right)
47+
self.assertFalse(left>right)
48+
self.assertTrue(left>=right)
49+
50+
def comp_ne(self, left, right):
51+
self.assertFalse(left==right)
52+
self.assertTrue(left!=right)
53+
54+
def comp_gt(self, left, right):
55+
self.assertFalse(left < right)
56+
self.assertFalse(left <= right)
57+
self.assertTrue(left>right)
58+
self.assertTrue(left>=right)
59+
self.assertFalse(left==right)
60+
self.assertTrue(left!=right)
61+
62+
def comp_lt(self, left, right):
63+
self.assertTrue(left < right)
64+
self.assertTrue(left <= right)
65+
self.assertFalse(left>right)
66+
self.assertFalse(left>=right)
67+
self.assertFalse(left==right)
68+
self.assertTrue(left!=right)
69+
70+
def comp_ge(self, left, right, isEQ):
71+
self.assertFalse(left < right)
72+
self.assertTrue(left>=right)
73+
if (isEQ):
74+
self.assertTrue(left<=right)
75+
self.assertTrue(left==right)
76+
self.assertFalse(left!=right)
77+
self.assertFalse(left>right)
78+
else:
79+
self.assertFalse(left<=right)
80+
self.assertFalse(left==right)
81+
self.assertTrue(left!=right)
82+
self.assertTrue(left>right)
83+
84+
def comp_le(self, left, right, isEQ):
85+
self.assertFalse(left > right)
86+
self.assertTrue(left<=right)
87+
if (isEQ):
88+
self.assertTrue(left==right)
89+
self.assertFalse(left!=right)
90+
self.assertFalse(left<right)
91+
self.assertTrue(left>=right)
92+
else:
93+
self.assertFalse(left==right)
94+
self.assertTrue(left!=right)
95+
self.assertTrue(left<right)
96+
self.assertFalse(left>=right)
97+

graalpython/com.oracle.graal.python.test/src/tests/test_list.py

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
LONG_NUMBER = 6227020800;
1111

1212
import list_tests
13+
from compare import CompareTest
1314

1415

1516
class ListTest(list_tests.CommonTest):
@@ -532,4 +533,97 @@ def __index__(self):
532533
ob = My(10)
533534
self.assertRaises(TypeError, l.__imul__, ob)
534535

535-
536+
class ListCompareTest(CompareTest):
537+
538+
def test_compare(self):
539+
l1 = [1, 2, 3]
540+
l2 = [1,2,3,0]
541+
l3 = [1,2,3,4]
542+
543+
self.comp_eq(l1, l1)
544+
545+
self.comp_ne(l1, l2)
546+
self.comp_ne(l2, l3)
547+
548+
self.comp_ge(l1, l1, True)
549+
self.comp_ge(l2, l1, False)
550+
self.comp_ge(l3, l2, False)
551+
self.comp_ge(l3, l1, False)
552+
553+
self.comp_le(l1, l1, True)
554+
self.comp_le(l1, l2, False)
555+
self.comp_le(l2, l3, False)
556+
self.comp_le(l1, l3, False)
557+
558+
self.comp_lt(l1, l2)
559+
self.comp_lt(l2, l3)
560+
self.comp_lt(l1, l3)
561+
562+
self.comp_gt(l2, l1)
563+
self.comp_gt(l3, l2)
564+
self.comp_gt(l3, l1)
565+
566+
def test_equal_other(self):
567+
def tryWithOtherType(left, right):
568+
self.assertFalse(left == right, "Operation {} == {} should be False".format(left, right))
569+
self.assertTrue(left != right, "Operation {} != {} should be True".format(left, right))
570+
571+
l1 = [1, 2, 3]
572+
tryWithOtherType(l1, 1)
573+
tryWithOtherType(l1, 'hello')
574+
tryWithOtherType(l1, False)
575+
tryWithOtherType(l1, (1, 2, 3))
576+
tryWithOtherType(l1, {1, 2, 3})
577+
tryWithOtherType(l1, {'one':1, 'two':2, 'three':3})
578+
579+
def test_raiseTypeError(self):
580+
def tryWithOtherType(left, right):
581+
def raiseTypeError(left, op, right):
582+
try:
583+
if op == "<":
584+
left < right
585+
elif op == ">":
586+
left > right
587+
elif op == "<=":
588+
left <= right
589+
elif op == ">=":
590+
left >= right
591+
self.assertTrue(False, "Operation {} {} {} should raise TypeError".format(left, op, right))
592+
except TypeError:
593+
pass
594+
595+
raiseTypeError(left, "<", right)
596+
raiseTypeError(left, ">", right)
597+
raiseTypeError(left, "<=", right)
598+
raiseTypeError(left, ">=", right)
599+
600+
l1 = [1, 2, 3]
601+
tryWithOtherType(l1, 1)
602+
tryWithOtherType(l1, True)
603+
tryWithOtherType(l1, 'hello')
604+
605+
def test_extendingClass(self):
606+
class MyList(list):
607+
def __eq__(self, value):
608+
return 'eq'
609+
def __ne__(self, value):
610+
return value;
611+
def __gt__(self, value):
612+
return 10
613+
def __lt__(self, value):
614+
return 11.11
615+
def __ge__(self, value):
616+
return value + 5
617+
def __le__(self, value):
618+
r = super().__le__(value)
619+
return "OK:" + str(r)
620+
621+
l1 = MyList([1, 10])
622+
self.assertEqual(l1 == 1, 'eq')
623+
self.assertEqual(l1 != 'ne', 'ne')
624+
self.assertEqual(l1 > 'ne', 10)
625+
self.assertEqual(l1 < 1, 11.11)
626+
self.assertEqual(l1 >= 6, 11)
627+
self.assertEqual(l1 <= [1, 1], 'OK:False')
628+
self.assertEqual(l1 <= [1, 10], 'OK:True')
629+
self.assertEqual(l1 <= [1, 10, 0], 'OK:True')

graalpython/com.oracle.graal.python.test/src/tests/test_tuple.py

Lines changed: 2 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import seq_tests
66
import unittest
77
import pickle
8+
from compare import CompareTest
89

910
class TupleTest(seq_tests.CommonTest):
1011

@@ -221,64 +222,7 @@ def __index__(self):
221222
raiseTypeError(t, IndexF())
222223

223224

224-
class TupleCompareTest(unittest.TestCase):
225-
226-
def comp_eq(self, left, right):
227-
self.assertFalse(left < right)
228-
self.assertTrue(left<=right)
229-
self.assertTrue(left==right)
230-
self.assertFalse(left!=right)
231-
self.assertFalse(left>right)
232-
self.assertTrue(left>=right)
233-
234-
def comp_ne(self, left, right):
235-
self.assertFalse(left==right)
236-
self.assertTrue(left!=right)
237-
238-
def comp_gt(self, left, right):
239-
self.assertFalse(left < right)
240-
self.assertFalse(left <= right)
241-
self.assertTrue(left>right)
242-
self.assertTrue(left>=right)
243-
self.assertFalse(left==right)
244-
self.assertTrue(left!=right)
245-
246-
def comp_lt(self, left, right):
247-
self.assertTrue(left < right)
248-
self.assertTrue(left <= right)
249-
self.assertFalse(left>right)
250-
self.assertFalse(left>=right)
251-
self.assertFalse(left==right)
252-
self.assertTrue(left!=right)
253-
254-
def comp_ge(self, left, right, isEQ):
255-
self.assertFalse(left < right)
256-
self.assertTrue(left>=right)
257-
if (isEQ):
258-
self.assertTrue(left<=right)
259-
self.assertTrue(left==right)
260-
self.assertFalse(left!=right)
261-
self.assertFalse(left>right)
262-
else:
263-
self.assertFalse(left<=right)
264-
self.assertFalse(left==right)
265-
self.assertTrue(left!=right)
266-
self.assertTrue(left>right)
267-
268-
def comp_le(self, left, right, isEQ):
269-
self.assertFalse(left > right)
270-
self.assertTrue(left<=right)
271-
if (isEQ):
272-
self.assertTrue(left==right)
273-
self.assertFalse(left!=right)
274-
self.assertFalse(left<right)
275-
self.assertTrue(left>=right)
276-
else:
277-
self.assertFalse(left==right)
278-
self.assertTrue(left!=right)
279-
self.assertTrue(left<right)
280-
self.assertFalse(left>=right)
281-
225+
class TupleCompareTest(CompareTest):
282226

283227
def test_compare(self):
284228
t1 = (1, 2, 3)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/list/ListBuiltins.java

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
import static com.oracle.graal.python.nodes.SpecialMethodNames.__ITER__;
3737
import static com.oracle.graal.python.nodes.SpecialMethodNames.__LEN__;
3838
import static com.oracle.graal.python.nodes.SpecialMethodNames.__LT__;
39+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GT__;
40+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__LE__;
41+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GE__;
3942
import static com.oracle.graal.python.nodes.SpecialMethodNames.__MUL__;
4043
import static com.oracle.graal.python.nodes.SpecialMethodNames.__IMUL__;
4144
import static com.oracle.graal.python.nodes.SpecialMethodNames.__NE__;
@@ -1497,6 +1500,11 @@ boolean doPList(PList left, PList right,
14971500
return false;
14981501
}
14991502
}
1503+
1504+
@Fallback
1505+
PNotImplemented contains(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object other) {
1506+
return PNotImplemented.NOT_IMPLEMENTED;
1507+
}
15001508
}
15011509

15021510
@Builtin(name = __NE__, fixedNumOfArguments = 2)
@@ -1532,31 +1540,82 @@ boolean doPList(PList left, PList right,
15321540
return true;
15331541
}
15341542
}
1543+
1544+
@Fallback
1545+
PNotImplemented contains(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object other) {
1546+
return PNotImplemented.NOT_IMPLEMENTED;
1547+
}
15351548
}
15361549

15371550
@Builtin(name = __LT__, fixedNumOfArguments = 2)
15381551
@GenerateNodeFactory
1539-
abstract static class LtNode extends PythonBinaryBuiltinNode {
1552+
abstract static class LtNode extends ListComparisonNode {
15401553

15411554
@Specialization
15421555
boolean contains(PList self, PList other,
15431556
@Cached("create(__EQ__, __EQ__, __EQ__)") BinaryComparisonNode eqNode,
15441557
@Cached("create(__LT__, __GT__, __LT__)") BinaryComparisonNode ltNode) {
1558+
return doComparison(self, other, eqNode, ltNode);
1559+
}
1560+
}
1561+
1562+
@Builtin(name = __GT__, fixedNumOfArguments = 2)
1563+
@GenerateNodeFactory
1564+
abstract static class GtNode extends ListComparisonNode {
1565+
1566+
@Specialization
1567+
boolean contains(PList self, PList other,
1568+
@Cached("create(__EQ__, __EQ__, __EQ__)") BinaryComparisonNode eqNode,
1569+
@Cached("create(__GT__, __LT__, __GT__)") BinaryComparisonNode gtNode) {
1570+
return doComparison(self, other, eqNode, gtNode);
1571+
}
1572+
}
1573+
1574+
@Builtin(name = __GE__, fixedNumOfArguments = 2)
1575+
@GenerateNodeFactory
1576+
abstract static class GeNode extends ListComparisonNode {
1577+
1578+
@Specialization
1579+
boolean doPTuple(PList left, PList right,
1580+
@Cached("create(__EQ__, __EQ__, __EQ__)") BinaryComparisonNode eqNode,
1581+
@Cached("create(__GE__, __LE__, __GE__)") BinaryComparisonNode geNode) {
1582+
return doComparison(left, right, eqNode, geNode);
1583+
}
1584+
}
1585+
1586+
@Builtin(name = __LE__, fixedNumOfArguments = 2)
1587+
@GenerateNodeFactory
1588+
abstract static class LeNode extends ListComparisonNode {
1589+
1590+
@Specialization
1591+
boolean doPList(PList left, PList right,
1592+
@Cached("create(__EQ__, __EQ__, __EQ__)") BinaryComparisonNode eqNode,
1593+
@Cached("create(__LE__, __GE__, __LE__)") BinaryComparisonNode leNode) {
1594+
return doComparison(left, right, eqNode, leNode);
1595+
}
1596+
}
1597+
1598+
abstract static class ListComparisonNode extends PythonBinaryBuiltinNode {
1599+
1600+
static boolean doComparison(PList self, PList other,
1601+
BinaryComparisonNode eqNode,
1602+
BinaryComparisonNode compNode) {
15451603
int len = self.len();
15461604
int len2 = other.len();
15471605
int min = Math.min(len, len2);
15481606
for (int i = 0; i < min; i++) {
15491607
Object left = self.getItem(i);
15501608
Object right = other.getItem(i);
15511609
if (!eqNode.executeBool(left, right)) {
1552-
return ltNode.executeBool(left, right);
1610+
return compNode.executeBool(left, right);
15531611
}
15541612
}
1555-
return len < len2;
1613+
return compNode.executeBool(len, len2);
15561614
}
15571615

15581616
@Fallback
1559-
PNotImplemented contains(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object other) {
1617+
@SuppressWarnings("unused")
1618+
PNotImplemented doOther(Object left, Object right) {
15601619
return PNotImplemented.NOT_IMPLEMENTED;
15611620
}
15621621
}

0 commit comments

Comments
 (0)