@@ -575,7 +575,8 @@ is_free_in_any_child(PySTEntryObject *entry, PyObject *key)
575
575
576
576
static int
577
577
inline_comprehension (PySTEntryObject * ste , PySTEntryObject * comp ,
578
- PyObject * scopes , PyObject * comp_free )
578
+ PyObject * scopes , PyObject * comp_free ,
579
+ PyObject * promote_to_cell )
579
580
{
580
581
PyObject * k , * v ;
581
582
Py_ssize_t pos = 0 ;
@@ -611,7 +612,9 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
611
612
// cell vars in comprehension that are locals in outer scope
612
613
// must be promoted to cell so u_cellvars isn't wrong
613
614
if (scope == CELL && ste -> ste_type == FunctionBlock ) {
614
- SET_SCOPE (scopes , k , scope );
615
+ if (PySet_Add (promote_to_cell , k ) < 0 ) {
616
+ return 0 ;
617
+ }
615
618
}
616
619
617
620
// free vars in comprehension that are locals in outer scope can
@@ -638,7 +641,7 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
638
641
*/
639
642
640
643
static int
641
- analyze_cells (PyObject * scopes , PyObject * free )
644
+ analyze_cells (PyObject * scopes , PyObject * free , PyObject * promote_to_cell )
642
645
{
643
646
PyObject * name , * v , * v_cell ;
644
647
int success = 0 ;
@@ -653,7 +656,7 @@ analyze_cells(PyObject *scopes, PyObject *free)
653
656
scope = PyLong_AS_LONG (v );
654
657
if (scope != LOCAL )
655
658
continue ;
656
- if (!PySet_Contains (free , name ))
659
+ if (!PySet_Contains (free , name ) && ! PySet_Contains ( promote_to_cell , name ) )
657
660
continue ;
658
661
/* Replace LOCAL with CELL for this name, and remove
659
662
from free. It is safe to replace the value of name
@@ -803,7 +806,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
803
806
PyObject * global )
804
807
{
805
808
PyObject * name , * v , * local = NULL , * scopes = NULL , * newbound = NULL ;
806
- PyObject * newglobal = NULL , * newfree = NULL ;
809
+ PyObject * newglobal = NULL , * newfree = NULL , * promote_to_cell = NULL ;
807
810
PyObject * temp ;
808
811
int success = 0 ;
809
812
Py_ssize_t i , pos = 0 ;
@@ -835,6 +838,9 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
835
838
newbound = PySet_New (NULL );
836
839
if (!newbound )
837
840
goto error ;
841
+ promote_to_cell = PySet_New (NULL );
842
+ if (!promote_to_cell )
843
+ goto error ;
838
844
839
845
/* Class namespace has no effect on names visible in
840
846
nested functions, so populate the global and bound
@@ -915,7 +921,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
915
921
goto error ;
916
922
}
917
923
if (inline_comp ) {
918
- if (!inline_comprehension (ste , entry , scopes , child_free )) {
924
+ if (!inline_comprehension (ste , entry , scopes , child_free , promote_to_cell )) {
919
925
Py_DECREF (child_free );
920
926
goto error ;
921
927
}
@@ -946,7 +952,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
946
952
}
947
953
948
954
/* Check if any local variables must be converted to cell variables */
949
- if (ste -> ste_type == FunctionBlock && !analyze_cells (scopes , newfree ))
955
+ if (ste -> ste_type == FunctionBlock && !analyze_cells (scopes , newfree , promote_to_cell ))
950
956
goto error ;
951
957
else if (ste -> ste_type == ClassBlock && !drop_class_free (ste , newfree ))
952
958
goto error ;
@@ -966,6 +972,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
966
972
Py_XDECREF (newbound );
967
973
Py_XDECREF (newglobal );
968
974
Py_XDECREF (newfree );
975
+ Py_XDECREF (promote_to_cell );
969
976
if (!success )
970
977
assert (PyErr_Occurred ());
971
978
return success ;
0 commit comments