@@ -5500,10 +5500,45 @@ push_inlined_comprehension_state(struct compiler *c, location loc,
5500
5500
while (PyDict_Next (entry -> ste_symbols , & pos , & k , & v )) {
5501
5501
assert (PyLong_Check (v ));
5502
5502
long symbol = PyLong_AS_LONG (v );
5503
- // only values bound in the comprehension (DEF_LOCAL) need to be handled
5504
- // at all; DEF_LOCAL | DEF_NONLOCAL can occur in the case of an
5505
- // assignment expression to a nonlocal in the comprehension, these don't
5506
- // need handling here since they shouldn't be isolated
5503
+ long scope = (symbol >> SCOPE_OFFSET ) & SCOPE_MASK ;
5504
+ PyObject * outv = PyDict_GetItemWithError (c -> u -> u_ste -> ste_symbols , k );
5505
+ if (outv == NULL ) {
5506
+ outv = _PyLong_GetZero ();
5507
+ }
5508
+ assert (PyLong_Check (outv ));
5509
+ long outsc = (PyLong_AS_LONG (outv ) >> SCOPE_OFFSET ) & SCOPE_MASK ;
5510
+ // If a name has different scope inside than outside the comprehension,
5511
+ // we need to temporarily handle it with the right scope while
5512
+ // compiling the comprehension. If it's free in the comprehension
5513
+ // scope, no special handling; it should be handled the same as the
5514
+ // enclosing scope. (If it's free in outer scope and cell in inner
5515
+ // scope, we can't treat it as both cell and free in the same function,
5516
+ // but treating it as free throughout is fine; it's *_DEREF
5517
+ // either way.)
5518
+ if ((scope != outsc && scope != FREE && !(scope == CELL && outsc == FREE ))
5519
+ || in_class_block ) {
5520
+ if (state -> temp_symbols == NULL ) {
5521
+ state -> temp_symbols = PyDict_New ();
5522
+ if (state -> temp_symbols == NULL ) {
5523
+ return ERROR ;
5524
+ }
5525
+ }
5526
+ // update the symbol to the in-comprehension version and save
5527
+ // the outer version; we'll restore it after running the
5528
+ // comprehension
5529
+ Py_INCREF (outv );
5530
+ if (PyDict_SetItem (c -> u -> u_ste -> ste_symbols , k , v ) < 0 ) {
5531
+ Py_DECREF (outv );
5532
+ return ERROR ;
5533
+ }
5534
+ if (PyDict_SetItem (state -> temp_symbols , k , outv ) < 0 ) {
5535
+ Py_DECREF (outv );
5536
+ return ERROR ;
5537
+ }
5538
+ Py_DECREF (outv );
5539
+ }
5540
+ // locals handling for names bound in comprehension (DEF_LOCAL |
5541
+ // DEF_NONLOCAL occurs in assignment expression to nonlocal)
5507
5542
if ((symbol & DEF_LOCAL && !(symbol & DEF_NONLOCAL )) || in_class_block ) {
5508
5543
if (!_PyST_IsFunctionLike (c -> u -> u_ste )) {
5509
5544
// non-function scope: override this name to use fast locals
@@ -5528,41 +5563,6 @@ push_inlined_comprehension_state(struct compiler *c, location loc,
5528
5563
}
5529
5564
}
5530
5565
}
5531
- long scope = (symbol >> SCOPE_OFFSET ) & SCOPE_MASK ;
5532
- PyObject * outv = PyDict_GetItemWithError (c -> u -> u_ste -> ste_symbols , k );
5533
- if (outv == NULL ) {
5534
- outv = _PyLong_GetZero ();
5535
- }
5536
- assert (PyLong_Check (outv ));
5537
- long outsc = (PyLong_AS_LONG (outv ) >> SCOPE_OFFSET ) & SCOPE_MASK ;
5538
- if (scope != outsc && !(scope == CELL && outsc == FREE )) {
5539
- // If a name has different scope inside than outside the
5540
- // comprehension, we need to temporarily handle it with the
5541
- // right scope while compiling the comprehension. (If it's free
5542
- // in outer scope and cell in inner scope, we can't treat it as
5543
- // both cell and free in the same function, but treating it as
5544
- // free throughout is fine; it's *_DEREF either way.)
5545
-
5546
- if (state -> temp_symbols == NULL ) {
5547
- state -> temp_symbols = PyDict_New ();
5548
- if (state -> temp_symbols == NULL ) {
5549
- return ERROR ;
5550
- }
5551
- }
5552
- // update the symbol to the in-comprehension version and save
5553
- // the outer version; we'll restore it after running the
5554
- // comprehension
5555
- Py_INCREF (outv );
5556
- if (PyDict_SetItem (c -> u -> u_ste -> ste_symbols , k , v ) < 0 ) {
5557
- Py_DECREF (outv );
5558
- return ERROR ;
5559
- }
5560
- if (PyDict_SetItem (state -> temp_symbols , k , outv ) < 0 ) {
5561
- Py_DECREF (outv );
5562
- return ERROR ;
5563
- }
5564
- Py_DECREF (outv );
5565
- }
5566
5566
// local names bound in comprehension must be isolated from
5567
5567
// outer scope; push existing value (which may be NULL if
<
3C76
td data-grid-cell-id="diff-ebc983d9f91e5bcf73500e377ac65e85863c4f77fd5b6b6caf4fcdf7c0f0b057-5568-5568-0" data-selected="false" role="gridcell" style="background-color:var(--bgColor-default);text-align:center" tabindex="-1" valign="top" class="focusable-grid-cell diff-line-number position-relative diff-line-number-neutral left-side">5568
5568
// not defined) on stack
0 commit comments