Author: Philip Jenvey <pjen...@underboss.org>
Branch: py3k
Changeset: r64301:f4dfafbc4ac8
Date: 2013-05-18 16:51 -0700
http://bitbucket.org/pypy/pypy/changeset/f4dfafbc4ac8/

Log:    merge default

diff --git a/pypy/interpreter/astcompiler/codegen.py 
b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -929,15 +929,22 @@
             self.use_next_block(end)
 
     def _optimize_comparator(self, op, node):
-        """Fold lists of constants in the context of "in"/"not in".
+        """Fold lists/sets of constants in the context of "in"/"not in".
 
-        lists are folded into tuples, otherwise returns False
+        lists are folded into tuples, sets into frozensets, otherwise
+        returns False
         """
-        if op in (ast.In, ast.NotIn) and isinstance(node, ast.List):
-            w_const = self._tuple_of_consts(node.elts)
-            if w_const is not None:
-                self.load_const(w_const)
-                return True
+        if op in (ast.In, ast.NotIn):
+            is_list = isinstance(node, ast.List)
+            if is_list or isinstance(node, ast.Set):
+                w_const = self._tuple_of_consts(node.elts)
+                if w_const is not None:
+                    if not is_list:
+                        from pypy.objspace.std.setobject import (
+                            W_FrozensetObject)
+                        w_const = W_FrozensetObject(self.space, w_const)
+                    self.load_const(w_const)
+                    return True
         return False
 
     def _tuple_of_consts(self, elts):
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py 
b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -1058,3 +1058,17 @@
             counts = self.count_instructions(source)
             assert ops.BUILD_LIST not in counts
             assert ops.LOAD_CONST in counts
+
+    def test_folding_of_set_constants(self):
+        for source in (
+            # in/not in constants with BUILD_SET should be folded to a 
frozenset:
+            'a in {1,2,3}',
+            'a not in {"a","b","c"}',
+            'a in {None, 1, None}',
+            'a not in {(1, 2), 3, 4}',
+            'a in {1, 2, 3, 3, 2, 1}',
+            ):
+            source = 'def f(): %s' % source
+            counts = self.count_instructions(source)
+            assert ops.BUILD_SET not in counts
+            assert ops.LOAD_CONST in counts
diff --git a/pypy/interpreter/test/test_compiler.py 
b/pypy/interpreter/test/test_compiler.py
--- a/pypy/interpreter/test/test_compiler.py
+++ b/pypy/interpreter/test/test_compiler.py
@@ -1054,6 +1054,14 @@
         assert i > -1
         assert isinstance(co.co_consts[i], tuple)
 
+    def test_folding_of_set_constants(self):
+        source = 'a in {1, 2, 3}'
+        co = compile(source, '', 'exec')
+        i = co.co_consts.index(set([1, 2, 3]))
+        assert i > -1
+        assert isinstance(co.co_consts[i], frozenset)
+
+
 class AppTestCallMethod(object):
     spaceconfig = {'objspace.opcodes.CALL_METHOD': True}
         
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to