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):
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):
}
/* 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.
*/
{
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);