Commits

Armin Rigo committed c85db2c

Fix for issue1077: [nan] <= [5] should be False.

Comments (0)

Files changed (4)

pypy/objspace/std/listobject.py

         i += 1
     return space.w_True
 
-def lessthan_unwrappeditems(space, w_list1, w_list2):
-    # needs to be safe against eq_w() mutating the w_lists behind our back
-    # Search for the first index where items are different
-    i = 0
-    # XXX in theory, this can be implemented more efficiently as well. let's
-    # not care for now
-    while i < w_list1.length() and i < w_list2.length():
-        w_item1 = w_list1.getitem(i)
-        w_item2 = w_list2.getitem(i)
-        if not space.eq_w(w_item1, w_item2):
-            return space.lt(w_item1, w_item2)
-        i += 1
-    # No more items to compare -- compare sizes
-    return space.newbool(w_list1.length() < w_list2.length())
+def _make_list_comparison(name):
+    import operator
+    op = getattr(operator, name)
+    def compare_unwrappeditems(space, w_list1, w_list2):
+        # needs to be safe against eq_w() mutating the w_lists behind our back
+        # Search for the first index where items are different
+        i = 0
+        # XXX in theory, this can be implemented more efficiently as well.
+        # let's not care for now
+        while i < w_list1.length() and i < w_list2.length():
+            w_item1 = w_list1.getitem(i)
+            w_item2 = w_list2.getitem(i)
+            if not space.eq_w(w_item1, w_item2):
+                return getattr(space, name)(w_item1, w_item2)
+            i += 1
+        # No more items to compare -- compare sizes
+        return space.newbool(op(w_list1.length(), w_list2.length()))
+    return func_with_new_name(compare_unwrappeditems, name + '__List_List')
 
-def greaterthan_unwrappeditems(space, w_list1, w_list2):
-    # needs to be safe against eq_w() mutating the w_lists behind our back
-    # Search for the first index where items are different
-    i = 0
-    # XXX in theory, this can be implemented more efficiently as well. let's
-    # not care for now
-    while i < w_list1.length() and i < w_list2.length():
-        w_item1 = w_list1.getitem(i)
-        w_item2 = w_list2.getitem(i)
-        if not space.eq_w(w_item1, w_item2):
-            return space.gt(w_item1, w_item2)
-        i += 1
-    # No more items to compare -- compare sizes
-    return space.newbool(w_list1.length() > w_list2.length())
-
-def lt__List_List(space, w_list1, w_list2):
-    return lessthan_unwrappeditems(space, w_list1, w_list2)
-
-def gt__List_List(space, w_list1, w_list2):
-    return greaterthan_unwrappeditems(space, w_list1, w_list2)
+lt__List_List = _make_list_comparison('lt')
+le__List_List = _make_list_comparison('le')
+gt__List_List = _make_list_comparison('gt')
+ge__List_List = _make_list_comparison('ge')
 
 def delitem__List_ANY(space, w_list, w_idx):
     idx = get_list_index(space, w_idx)

pypy/objspace/std/test/test_listobject.py

             s.update(Sub2(arg))
             assert s == set(base(arg))
 
+    def test_comparison(self):
+        assert ([] <  []) is False
+        assert ([] <= []) is True
+        assert ([] == []) is True
+        assert ([] != []) is False
+        assert ([] >  []) is False
+        assert ([] >= []) is True
+        assert ([5] <  []) is False
+        assert ([5] <= []) is False
+        assert ([5] == []) is False
+        assert ([5] != []) is True
+        assert ([5] >  []) is True
+        assert ([5] >= []) is True
+        assert ([] <  [5]) is True
+        assert ([] <= [5]) is True
+        assert ([] == [5]) is False
+        assert ([] != [5]) is True
+        assert ([] >  [5]) is False
+        assert ([] >= [5]) is False
+        assert ([4] <  [5]) is True
+        assert ([4] <= [5]) is True
+        assert ([4] == [5]) is False
+        assert ([4] != [5]) is True
+        assert ([4] >  [5]) is False
+        assert ([4] >= [5]) is False
+        assert ([5] <  [5]) is False
+        assert ([5] <= [5]) is True
+        assert ([5] == [5]) is True
+        assert ([5] != [5]) is False
+        assert ([5] >  [5]) is False
+        assert ([5] >= [5]) is True
+        assert ([6] <  [5]) is False
+        assert ([6] <= [5]) is False
+        assert ([6] == [5]) is False
+        assert ([6] != [5]) is True
+        assert ([6] >  [5]) is True
+        assert ([6] >= [5]) is True
+        N = float('nan')
+        assert ([N] <  [5]) is False
+        assert ([N] <= [5]) is False
+        assert ([N] == [5]) is False
+        assert ([N] != [5]) is True
+        assert ([N] >  [5]) is False
+        assert ([N] >= [5]) is False
+        assert ([5] <  [N]) is False
+        assert ([5] <= [N]) is False
+        assert ([5] == [N]) is False
+        assert ([5] != [N]) is True
+        assert ([5] >  [N]) is False
+        assert ([5] >= [N]) is False
+
 class AppTestForRangeLists(AppTestW_ListObject):
 
     def setup_class(cls):

