Skip to content

Commit 35c633d

Browse files
miss-islingtoncarljmJelleZijlstra
authored
[3.12] gh-109219: propagate free vars through type param scopes (GH-109377) (#109410)
gh-109219: propagate free vars through type param scopes (GH-109377) (cherry picked from commit 909adb5) Co-authored-by: Carl Meyer <[email protected]> Co-authored-by: Jelle Zijlstra <[email protected]>
1 parent 52a9c57 commit 35c633d

File tree

3 files changed

+17
-3
lines changed

3 files changed

+17
-3
lines changed

Lib/test/test_type_params.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,19 @@ class Cls:
694694
cls = ns["outer"]()
695695
self.assertEqual(cls.Alias.__value__, "class")
696696

697+
def test_nested_free(self):
698+
ns = run_code("""
699+
def f():
700+
T = str
701+
class C:
702+
T = int
703+
class D[U](T):
704+
x = T
705+
return C
706+
""")
707+
C = ns["f"]()
708+
self.assertIn(int, C.D.__bases__)
709+
self.assertIs(C.D.x, str)
697710

698711
class TypeParamsManglingTest(unittest.TestCase):
699712
def test_mangling(self):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix compiling type param scopes that use a name which is also free in an
2+
inner scope.

Python/symtable.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -801,8 +801,7 @@ update_symbols(PyObject *symbols, PyObject *scopes,
801801
the class that has the same name as a local
802802
or global in the class scope.
803803
*/
804-
if (classflag &&
805-
PyLong_AS_LONG(v) & (DEF_BOUND | DEF_GLOBAL)) {
804+
if (classflag) {
806805
long flags = PyLong_AS_LONG(v) | DEF_FREE_CLASS;
807806
v_new = PyLong_FromLong(flags);
808807
if (!v_new) {
@@ -1037,7 +1036,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
10371036
goto error;
10381037
/* Records the results of the analysis in the symbol table entry */
10391038
if (!update_symbols(ste->ste_symbols, scopes, bound, newfree, inlined_cells,
1040-
ste->ste_type == ClassBlock))
1039+
(ste->ste_type == ClassBlock) || ste->ste_can_see_class_scope))
10411040
goto error;
10421041

10431042
temp = PyNumber_InPlaceOr(free, newfree);

0 commit comments

Comments
 (0)