@@ -632,7 +632,7 @@ is_free_in_any_child(PySTEntryObject *entry, PyObject *key)
632
632
static int
633
633
inline_comprehension (PySTEntryObject * ste ,PySTEntryObject * comp ,
634
634
PyObject * scopes ,PyObject * comp_free ,
635
- PyObject * promote_to_cell )
635
+ PyObject * inlined_cells )
636
636
{
637
637
PyObject * k ,* v ;
638
638
Py_ssize_t pos = 0 ;
@@ -645,6 +645,11 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
645
645
}
646
646
int scope = (comp_flags >>SCOPE_OFFSET )& SCOPE_MASK ;
647
647
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
+ }
648
653
PyObject * existing = PyDict_GetItemWithError (ste -> ste_symbols ,k );
649
654
if (existing == NULL && PyErr_Occurred ()) {
650
655
return 0 ;
@@ -665,14 +670,6 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
665
670
}
666
671
else {
667
672
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
-
676
673
// free vars in comprehension that are locals in outer scope can
677
674
// now simply be locals, unless they are free in comp children,
678
675
// or if the outer scope is a class block
@@ -698,7 +695,7 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
698
695
*/
699
696
700
697
static int
701
- analyze_cells (PyObject * scopes ,PyObject * free ,PyObject * promote_to_cell )
698
+ analyze_cells (PyObject * scopes ,PyObject * free ,PyObject * inlined_cells )
702
699
{
703
700
PyObject * name ,* v ,* v_cell ;
704
701
int success = 0 ;
@@ -713,7 +710,7 @@ analyze_cells(PyObject *scopes, PyObject *free, PyObject *promote_to_cell)
713
710
scope = PyLong_AS_LONG (v );
714
711
if (scope != LOCAL )
715
712
continue ;
716
- if (!PySet_Contains (free ,name )&& !PySet_Contains (promote_to_cell ,name ))
713
+ if (!PySet_Contains (free ,name )&& !PySet_Contains (inlined_cells ,name ))
717
714
continue ;
718
715
/* Replace LOCAL with CELL for this name, and remove
719
716
from free. It is safe to replace the value of name
@@ -753,7 +750,8 @@ drop_class_free(PySTEntryObject *ste, PyObject *free)
753
750
*/
754
751
static int
755
752
update_symbols (PyObject * symbols ,PyObject * scopes ,
756
- PyObject * bound ,PyObject * free ,int classflag )
753
+ PyObject * bound ,PyObject * free ,
754
+ PyObject * inlined_cells ,int classflag )
757
755
{
758
756
PyObject * name = NULL ,* itr = NULL ;
759
757
PyObject * v = NULL ,* v_scope = NULL ,* v_new = NULL ,* v_free = NULL ;
@@ -764,6 +762,9 @@ update_symbols(PyObject *symbols, PyObject *scopes,
764
762
long scope ,flags ;
765
763
assert (PyLong_Check (v ));
766
764
flags = PyLong_AS_LONG (v );
765
+ if (PySet_Contains (inlined_cells ,name )) {
766
+ flags |=DEF_COMP_CELL ;
767
+ }
767
768
v_scope = PyDict_GetItemWithError (scopes ,name );
768
769
assert (v_scope && PyLong_Check (v_scope ));
769
770
scope = PyLong_AS_LONG (v_scope );
@@ -870,7 +871,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
870
871
PySTEntryObject * class_entry )
871
872
{
872
873
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 ;
874
875
PyObject * temp ;
875
876
int success = 0 ;
876
877
Py_ssize_t i ,pos = 0 ;
@@ -902,8 +903,8 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
902
903
newbound = PySet_New (NULL );
903
904
if (!newbound )
904
905
gotoerror ;
905
- promote_to_cell = PySet_New (NULL );
906
- if (!promote_to_cell )
906
+ inlined_cells = PySet_New (NULL );
907
+ if (!inlined_cells )
907
908
gotoerror ;
908
909
909
910
/* Class namespace has no effect on names visible in
@@ -997,7 +998,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
997
998
gotoerror ;
998
999
}
999
1000
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 )) {
1001
1002
Py_DECREF (child_free );
1002
1003
gotoerror ;
1003
1004
}
@@ -1028,12 +1029,12 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
1028
1029
}
1029
1030
1030
1031
/* 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 ))
1032
1033
gotoerror ;
1033
1034
else if (ste -> ste_type == ClassBlock && !drop_class_free (ste ,newfree ))
1034
1035
gotoerror ;
1035
1036
/* 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 ,
1037
1038
ste -> ste_type == ClassBlock ))
1038
1039
gotoerror ;
1039
1040
@@ -1048,7 +1049,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
1048
1049
Py_XDECREF (newbound );
1049
1050
Py_XDECREF (newglobal );
1050
1051
Py_XDECREF (newfree );
1051
- Py_XDECREF (promote_to_cell );
1052
+ Py_XDECREF (inlined_cells );
1052
1053
if (!success )
1053
1054
assert (PyErr_Occurred ());
1054
1055
return success ;