@@ -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 ) {
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
if (!is_free_in_any_child (comp , k )) {
@@ -697,7 +694,7 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
697
694
*/
698
695
699
696
static int
700
- analyze_cells (PyObject * scopes , PyObject * free , PyObject * promote_to_cell )
697
+ analyze_cells (PyObject * scopes , PyObject * free , PyObject * inlined_cells )
701
698
{
702
699
PyObject * name , * v , * v_cell ;
703
700
int success = 0 ;
@@ -712,7 +709,7 @@ analyze_cells(PyObject *scopes, PyObject *free, PyObject *promote_to_cell)
712
709
scope = PyLong_AS_LONG (v );
713
710
if (scope != LOCAL )
714
711
continue ;
715
- if (!PySet_Contains (free , name ) && !PySet_Contains (promote_to_cell , name ))
712
+ if (!PySet_Contains (free , name ) && !PySet_Contains (inlined_cells , name ))
716
713
continue ;
717
714
/* Replace LOCAL with CELL for this name, and remove
718
715
from free. It is safe to replace the value of name
@@ -752,7 +749,8 @@ drop_class_free(PySTEntryObject *ste, PyObject *free)
752
749
*/
753
750
static int
754
751
update_symbols (PyObject * symbols , PyObject * scopes ,
755
- PyObject * bound , PyObject * free , int classflag )
752
+ PyObject * bound , PyObject * free ,
753
+ PyObject * inlined_cells , int classflag )
756
754
{
757
755
PyObject * name = NULL , * itr = NULL ;
758
756
PyObject * v = NULL , * v_scope = NULL , * v_new = NULL , * v_free = NULL ;
@@ -763,6 +761,9 @@ update_symbols(PyObject *symbols, PyObject *scopes,
763
761
long scope , flags ;
764
762
assert (PyLong_Check (v ));
765
763
flags = PyLong_AS_LONG (v );
764
+ if (PySet_Contains (inlined_cells , name )) {
765
+ flags |= DEF_COMP_CELL ;
766
+ }
766
767
v_scope = PyDict_GetItemWithError (scopes , name );
767
768
assert (v_scope && PyLong_Check (v_scope ));
768
769
scope = PyLong_AS_LONG (v_scope );
@@ -869,7 +870,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
869
870
PySTEntryObject * class_entry )
870
871
{
871
872
PyObject * name , * v , * local = NULL , * scopes = NULL , * newbound = NULL ;
872
- PyObject * newglobal = NULL , * newfree = NULL , * promote_to_cell = NULL ;
873
+ PyObject * newglobal = NULL , * newfree = NULL , * inlined_cells = NULL ;
873
874
PyObject * temp ;
874
875
int success = 0 ;
875
876
Py_ssize_t i , pos = 0 ;
@@ -901,8 +902,8 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
901
902
newbound = PySet_New (NULL );
902
903
if (!newbound )
903
904
goto error ;
904
- promote_to_cell = PySet_New (NULL );
905
- if (!promote_to_cell )
905
+ inlined_cells = PySet_New (NULL );
906
+ if (!inlined_cells )
906
907
goto error ;
907
908
908
909
/* Class namespace has no effect on names visible in
@@ -996,7 +997,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
996
997
goto error ;
997
998
}
998
999
if (inline_comp ) {
999
- if (!inline_comprehension (ste , entry , scopes , child_free , promote_to_cell )) {
1000
+ if (!inline_comprehension (ste , entry , scopes , child_free , inlined_cells )) {
1000
1001
Py_DECREF (child_free );
1001
1002
goto error ;
1002
1003
}
@@ -1027,12 +1028,12 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
1027
1028
}
1028
1029
1029
1030
/* Check if any local variables must be converted to cell variables */
1030
- if (_PyST_IsFunctionLike (ste ) && !analyze_cells (scopes , newfree , promote_to_cell ))
1031
+ if (_PyST_IsFunctionLike (ste ) && !analyze_cells (scopes , newfree , inlined_cells ))
1031
1032
goto error ;
1032
1033
else if (ste -> ste_type == ClassBlock && !drop_class_free (ste , newfree ))
1033
1034
goto error ;
1034
1035
/* Records the results of the analysis in the symbol table entry */
1035
- if (!update_symbols (ste -> ste_symbols , scopes , bound , newfree ,
1036
+ if (!update_symbols (ste -> ste_symbols , scopes , bound , newfree , inlined_cells ,
1036
1037
ste -> ste_type == ClassBlock ))
1037
1038
goto error ;
1038
1039
@@ -1047,7 +1048,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
1047
1048
Py_XDECREF (newbound );
1048
1049
Py_XDECREF (newglobal );
1049
1050
Py_XDECREF (newfree );
1050
- Py_XDECREF (promote_to_cell );
1051
+ Py_XDECREF (inlined_cells );
1051
1052
if (!success )
1052
1053
assert (PyErr_Occurred ());
1053
1054
return success ;
0 commit comments