Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions Lib/test/test_peepholer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@

from test.bytecode_helper import BytecodeTestCase

def count_instr_recursively(f, opname):
count = 0
for instr in dis.get_instructions(f):
if instr.opname == opname:
count += 1
if hasattr(f, '__code__'):
f = f.__code__
for c in f.co_consts:
if hasattr(c, 'co_code'):
count += count_instr_recursively(c, opname)
return count


class TestTranforms(BytecodeTestCase):

def test_unot(self):
Expand Down Expand Up @@ -311,6 +324,17 @@ def test_constant_folding(self):
self.assertFalse(instr.opname.startswith('BINARY_'))
self.assertFalse(instr.opname.startswith('BUILD_'))

def test_in_literal_list(self):
def containtest():
return x in [a, b]
self.assertEqual(count_instr_recursively(containtest, 'BUILD_LIST'), 0)

def test_iterate_literal_list(self):
def forloop():
for x in [a, b]:
pass
self.assertEqual(count_instr_recursively(forloop, 'BUILD_LIST'), 0)


class TestBuglets(unittest.TestCase):

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Optimized iterating and containing test for literal lists consisting of
non-constants: ``x in [a, b]`` and ``for x in [a, b]``. The case of all
constant elements already was optimized.
19 changes: 17 additions & 2 deletions Python/ast_opt.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,8 @@ fold_subscr(expr_ty node, PyArena *arena, int optimize)
}

/* Change literal list or set of constants into constant
tuple or frozenset respectively.
tuple or frozenset respectively. Change literal list of
non-constants into tuple.
Used for right operand of "in" and "not in" tests and for iterable
in "for" loop and comprehensions.
*/
Expand All @@ -378,7 +379,21 @@ fold_iter(expr_ty arg, PyArena *arena, int optimize)
{
PyObject *newval;
if (arg->kind == List_kind) {
newval = make_const_tuple(arg->v.List.elts);
/* First change a list into tuple. */
asdl_seq *elts = arg->v.List.elts;
Py_ssize_t n = asdl_seq_LEN(elts);
for (Py_ssize_t i = 0; i < n; i++) {
expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
if (e->kind == Starred_kind) {
return 1;
}
}
expr_context_ty ctx = arg->v.List.ctx;
arg->kind = Tuple_kind;
arg->v.Tuple.elts = elts;
arg->v.Tuple.ctx = ctx;
/* Try to create a constant tuple. */
newval = make_const_tuple(elts);
}
else if (arg->kind == Set_kind) {
newval = make_const_tuple(arg->v.Set.elts);
Expand Down