pypy/objspace/std/test/test_tupleobject.py

         assert (4, 2, 3, 4).index(4, 1) == 3
         assert (4, 4, 4).index(4, 1, 2) == 1
         raises(ValueError, (1, 2, 3, 4).index, 4, 0, 2)
+
+    def test_comparison(self):
+        assert (() <  ()) is False
+        assert (() <= ()) is True
+        assert (() == ()) is True
+        assert (() != ()) is False
+        assert (() >  ()) is False
+        assert (() >= ()) is True
+        assert ((5,) <  ()) is False
+        assert ((5,) <= ()) is False
+        assert ((5,) == ()) is False
+        assert ((5,) != ()) is True
+        assert ((5,) >  ()) is True
+        assert ((5,) >= ()) is True
+        assert (() <  (5,)) is True
+        assert (() <= (5,)) is True
+        assert (() == (5,)) is False
+        assert (() != (5,)) is True
+        assert (() >  (5,)) is False
+        assert (() >= (5,)) is False
+        assert ((4,) <  (5,)) is True
+        assert ((4,) <= (5,)) is True
+        assert ((4,) == (5,)) is False
+        assert ((4,) != (5,)) is True
+        assert ((4,) >  (5,)) is False
+        assert ((4,) >= (5,)) is False
+        assert ((5,) <  (5,)) is False
+        assert ((5,) <= (5,)) is True
+        assert ((5,) == (5,)) is True
+        assert ((5,) != (5,)) is False
+        assert ((5,) >  (5,)) is False
+        assert ((5,) >= (5,)) is True
+        assert ((6,) <  (5,)) is False
+        assert ((6,) <= (5,)) is False
+        assert ((6,) == (5,)) is False
+        assert ((6,) != (5,)) is True
+        assert ((6,) >  (5,)) is True
+        assert ((6,) >= (5,)) is True
+        N = float('nan')
+        assert ((N,) <  (5,)) is False
+        assert ((N,) <= (5,)) is False
+        assert ((N,) == (5,)) is False
+        assert ((N,) != (5,)) is True
+        assert ((N,) >  (5,)) is False
+        assert ((N,) >= (5,)) is False
+        assert ((5,) <  (N,)) is False
+        assert ((5,) <= (N,)) is False
+        assert ((5,) == (N,)) is False
+        assert ((5,) != (N,)) is True
+        assert ((5,) >  (N,)) is False
+        assert ((5,) >= (N,)) is False

pypy/objspace/std/tupleobject.py

 from pypy.objspace.std import slicetype
 from pypy.rlib.debug import make_sure_not_resized
 from pypy.rlib import jit
+from pypy.tool.sourcetools import func_with_new_name
 
 # Tuples of known length up to UNROLL_TUPLE_LIMIT have unrolled certain methods
 UNROLL_TUPLE_LIMIT = 10
             return space.w_False
     return space.w_True
 
-@jit.look_inside_iff(tuple_unroll_condition)
-def lt__Tuple_Tuple(space, w_tuple1, w_tuple2):
-    items1 = w_tuple1.wrappeditems
-    items2 = w_tuple2.wrappeditems
-    ncmp = min(len(items1), len(items2))
-    # Search for the first index where items are different
-    for p in range(ncmp):
-        if not space.eq_w(items1[p], items2[p]):
-            return space.lt(items1[p], items2[p])
-    # No more items to compare -- compare sizes
-    return space.newbool(len(items1) < len(items2))
+def _make_tuple_comparison(name):
+    import operator
+    op = getattr(operator, name)
+    #
+    @jit.look_inside_iff(tuple_unroll_condition)
+    def compare_tuples(space, w_tuple1, w_tuple2):
+        items1 = w_tuple1.wrappeditems
+        items2 = w_tuple2.wrappeditems
+        ncmp = min(len(items1), len(items2))
+        # Search for the first index where items are different
+        for p in range(ncmp):
+            if not space.eq_w(items1[p], items2[p]):
+                return getattr(space, name)(items1[p], items2[p])
+        # No more items to compare -- compare sizes
+        return space.newbool(op(len(items1), len(items2)))
+    return func_with_new_name(compare_tuples, name + '__Tuple_Tuple')
 
-@jit.look_inside_iff(tuple_unroll_condition)
-def gt__Tuple_Tuple(space, w_tuple1, w_tuple2):
-    items1 = w_tuple1.wrappeditems
-    items2 = w_tuple2.wrappeditems
-    ncmp = min(len(items1), len(items2))
-    # Search for the first index where items are different
-    for p in range(ncmp):
-        if not space.eq_w(items1[p], items2[p]):
-            return space.gt(items1[p], items2[p])
-    # No more items to compare -- compare sizes
-    return space.newbool(len(items1) > len(items2))
+lt__Tuple_Tuple = _make_tuple_comparison('lt')
+le__Tuple_Tuple = _make_tuple_comparison('le')
+gt__Tuple_Tuple = _make_tuple_comparison('gt')
+ge__Tuple_Tuple = _make_tuple_comparison('ge')
 
 def repr__Tuple(space, w_tuple):
     items = w_tuple.wrappeditems
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.