Skip to content

Commit 909adb5

Browse files
gh-109219: propagate free vars through type param scopes (#109377)
Co-authored-by: Jelle Zijlstra <[email protected]>
1 parent 4a54074 commit 909adb5

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
@@ -836,8 +836,7 @@ update_symbols(PyObject *symbols, PyObject *scopes,
836836
the class that has the same name as a local
837837
or global in the class scope.
838838
*/
839-
if (classflag &&
840-
PyLong_AS_LONG(v) & (DEF_BOUND | DEF_GLOBAL)) {
839+
if (classflag) {
841840
long flags = PyLong_AS_LONG(v) | DEF_FREE_CLASS;
842841
v_new = PyLong_FromLong(flags);
843842
if (!v_new) {
@@ -1078,7 +1077,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
10781077
goto error;
10791078
/* Records the results of the analysis in the symbol table entry */
10801079
if (!update_symbols(ste->ste_symbols, scopes, bound, newfree, inlined_cells,
1081-
ste->ste_type == ClassBlock))
1080+
(ste->ste_type == ClassBlock) || ste->ste_can_see_class_scope))
10821081
goto error;
10831082

10841083
temp = PyNumber_InPlaceOr(free, newfree);

0 commit comments

Comments
 (0)