1. Pypy
  2. Untitled project
  3. pypy

Commits

Armin Rigo  committed c823adb

Implement "x in (constant-tuple)" not by doing a dictionary lookup,
but instead as a chain of equalities.

  • Participants
  • Parent commits 5b867d5
  • Branches default

Comments (0)

Files changed (2)

File rpython/rtyper/rtuple.py

View file
         if not s_tup.is_constant():
             raise TyperError("contains() on non-const tuple")
         t = s_tup.const
-        typ = type(t[0])
-        for x in t[1:]:
-            if type(x) is not typ:
-                raise TyperError("contains() on mixed-type tuple "
-                                 "constant %r" % (t,))
-        d = {}
+        if len(t) == 0:
+            hop.exception_cannot_occur()
+            return hop.inputconst(Bool, False)
+        r_item = hop.args_r[1]
+        v_arg = hop.inputarg(r_item, arg=1)
+        ll_eq = r_item.get_ll_eq_function() or _ll_equal
+        v_result = None
         for x in t:
-            d[x] = None
-        hop2 = hop.copy()
-        _, _ = hop2.r_s_popfirstarg()
-        v_dict = Constant(d)
-        s_dict = hop.rtyper.annotator.bookkeeper.immutablevalue(d)
-        hop2.v_s_insertfirstarg(v_dict, s_dict)
-        return hop2.dispatch()
+            c_tuple_item = hop.inputconst(r_item, x)
+            v_equal = hop.gendirectcall(ll_eq, v_arg, c_tuple_item)
+            if v_result is None:
+                v_result = v_equal
+            else:
+                v_result = hop.genop("int_or", [v_result, v_equal],
+                                     resulttype = Bool)
+        hop.exception_cannot_occur()
+        return v_result or hop.inputconst(Bool, False)
 
 class __extend__(pairtype(TupleRepr, TupleRepr)):
 
         return t.item0
     else:
         raise StopIteration
+
+def _ll_equal(x, y):
+    return x == y

File rpython/rtyper/test/test_rtuple.py

View file
         res = self.interpret(f, [0])
         assert res is False
 
+    def test_constant_tuple_contains3(self):
+        def f(i):
+            return i in ()
+        res = self.interpret(f, [3])
+        assert res is False
+
+    def test_constant_tuple_contains4(self):
+        def f(i):
+            return i in (3,)
+        res = self.interpret(f, [3])
+        assert res is True
+        res = self.interpret(f, [4])
+        assert res is False
+
     def test_constant_unichar_tuple_contains(self):
         def f(i):
             return unichr(i) in (u'1', u'9')