@@ -205,7 +205,7 @@ fold_binop(expr_ty node, PyArena *arena)
205205}
206206
207207static PyObject *
208- make_const_tuple (asdl_seq * elts , int make_set )
208+ make_const_tuple (asdl_seq * elts )
209209{
210210 for (int i = 0 ; i < asdl_seq_LEN (elts ); i ++ ) {
211211 expr_ty e = (expr_ty )asdl_seq_GET (elts , i );
@@ -225,11 +225,6 @@ make_const_tuple(asdl_seq *elts, int make_set)
225225 Py_INCREF (v );
226226 PyTuple_SET_ITEM (newval , i , v );
227227 }
228-
229- /* Need to create frozen_set instead. */
230- if (make_set ) {
231- Py_SETREF (newval , PyFrozenSet_New (newval ));
232- }
233228 return newval ;
234229}
235230
@@ -241,7 +236,7 @@ fold_tuple(expr_ty node, PyArena *arena)
241236 if (node -> v .Tuple .ctx != Load )
242237 return 1 ;
243238
244- newval = make_const_tuple (node -> v .Tuple .elts , 0 );
239+ newval = make_const_tuple (node -> v .Tuple .elts );
245240 return make_const (node , newval , arena );
246241}
247242
@@ -268,38 +263,48 @@ fold_subscr(expr_ty node, PyArena *arena)
268263 return make_const (node , newval , arena );
269264}
270265
266+ /* Change literal list or set of constants into constant
267+ tuple or frozenset respectively.
268+ Used for right operand of "in" and "not in" tests and for iterable
269+ in "for" loop and comprehensions.
270+ */
271+ static int
272+ fold_iter (expr_ty arg , PyArena * arena )
273+ {
274+ PyObject * newval ;
275+ if (arg -> kind == List_kind ) {
276+ newval = make_const_tuple (arg -> v .List .elts );
277+ }
278+ else if (arg -> kind == Set_kind ) {
279+ newval = make_const_tuple (arg -> v .Set .elts );
280+ if (newval ) {
281+ Py_SETREF (newval , PyFrozenSet_New (newval ));
282+ }
283+ }
284+ else {
285+ return 1 ;
286+ }
287+ return make_const (arg , newval , arena );
288+ }
289+
271290static int
272291fold_compare (expr_ty node , PyArena * arena )
273292{
274293 asdl_int_seq * ops ;
275294 asdl_seq * args ;
276- PyObject * newval ;
277295 int i ;
278296
279297 ops = node -> v .Compare .ops ;
280298 args = node -> v .Compare .comparators ;
281299 /* TODO: optimize cases with literal arguments. */
282- for (i = 0 ; i < asdl_seq_LEN (ops ); i ++ ) {
283- int op ;
284- expr_ty arg ;
285- asdl_seq * elts ;
286-
287- op = asdl_seq_GET (ops , i );
288- arg = (expr_ty )asdl_seq_GET (args , i );
289- /* Change literal list or set in 'in' or 'not in' into
290- tuple or frozenset respectively. */
291- /* TODO: do the same when list or set is used as iterable
292- in for loop and comprehensions? */
293- if (op != In && op != NotIn )
294- continue ;
295- if (arg -> kind == List_kind )
296- elts = arg -> v .List .elts ;
297- else if (arg -> kind == Set_kind )
298- elts = arg -> v .Set .elts ;
299- else continue ;
300-
301- newval = make_const_tuple (elts , arg -> kind == Set_kind );
302- make_const (arg , newval , arena );
300+ /* Change literal list or set in 'in' or 'not in' into
301+ tuple or frozenset respectively. */
302+ i = asdl_seq_LEN (ops ) - 1 ;
303+ int op = asdl_seq_GET (ops , i );
304+ if (op == In || op == NotIn ) {
305+ if (!fold_iter ((expr_ty )asdl_seq_GET (args , i ), arena )) {
306+ return 0 ;
307+ }
303308 }
304309 return 1 ;
305310}
@@ -497,6 +502,8 @@ astfold_comprehension(comprehension_ty node_, PyArena* ctx_)
497502 CALL (astfold_expr , expr_ty , node_ -> target );
498503 CALL (astfold_expr , expr_ty , node_ -> iter );
499504 CALL_SEQ (astfold_expr , expr_ty , node_ -> ifs );
505+
506+ CALL (fold_iter , expr_ty , node_ -> iter );
500507 return 1 ;
501508}
502509
@@ -565,6 +572,8 @@ astfold_stmt(stmt_ty node_, PyArena* ctx_)
565572 CALL (astfold_expr , expr_ty , node_ -> v .For .iter );
566573 CALL_SEQ (astfold_stmt , stmt_ty , node_ -> v .For .body );
567574 CALL_SEQ (astfold_stmt , stmt_ty , node_ -> v .For .orelse );
575+
576+ CALL (fold_iter , expr_ty , node_ -> v .For .iter );
568577 break ;
569578 case AsyncFor_kind :
570579 CALL (astfold_expr , expr_ty , node_ -> v .AsyncFor .target );
0 commit comments