@@ -632,7 +632,7 @@ is_free_in_any_child(PySTEntryObject *entry, PyObject *key)
632632static int
633633inline_comprehension (PySTEntryObject * ste , PySTEntryObject * comp ,
634634 PyObject * scopes , PyObject * comp_free ,
635- PyObject * promote_to_cell )
635+ PyObject * inlined_cells )
636636{
637637 PyObject * k , * v ;
638638 Py_ssize_t pos = 0 ;
@@ -645,6 +645,11 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
645645 }
646646 int scope = (comp_flags >> SCOPE_OFFSET ) & SCOPE_MASK ;
647647 int only_flags = comp_flags & ((1 << SCOPE_OFFSET ) - 1 );
648+ if (scope == CELL || only_flags & DEF_COMP_CELL ) {
649+ if (PySet_Add (inlined_cells , k ) < 0 ) {
650+ return 0 ;
651+ }
652+ }
648653 PyObject * existing = PyDict_GetItemWithError (ste -> ste_symbols , k );
649654 if (existing == NULL && PyErr_Occurred ()) {
650655 return 0 ;
@@ -665,14 +670,6 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
665670 }
666671 else {
667672 if (PyLong_AsLong (existing ) & DEF_BOUND ) {
668- // cell vars in comprehension that are locals in outer scope
669- // must be promoted to cell so u_cellvars isn't wrong
670- if (scope == CELL && _PyST_IsFunctionLike (ste )) {
671- if (PySet_Add (promote_to_cell , k ) < 0 ) {
672- return 0 ;
673- }
674- }
675-
676673 // free vars in comprehension that are locals in outer scope can
677674 // now simply be locals, unless they are free in comp children,
678675 // or if the outer scope is a class block
@@ -698,7 +695,7 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
698695*/
699696
700697static int
701- analyze_cells (PyObject * scopes , PyObject * free , PyObject * promote_to_cell )
698+ analyze_cells (PyObject * scopes , PyObject * free , PyObject * inlined_cells )
702699{
703700 PyObject * name , * v , * v_cell ;
704701 int success = 0 ;
@@ -713,7 +710,7 @@ analyze_cells(PyObject *scopes, PyObject *free, PyObject *promote_to_cell)
713710 scope = PyLong_AS_LONG (v );
714711 if (scope != LOCAL )
715712 continue ;
716- if (!PySet_Contains (free , name ) && !PySet_Contains (promote_to_cell , name ))
713+ if (!PySet_Contains (free , name ) && !PySet_Contains (inlined_cells , name ))
717714 continue ;
718715 /* Replace LOCAL with CELL for this name, and remove
719716 from free. It is safe to replace the value of name
@@ -753,7 +750,8 @@ drop_class_free(PySTEntryObject *ste, PyObject *free)
753750*/
754751static int
755752update_symbols (PyObject * symbols , PyObject * scopes ,
756- PyObject * bound , PyObject * free , int classflag )
753+ PyObject * bound , PyObject * free ,
754+ PyObject * inlined_cells , int classflag )
757755{
758756 PyObject * name = NULL , * itr = NULL ;
759757 PyObject * v = NULL , * v_scope = NULL , * v_new = NULL , * v_free = NULL ;
@@ -764,6 +762,9 @@ update_symbols(PyObject *symbols, PyObject *scopes,
764762 long scope , flags ;
765763 assert (PyLong_Check (v ));
766764 flags = PyLong_AS_LONG (v );
765+ if (PySet_Contains (inlined_cells , name )) {
766+ flags |= DEF_COMP_CELL ;
767+ }
767768 v_scope = PyDict_GetItemWithError (scopes , name );
768769 assert (v_scope && PyLong_Check (v_scope ));
769770 scope = PyLong_AS_LONG (v_scope );
@@ -870,7 +871,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
870871 PySTEntryObject * class_entry )
871872{
872873 PyObject * name , * v , * local = NULL , * scopes = NULL , * newbound = NULL ;
873- PyObject * newglobal = NULL , * newfree = NULL , * promote_to_cell = NULL ;
874+ PyObject * newglobal = NULL , * newfree = NULL , * inlined_cells = NULL ;
874875 PyObject * temp ;
875876 int success = 0 ;
876877 Py_ssize_t i , pos = 0 ;
@@ -902,8 +903,8 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
902903 newbound = PySet_New (NULL );
903904 if (!newbound )
904905 goto error ;
905- promote_to_cell = PySet_New (NULL );
906- if (!promote_to_cell )
906+ inlined_cells = PySet_New (NULL );
907+ if (!inlined_cells )
907908 goto error ;
908909
909910 /* Class namespace has no effect on names visible in
@@ -997,7 +998,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
997998 goto error ;
998999 }
9991000 if (inline_comp ) {
1000- if (!inline_comprehension (ste , entry , scopes , child_free , promote_to_cell )) {
1001+ if (!inline_comprehension (ste , entry , scopes , child_free , inlined_cells )) {
10011002 Py_DECREF (child_free );
10021003 goto error ;
10031004 }
@@ -1028,12 +1029,12 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
10281029 }
10291030
10301031 /* Check if any local variables must be converted to cell variables */
1031- if (_PyST_IsFunctionLike (ste ) && !analyze_cells (scopes , newfree , promote_to_cell ))
1032+ if (_PyST_IsFunctionLike (ste ) && !analyze_cells (scopes , newfree , inlined_cells ))
10321033 goto error ;
10331034 else if (ste -> ste_type == ClassBlock && !drop_class_free (ste , newfree ))
10341035 goto error ;
10351036 /* Records the results of the analysis in the symbol table entry */
1036- if (!update_symbols (ste -> ste_symbols , scopes , bound , newfree ,
1037+ if (!update_symbols (ste -> ste_symbols , scopes , bound , newfree , inlined_cells ,
10371038 ste -> ste_type == ClassBlock ))
10381039 goto error ;
10391040
@@ -1048,7 +1049,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
10481049 Py_XDECREF (newbound );
10491050 Py_XDECREF (newglobal );
10501051 Py_XDECREF (newfree );
1051- Py_XDECREF (promote_to_cell );
1052+ Py_XDECREF (inlined_cells );
10521053 if (!success )
10531054 assert (PyErr_Occurred ());
10541055 return success ;
0 commit comments