@@ -575,7 +575,8 @@ is_free_in_any_child(PySTEntryObject *entry, PyObject *key)
575575
576576static int
577577inline_comprehension (PySTEntryObject * ste , PySTEntryObject * comp ,
578- PyObject * scopes , PyObject * comp_free )
578+ PyObject * scopes , PyObject * comp_free ,
579+ PyObject * promote_to_cell )
579580{
580581 PyObject * k , * v ;
581582 Py_ssize_t pos = 0 ;
@@ -611,7 +612,9 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
611612 // cell vars in comprehension that are locals in outer scope
612613 // must be promoted to cell so u_cellvars isn't wrong
613614 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+ }
615618 }
616619
617620 // free vars in comprehension that are locals in outer scope can
@@ -638,7 +641,7 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
638641*/
639642
640643static int
641- analyze_cells (PyObject * scopes , PyObject * free )
644+ analyze_cells (PyObject * scopes , PyObject * free , PyObject * promote_to_cell )
642645{
643646 PyObject * name , * v , * v_cell ;
644647 int success = 0 ;
@@ -653,7 +656,7 @@ analyze_cells(PyObject *scopes, PyObject *free)
653656 scope = PyLong_AS_LONG (v );
654657 if (scope != LOCAL )
655658 continue ;
656- if (!PySet_Contains (free , name ))
659+ if (!PySet_Contains (free , name ) && ! PySet_Contains ( promote_to_cell , name ) )
657660 continue ;
658661 /* Replace LOCAL with CELL for this name, and remove
659662 from free. It is safe to replace the value of name
@@ -803,7 +806,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
803806 PyObject * global )
804807{
805808 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 ;
807810 PyObject * temp ;
808811 int success = 0 ;
809812 Py_ssize_t i , pos = 0 ;
@@ -835,6 +838,9 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
835838 newbound = PySet_New (NULL );
836839 if (!newbound )
837840 goto error ;
841+ promote_to_cell = PySet_New (NULL );
842+ if (!promote_to_cell )
843+ goto error ;
838844
839845 /* Class namespace has no effect on names visible in
840846 nested functions, so populate the global and bound
@@ -915,7 +921,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
915921 goto error ;
916922 }
917923 if (inline_comp ) {
918- if (!inline_comprehension (ste , entry , scopes , child_free )) {
924+ if (!inline_comprehension (ste , entry , scopes , child_free , promote_to_cell )) {
919925 Py_DECREF (child_free );
920926 goto error ;
921927 }
@@ -946,7 +952,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
946952 }
947953
948954 /* 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 ))
950956 goto error ;
951957 else if (ste -> ste_type == ClassBlock && !drop_class_free (ste , newfree ))
952958 goto error ;
@@ -966,6 +972,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
966972 Py_XDECREF (newbound );
967973 Py_XDECREF (newglobal );
968974 Py_XDECREF (newfree );
975+ Py_XDECREF (promote_to_cell );
969976 if (!success )
970977 assert (PyErr_Occurred ());
971978 return success ;
0 commit comments