summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2018-03-11 08:54:47 (GMT)
committerGitHub <noreply@github.com>2018-03-11 08:54:47 (GMT)
commit3f7e9aa2ef215917b9f1521441f67f4ecd33a1bc (patch)
tree7f4b2918d822c863869ef604332e851eeea5c0a1 /Python
parent4e2442505c5e9eec396dcef4d2e6bdd2b6f92fc9 (diff)
downloadcpython-3f7e9aa2ef215917b9f1521441f67f4ecd33a1bc.zip
cpython-3f7e9aa2ef215917b9f1521441f67f4ecd33a1bc.tar.gz
cpython-3f7e9aa2ef215917b9f1521441f67f4ecd33a1bc.tar.bz2
bpo-32925: Optimized iterating and containing test for literal lists (GH-5842)
consisting of non-constants: `x in [a, b]` and `for x in [a, b]`. The case of all constant elements already was optimized.
Diffstat (limited to 'Python')
-rw-r--r--Python/ast_opt.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/Python/ast_opt.c b/Python/ast_opt.c
index 65cf3c1..a54f98c 100644
--- a/Python/ast_opt.c
+++ b/Python/ast_opt.c
@@ -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.
*/
@@ -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);