@@ -103,6 +103,7 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block,
103
103
ste -> ste_children = NULL ;
104
104
105
105
ste -> ste_directives = NULL ;
106
+ ste -> ste_mangled_names = NULL ;
106
107
107
108
ste -> ste_type = block ;
108
109
ste -> ste_nested = 0 ;
@@ -166,6 +167,7 @@ ste_dealloc(PySTEntryObject *ste)
166
167
Py_XDECREF (ste -> ste_varnames );
167
168
Py_XDECREF (ste -> ste_children );
168
169
Py_XDECREF (ste -> ste_directives );
170
+ Py_XDECREF (ste -> ste_mangled_names );
169
171
PyObject_Free (ste );
170
172
}
171
173
@@ -1338,6 +1340,11 @@ symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,
1338
1340
if (prev ) {
1339
1341
ste -> ste_comp_iter_expr = prev -> ste_comp_iter_expr ;
1340
1342
}
1343
+ /* No need to inherit ste_mangled_names in classes, where all names
1344
+ * are mangled. */
1345
+ if (prev && prev -> ste_mangled_names != NULL && block != ClassBlock ) {
1346
+ ste -> ste_mangled_names = Py_NewRef (prev -> ste_mangled_names );
1347
+ }
1341
1348
/* The entry is owned by the stack. Borrow it for st_cur. */
1342
1349
Py_DECREF (ste );
1343
1350
st -> st_cur = ste ;
@@ -1363,7 +1370,7 @@ symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,
1363
1370
static long
1364
1371
symtable_lookup_entry (struct symtable * st , PySTEntryObject * ste , PyObject * name )
1365
1372
{
1366
- PyObject * mangled = _Py_Mangle (st -> st_private , name );
1373
+ PyObject * mangled = _Py_MaybeMangle (st -> st_private , ste , name );
1367
1374
if (!mangled )
1368
1375
return 0 ;
1369
1376
long ret = _PyST_GetSymbol (ste , mangled );
@@ -1384,8 +1391,7 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s
1384
1391
PyObject * o ;
1385
1392
PyObject * dict ;
1386
1393
long val ;
1387
- PyObject * mangled = _Py_Mangle (st -> st_private , name );
1388
-
1394
+ PyObject * mangled = _Py_MaybeMangle (st -> st_private , st -> st_cur , name );
1389
1395
1390
1396
if (!mangled )
1391
1397
return 0 ;
@@ -1474,6 +1480,11 @@ static int
1474
1480
symtable_add_def (struct symtable * st , PyObject * name , int flag ,
1475
1481
int lineno , int col_offset , int end_lineno , int end_col_offset )
1476
1482
{
1483
+ if ((flag & DEF_TYPE_PARAM ) && st -> st_cur -> ste_mangled_names != NULL ) {
1484
+ if (PySet_Add (st -> st_cur -> ste_mangled_names , name ) < 0 ) {
1485
+ return 0 ;
1486
+ }
1487
+ }
1477
1488
return symtable_add_def_helper (st , name , flag , st -> st_cur ,
1478
1489
lineno , col_offset , end_lineno , end_col_offset );
1479
1490
}
@@ -1508,7 +1519,6 @@ symtable_enter_type_param_block(struct symtable *st, identifier name,
1508
1519
lineno , col_offset , end_lineno , end_col_offset )) {
1509
1520
return 0 ;
1510
1521
}
1511
- st -> st_private = name ;
1512
1522
// This is used for setting the generic base
1513
1523
_Py_DECLARE_STR (generic_base , ".generic_base" );
1514
1524
if (!symtable_add_def (st , & _Py_STR (generic_base ), DEF_LOCAL ,
@@ -1597,7 +1607,7 @@ symtable_record_directive(struct symtable *st, identifier name, int lineno,
1597
1607
if (!st -> st_cur -> ste_directives )
1598
1608
return 0 ;
1599
1609
}
1600
- mangled = _Py_Mangle (st -> st_private , name );
1610
+ mangled = _Py_MaybeMangle (st -> st_private , st -> st_cur , name );
1601
1611
if (!mangled )
1602
1612
return 0 ;
1603
1613
data = Py_BuildValue ("(Niiii)" , mangled , lineno , col_offset , end_lineno , end_col_offset );
@@ -1673,13 +1683,19 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
1673
1683
VISIT_QUIT (st , 0 );
1674
1684
if (s -> v .ClassDef .decorator_list )
1675
1685
VISIT_SEQ (st , expr , s -> v .ClassDef .decorator_list );
1686
+ tmp = st -> st_private ;
1676
1687
if (asdl_seq_LEN (s -> v .ClassDef .type_params ) > 0 ) {
1677
1688
if (!symtable_enter_type_param_block (st , s -> v .ClassDef .name ,
1678
1689
(void * )s -> v .ClassDef .type_params ,
1679
1690
false, false, s -> kind ,
1680
1691
LOCATION (s ))) {
1681
1692
VISIT_QUIT (st , 0 );
1682
1693
}
1694
+ st -> st_private = s -> v .ClassDef .name ;
1695
+ st -> st_cur -> ste_mangled_names = PySet_New (NULL );
1696
+ if (!st -> st_cur -> ste_mangled_names ) {
1697
+ VISIT_QUIT (st , 0 );
1698
+ }
1683
1699
VISIT_SEQ (st , type_param , s -> v .ClassDef .type_params );
1684
1700
}
1685
1701
VISIT_SEQ (st , expr , s -> v .ClassDef .bases );
@@ -1688,7 +1704,6 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
1688
1704
(void * )s , s -> lineno , s -> col_offset ,
1689
1705
s -> end_lineno , s -> end_col_offset ))
1690
1706
VISIT_QUIT (st , 0 );
1691
- tmp = st -> st_private ;
1692
1707
st -> st_private = s -> v .ClassDef .name ;
1693
1708
if (asdl_seq_LEN (s -> v .ClassDef .type_params ) > 0 ) {
1694
1709
if (!symtable_add_def (st , & _Py_ID (__type_params__ ),
@@ -1702,13 +1717,13 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
1702
1717
}
1703
1718
}
1704
1719
VISIT_SEQ (st , stmt , s -> v .ClassDef .body );
1705
- st -> st_private = tmp ;
1706
1720
if (!symtable_exit_block (st ))
1707
1721
VISIT_QUIT (st , 0 );
1708
1722
if (asdl_seq_LEN (s -> v .ClassDef .type_params ) > 0 ) {
1709
1723
if (!symtable_exit_block (st ))
1710
1724
VISIT_QUIT (st , 0 );
1711
1725
}
1726
+ st -> st_private = tmp ;
1712
1727
break ;
1713
1728
}
1714
1729
case TypeAlias_kind : {
@@ -2776,6 +2791,26 @@ _Py_SymtableStringObjectFlags(const char *str, PyObject *filename,
2776
2791
return st ;
2777
2792
}
2778
2793
2794
+ PyObject *
2795
+ _Py_MaybeMangle (PyObject * privateobj , PySTEntryObject * ste , PyObject * name )
2796
+ {
2797
+ /* Special case for type parameter blocks around generic classes:
2798
+ * we want to mangle type parameter names (so a type param with a private
2799
+ * name can be used inside the class body), but we don't want to mangle
2800
+ * any other names that appear within the type parameter scope.
2801
+ */
2802
+ if (ste -> ste_mangled_names != NULL ) {
2803
+ int result = PySet_Contains (ste -> ste_mangled_names , name );
2804
+ if (result < 0 ) {
2805
+ return NULL ;
2806
+ }
2807
+ if (result == 0 ) {
2808
+ return Py_NewRef (name );
2809
+ }
2810
+ }
2811
+ return _Py_Mangle (privateobj , name );
2812
+ }
2813
+
2779
2814
PyObject *
2780
2815
_Py_Mangle (PyObject * privateobj , PyObject * ident )
2781
2816
{
0 commit comments