@@ -103,6 +103,7 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block,
103103 ste -> ste_children = NULL ;
104104
105105 ste -> ste_directives = NULL ;
106+ ste -> ste_mangled_names = NULL ;
106107
107108 ste -> ste_type = block ;
108109 ste -> ste_nested = 0 ;
@@ -166,6 +167,7 @@ ste_dealloc(PySTEntryObject *ste)
166167 Py_XDECREF (ste -> ste_varnames );
167168 Py_XDECREF (ste -> ste_children );
168169 Py_XDECREF (ste -> ste_directives );
170+ Py_XDECREF (ste -> ste_mangled_names );
169171 PyObject_Free (ste );
170172}
171173
@@ -1338,6 +1340,11 @@ symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,
13381340 if (prev ) {
13391341 ste -> ste_comp_iter_expr = prev -> ste_comp_iter_expr ;
13401342 }
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+ }
13411348 /* The entry is owned by the stack. Borrow it for st_cur. */
13421349 Py_DECREF (ste );
13431350 st -> st_cur = ste ;
@@ -1363,7 +1370,7 @@ symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,
13631370static long
13641371symtable_lookup_entry (struct symtable * st , PySTEntryObject * ste , PyObject * name )
13651372{
1366- PyObject * mangled = _Py_Mangle (st -> st_private , name );
1373+ PyObject * mangled = _Py_MaybeMangle (st -> st_private , ste , name );
13671374 if (!mangled )
13681375 return 0 ;
13691376 long ret = _PyST_GetSymbol (ste , mangled );
@@ -1384,8 +1391,7 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s
13841391 PyObject * o ;
13851392 PyObject * dict ;
13861393 long val ;
1387- PyObject * mangled = _Py_Mangle (st -> st_private , name );
1388-
1394+ PyObject * mangled = _Py_MaybeMangle (st -> st_private , st -> st_cur , name );
13891395
13901396 if (!mangled )
13911397 return 0 ;
@@ -1474,6 +1480,11 @@ static int
14741480symtable_add_def (struct symtable * st , PyObject * name , int flag ,
14751481 int lineno , int col_offset , int end_lineno , int end_col_offset )
14761482{
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+ }
14771488 return symtable_add_def_helper (st , name , flag , st -> st_cur ,
14781489 lineno , col_offset , end_lineno , end_col_offset );
14791490}
@@ -1508,7 +1519,6 @@ symtable_enter_type_param_block(struct symtable *st, identifier name,
15081519 lineno , col_offset , end_lineno , end_col_offset )) {
15091520 return 0 ;
15101521 }
1511- st -> st_private = name ;
15121522 // This is used for setting the generic base
15131523 _Py_DECLARE_STR (generic_base , ".generic_base" );
15141524 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,
15971607 if (!st -> st_cur -> ste_directives )
15981608 return 0 ;
15991609 }
1600- mangled = _Py_Mangle (st -> st_private , name );
1610+ mangled = _Py_MaybeMangle (st -> st_private , st -> st_cur , name );
16011611 if (!mangled )
16021612 return 0 ;
16031613 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)
16731683 VISIT_QUIT (st , 0 );
16741684 if (s -> v .ClassDef .decorator_list )
16751685 VISIT_SEQ (st , expr , s -> v .ClassDef .decorator_list );
1686+ tmp = st -> st_private ;
16761687 if (asdl_seq_LEN (s -> v .ClassDef .type_params ) > 0 ) {
16771688 if (!symtable_enter_type_param_block (st , s -> v .ClassDef .name ,
16781689 (void * )s -> v .ClassDef .type_params ,
16791690 false, false, s -> kind ,
16801691 LOCATION (s ))) {
16811692 VISIT_QUIT (st , 0 );
16821693 }
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+ }
16831699 VISIT_SEQ (st , type_param , s -> v .ClassDef .type_params );
16841700 }
16851701 VISIT_SEQ (st , expr , s -> v .ClassDef .bases );
@@ -1688,7 +1704,6 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
16881704 (void * )s , s -> lineno , s -> col_offset ,
16891705 s -> end_lineno , s -> end_col_offset ))
16901706 VISIT_QUIT (st , 0 );
1691- tmp = st -> st_private ;
16921707 st -> st_private = s -> v .ClassDef .name ;
16931708 if (asdl_seq_LEN (s -> v .ClassDef .type_params ) > 0 ) {
16941709 if (!symtable_add_def (st , & _Py_ID (__type_params__ ),
@@ -1702,13 +1717,13 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
17021717 }
17031718 }
17041719 VISIT_SEQ (st , stmt , s -> v .ClassDef .body );
1705- st -> st_private = tmp ;
17061720 if (!symtable_exit_block (st ))
17071721 VISIT_QUIT (st , 0 );
17081722 if (asdl_seq_LEN (s -> v .ClassDef .type_params ) > 0 ) {
17091723 if (!symtable_exit_block (st ))
17101724 VISIT_QUIT (st , 0 );
17111725 }
1726+ st -> st_private = tmp ;
17121727 break ;
17131728 }
17141729 case TypeAlias_kind : {
@@ -2776,6 +2791,26 @@ _Py_SymtableStringObjectFlags(const char *str, PyObject *filename,
27762791 return st ;
27772792}
27782793
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+
27792814PyObject *
27802815_Py_Mangle (PyObject * privateobj , PyObject * ident )
27812816{
0 commit comments