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