@@ -804,7 +804,7 @@ is_free_in_any_child(PySTEntryObject *entry, PyObject *key)
804804static int
805805inline_comprehension (PySTEntryObject * ste , PySTEntryObject * comp ,
806806 PyObject * scopes , PyObject * comp_free ,
807- PyObject * inlined_cells )
807+ PyObject * inlined_cells , PyObject * local )
808808{
809809 PyObject * k , * v ;
810810 Py_ssize_t pos = 0 ;
@@ -880,17 +880,23 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
880880 return 0 ;
881881 }
882882 if ((flags & DEF_BOUND ) && ste -> ste_type != ClassBlock ) {
883- // free vars in comprehension that are locals in outer scope can
884- // now simply be locals, unless they are free in comp children,
885- // or if the outer scope is a class block
886- int ok = is_free_in_any_child (comp , k );
887- if (ok < 0 ) {
883+ int is_local = PySet_Contains (local , k );
884+ if (is_local < 0 ) {
888885 return 0 ;
889886 }
890- if (!ok ) {
891- if (PySet_Discard (comp_free , k ) < 0 ) {
887+ if (is_local ) {
888+ // free vars in comprehension that are locals in outer scope can
889+ // now simply be locals, unless they are free in comp children,
890+ // or if the outer scope is a class block
891+ int ok = is_free_in_any_child (comp , k );
892+ if (ok < 0 ) {
892893 return 0 ;
893894 }
895+ if (!ok ) {
896+ if (PySet_Discard (comp_free , k ) < 0 ) {
897+ return 0 ;
898+ }
899+ }
894900 }
895901 }
896902 }
@@ -913,20 +919,27 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
913919 provides the binding for the free variable. The name should be
914920 marked CELL in this block and removed from the free list.
915921
916- Note that the current block's free variables are included in free.
917- That's safe because no name can be free and local in the same scope.
922+ Note that the current block's free variables are included in free. A name
923+ can appear local in scopes and free if the local binding was copied from an
924+ inlined comprehension; such a name is not in local and must remain free.
918925*/
919926
920927static int
921- analyze_cells (PyObject * scopes , PyObject * free , PyObject * inlined_cells )
928+ analyze_cells (PyObject * scopes , PyObject * free , PyObject * inlined_cells ,
929+ PyObject * local )
922930{
923- PyObject * name , * v , * v_cell ;
931+ PyObject * name , * v , * v_cell , * v_free ;
924932 int success = 0 ;
925933 Py_ssize_t pos = 0 ;
926934
927935 v_cell = PyLong_FromLong (CELL );
928936 if (!v_cell )
929937 return 0 ;
938+ v_free = PyLong_FromLong (FREE );
939+ if (!v_free ) {
940+ Py_DECREF (v_cell );
941+ return 0 ;
942+ }
930943 while (PyDict_Next (scopes , & pos , & name , & v )) {
931944 long scope = PyLong_AsLong (v );
932945 if (scope == -1 && PyErr_Occurred ()) {
@@ -938,7 +951,22 @@ analyze_cells(PyObject *scopes, PyObject *free, PyObject *inlined_cells)
938951 if (contains < 0 ) {
939952 goto error ;
940953 }
941- if (!contains ) {
954+ if (contains ) {
955+ int is_local = PySet_Contains (local , name );
956+ if (is_local < 0 ) {
957+ goto error ;
958+ }
959+ if (!is_local ) {
960+ // This binding was copied from an inlined comprehension, not
961+ // defined in this scope. Another child may still need the
962+ // name from an enclosing scope.
963+ if (PyDict_SetItem (scopes , name , v_free ) < 0 ) {
964+ goto error ;
965+ }
966+ continue ;
967+ }
968+ }
969+ else {
942970 contains = PySet_Contains (inlined_cells , name );
943971 if (contains < 0 ) {
944972 goto error ;
@@ -959,6 +987,7 @@ analyze_cells(PyObject *scopes, PyObject *free, PyObject *inlined_cells)
959987 success = 1 ;
960988 error :
961989 Py_DECREF (v_cell );
990+ Py_DECREF (v_free );
962991 return success ;
963992}
964993
@@ -1275,7 +1304,8 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
12751304 goto error ;
12761305 }
12771306 if (inline_comp ) {
1278- if (!inline_comprehension (ste , entry , scopes , child_free , inlined_cells )) {
1307+ if (!inline_comprehension (ste , entry , scopes , child_free ,
1308+ inlined_cells , local )) {
12791309 Py_DECREF (child_free );
12801310 goto error ;
12811311 }
@@ -1303,8 +1333,11 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
13031333 }
13041334
13051335 /* Check if any local variables must be converted to cell variables */
1306- if (_PyST_IsFunctionLike (ste ) && !analyze_cells (scopes , newfree , inlined_cells ))
1336+ if (_PyST_IsFunctionLike (ste ) &&
1337+ !analyze_cells (scopes , newfree , inlined_cells , local ))
1338+ {
13071339 goto error ;
1340+ }
13081341 else if (ste -> ste_type == ClassBlock && !drop_class_free (ste , newfree ))
13091342 goto error ;
13101343 /* Records the results of the analysis in the symbol table entry */
0 commit comments