@@ -212,11 +212,13 @@ static int compiler_set_qualname(struct compiler *);
212212static int compiler_sync_comprehension_generator (
213213 struct compiler * c ,
214214 asdl_seq * generators , int gen_index ,
215+ int depth ,
215216 expr_ty elt , expr_ty val , int type );
216217
217218static int compiler_async_comprehension_generator (
218219 struct compiler * c ,
219220 asdl_seq * generators , int gen_index ,
221+ int depth ,
220222 expr_ty elt , expr_ty val , int type );
221223
222224static PyCodeObject * assemble (struct compiler * , int addNone );
@@ -4343,22 +4345,24 @@ compiler_call_helper(struct compiler *c,
43434345static int
43444346compiler_comprehension_generator (struct compiler * c ,
43454347 asdl_seq * generators , int gen_index ,
4348+ int depth ,
43464349 expr_ty elt , expr_ty val , int type )
43474350{
43484351 comprehension_ty gen ;
43494352 gen = (comprehension_ty )asdl_seq_GET (generators , gen_index );
43504353 if (gen -> is_async ) {
43514354 return compiler_async_comprehension_generator (
4352- c , generators , gen_index , elt , val , type );
4355+ c , generators , gen_index , depth , elt , val , type );
43534356 } else {
43544357 return compiler_sync_comprehension_generator (
4355- c , generators , gen_index , elt , val , type );
4358+ c , generators , gen_index , depth , elt , val , type );
43564359 }
43574360}
43584361
43594362static int
43604363compiler_sync_comprehension_generator (struct compiler * c ,
43614364 asdl_seq * generators , int gen_index ,
4365+ int depth ,
43624366 expr_ty elt , expr_ty val , int type )
43634367{
43644368 /* generate code for the iterator, then each of the ifs,
@@ -4386,12 +4390,38 @@ compiler_sync_comprehension_generator(struct compiler *c,
43864390 }
43874391 else {
43884392 /* Sub-iter - calculate on the fly */
4389- VISIT (c , expr , gen -> iter );
4390- ADDOP (c , GET_ITER );
4393+ /* Fast path for the temporary variable assignment idiom:
4394+ for y in [f(x)]
4395+ */
4396+ asdl_seq * elts ;
4397+ switch (gen -> iter -> kind ) {
4398+ case List_kind :
4399+ elts = gen -> iter -> v .List .elts ;
4400+ break ;
4401+ case Tuple_kind :
4402+ elts = gen -> iter -> v .Tuple .elts ;
4403+ break ;
4404+ default :
4405+ elts = NULL ;
4406+ }
4407+ if (asdl_seq_LEN (elts ) == 1 ) {
4408+ expr_ty elt = asdl_seq_GET (elts , 0 );
4409+ if (elt -> kind != Starred_kind ) {
4410+ VISIT (c , expr , elt );
4411+ start = NULL ;
4412+ }
4413+ }
4414+ if (start ) {
4415+ VISIT (c , expr , gen -> iter );
4416+ ADDOP (c , GET_ITER );
4417+ }
4418+ }
4419+ if (start ) {
4420+ depth ++ ;
4421+ compiler_use_next_block (c , start );
4422+ ADDOP_JREL (c , FOR_ITER , anchor );
4423+ NEXT_BLOCK (c );
43914424 }
4392- compiler_use_next_block (c , start );
4393- ADDOP_JREL (c , FOR_ITER , anchor );
4394- NEXT_BLOCK (c );
43954425 VISIT (c , expr , gen -> target );
43964426
43974427 /* XXX this needs to be cleaned up...a lot! */
@@ -4405,7 +4435,7 @@ compiler_sync_comprehension_generator(struct compiler *c,
44054435
44064436 if (++ gen_index < asdl_seq_LEN (generators ))
44074437 if (!compiler_comprehension_generator (c ,
4408- generators , gen_index ,
4438+ generators , gen_index , depth ,
44094439 elt , val , type ))
44104440 return 0 ;
44114441
@@ -4420,18 +4450,18 @@ compiler_sync_comprehension_generator(struct compiler *c,
44204450 break ;
44214451 case COMP_LISTCOMP :
44224452 VISIT (c , expr , elt );
4423- ADDOP_I (c , LIST_APPEND , gen_index + 1 );
4453+ ADDOP_I (c , LIST_APPEND , depth + 1 );
44244454 break ;
44254455 case COMP_SETCOMP :
44264456 VISIT (c , expr , elt );
4427- ADDOP_I (c , SET_ADD , gen_index + 1 );
4457+ ADDOP_I (c , SET_ADD , depth + 1 );
44284458 break ;
44294459 case COMP_DICTCOMP :
44304460 /* With '{k: v}', k is evaluated before v, so we do
44314461 the same. */
44324462 VISIT (c , expr , elt );
44334463 VISIT (c , expr , val );
4434- ADDOP_I (c , MAP_ADD , gen_index + 1 );
4464+ ADDOP_I (c , MAP_ADD , depth + 1 );
44354465 break ;
44364466 default :
44374467 return 0 ;
@@ -4440,15 +4470,18 @@ compiler_sync_comprehension_generator(struct compiler *c,
44404470 compiler_use_next_block (c , skip );
44414471 }
44424472 compiler_use_next_block (c , if_cleanup );
4443- ADDOP_JABS (c , JUMP_ABSOLUTE , start );
4444- compiler_use_next_block (c , anchor );
4473+ if (start ) {
4474+ ADDOP_JABS (c , JUMP_ABSOLUTE , start );
4475+ compiler_use_next_block (c , anchor );
4476+ }
44454477
44464478 return 1 ;
44474479}
44484480
44494481static int
44504482compiler_async_comprehension_generator (struct compiler * c ,
44514483 asdl_seq * generators , int gen_index ,
4484+ int depth ,
44524485 expr_ty elt , expr_ty val , int type )
44534486{
44544487 comprehension_ty gen ;
@@ -4492,9 +4525,10 @@ compiler_async_comprehension_generator(struct compiler *c,
44924525 NEXT_BLOCK (c );
44934526 }
44944527
4528+ depth ++ ;
44954529 if (++ gen_index < asdl_seq_LEN (generators ))
44964530 if (!compiler_comprehension_generator (c ,
4497- generators , gen_index ,
4531+ generators , gen_index , depth ,
44984532 elt , val , type ))
44994533 return 0 ;
45004534
@@ -4509,18 +4543,18 @@ compiler_async_comprehension_generator(struct compiler *c,
45094543 break ;
45104544 case COMP_LISTCOMP :
45114545 VISIT (c , expr , elt );
4512- ADDOP_I (c , LIST_APPEND , gen_index + 1 );
4546+ ADDOP_I (c , LIST_APPEND , depth + 1 );
45134547 break ;
45144548 case COMP_SETCOMP :
45154549 VISIT (c , expr , elt );
4516- ADDOP_I (c , SET_ADD , gen_index + 1 );
4550+ ADDOP_I (c , SET_ADD , depth + 1 );
45174551 break ;
45184552 case COMP_DICTCOMP :
45194553 /* With '{k: v}', k is evaluated before v, so we do
45204554 the same. */
45214555 VISIT (c , expr , elt );
45224556 VISIT (c , expr , val );
4523- ADDOP_I (c , MAP_ADD , gen_index + 1 );
4557+ ADDOP_I (c , MAP_ADD , depth + 1 );
45244558 break ;
45254559 default :
45264560 return 0 ;
@@ -4583,7 +4617,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
45834617 ADDOP_I (c , op , 0 );
45844618 }
45854619
4586- if (!compiler_comprehension_generator (c , generators , 0 , elt ,
4620+ if (!compiler_comprehension_generator (c , generators , 0 , 0 , elt ,
45874621 val , type ))
45884622 goto error_in_scope ;
45894623
0 commit comments