@@ -5561,10 +5561,48 @@ push_inlined_comprehension_state(struct compiler *c, location loc,
5561
5561
while (PyDict_Next (entry -> ste_symbols , & pos , & k , & v )) {
5562
5562
assert (PyLong_Check (v ));
5563
5563
long symbol = PyLong_AS_LONG (v );
5564
- // only values bound in the comprehension (DEF_LOCAL) need to be handled
5565
- // at all; DEF_LOCAL | DEF_NONLOCAL can occur in the case of an
5566
- // assignment expression to a nonlocal in the comprehension, these don't
5567
- // need handling here since they shouldn't be isolated
5564
+ long scope = (symbol >> SCOPE_OFFSET ) & SCOPE_MASK ;
5565
+ PyObject * outv = PyDict_GetItemWithError (c -> u -> u_ste -> ste_symbols , k );
5566
+ if (outv == NULL ) {
5567
+ if (PyErr_Occurred ()) {
5568
+ return ERROR ;
5569
+ }
5570
+ outv = _PyLong_GetZero ();
5571
+ }
5572
+ assert (PyLong_CheckExact (outv ));
5573
+ long outsc = (PyLong_AS_LONG (outv ) >> SCOPE_OFFSET ) & SCOPE_MASK ;
5574
+ // If a name has different scope inside than outside the comprehension,
5575
+ // we need to temporarily handle it with the right scope while
5576
+ // compiling the comprehension. If it's free in the comprehension
5577
+ // scope, no special handling; it should be handled the same as the
5578
+ // enclosing scope. (If it's free in outer scope and cell in inner
5579
+ // scope, we can't treat it as both cell and free in the same function,
5580
+ // but treating it as free throughout is fine; it's *_DEREF
5581
+ // either way.)
5582
+ if ((scope != outsc && scope != FREE && !(scope == CELL && outsc == FREE ))
5583
+ || in_class_block ) {
5584
+ if (state -> temp_symbols == NULL ) {
5585
+ state -> temp_symbols = PyDict_New ();
5586
+ if (state -> temp_symbols == NULL ) {
5587
+ return ERROR ;
5588
+ }
5589
+ }
5590
+ // update the symbol to the in-comprehension version and save
5591
+ // the outer version; we'll restore it after running the
5592
+ // comprehension
5593
+ Py_INCREF (outv );
5594
+ if (PyDict_SetItem (c -> u -> u_ste -> ste_symbols , k , v ) < 0 ) {
5595
+ Py_DECREF (outv );
5596
+ return ERROR ;
5597
+ }
5598
+ if (PyDict_SetItem (state -> temp_symbols , k , outv ) < 0 ) {
5599
+ Py_DECREF (outv );
5600
+ return ERROR ;
5601
+ }
5602
+ Py_DECREF (outv );
5603
+ }
5604
+ // locals handling for names bound in comprehension (DEF_LOCAL |
5605
+ // DEF_NONLOCAL occurs in assignment expression to nonlocal)
5568
5606
if ((symbol & DEF_LOCAL && !(symbol & DEF_NONLOCAL )) || in_class_block ) {
5569
5607
if (!_PyST_IsFunctionLike (c -> u -> u_ste )) {
5570
5608
// non-function scope: override this name to use fast locals
@@ -5589,41 +5627,6 @@ push_inlined_comprehension_state(struct compiler *c, location loc,
5589
5627
}
5590
5628
}
5591
5629
}
5592
- long scope = (symbol >> SCOPE_OFFSET ) & SCOPE_MASK ;
5593
- PyObject * outv = PyDict_GetItemWithError (c -> u -> u_ste -> ste_symbols , k );
5594
- if (outv == NULL ) {
5595
- outv = _PyLong_GetZero ();
5596
- }
5597
- assert (PyLong_Check (outv ));
5598
- long outsc = (PyLong_AS_LONG (outv ) >> SCOPE_OFFSET ) & SCOPE_MASK ;
5599
- if (scope != outsc && !(scope == CELL && outsc == FREE )) {
5600
- // If a name has different scope inside than outside the
5601
- // comprehension, we need to temporarily handle it with the
5602
- // right scope while compiling the comprehension. (If it's free
5603
- // in outer scope and cell in inner scope, we can't treat it as
5604
- // both cell and free in the same function, but treating it as
5605
- // free throughout is fine; it's *_DEREF either way.)
5606
-
5607
- if (state -> temp_symbols == NULL ) {
5608
- state -> temp_symbols = PyDict_New ();
5609
- if (state -> temp_symbols == NULL ) {
5610
- return ERROR ;
5611
- }
5612
- }
5613
- // update the symbol to the in-comprehension version and save
5614
- // the outer version; we'll restore it after running the
5615
- // comprehension
5616
- Py_INCREF (outv );
5617
- if (PyDict_SetItem (c -> u -> u_ste -> ste_symbols , k , v ) < 0 ) {
5618<
341A
/code>
- Py_DECREF (outv );
5619
- return ERROR ;
5620
- }
5621
- if (PyDict_SetItem (state -> temp_symbols , k , outv ) < 0 ) {
5622
- Py_DECREF (outv );
5623
- return ERROR ;
5624
- }
5625
- Py_DECREF (outv );
5626
- }
5627
5630
// local names bound in comprehension must be isolated from
5628
5631
// outer scope; push existing value (which may be NULL if
5629
5632
// not defined) on stack
0 commit comments