@@ -78,6 +78,8 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block,
78
78
ste -> ste_symbols = NULL ;
79
79
ste -> ste_varnames = NULL ;
80
80
ste -> ste_children = NULL ;
81
+ ste -> ste_current_typeparam_overlay = NULL ;
82
+ ste -> ste_typeparam_overlays = NULL ;
81
83
82
84
ste -> ste_directives = NULL ;
83
85
@@ -141,6 +143,8 @@ ste_dealloc(PySTEntryObject *ste)
141
143
Py_XDECREF (ste -> ste_varnames );
142
144
Py_XDECREF (ste -> ste_children );
143
145
Py_XDECREF (ste -> ste_directives );
146
+ Py_XDECREF (ste -> ste_typeparam_overlays );
147
+ Py_XDECREF (ste -> ste_current_typeparam_overlay );
144
148
PyObject_Free (ste );
145
149
}
146
150
@@ -389,7 +393,21 @@ PySymtable_Lookup(struct symtable *st, void *key)
389
393
long
390
394
_PyST_GetSymbol (PySTEntryObject * ste , PyObject * name )
391
395
{
392
- PyObject * v = PyDict_GetItemWithError (ste -> ste_symbols , name );
396
+ PyObject * v ;
397
+ if (ste -> ste_current_typeparam_overlay ) {
398
+ assert (ste -> ste_typeparam_overlays != NULL );
399
+ PyObject * inner_ste = PyDict_GetItemWithError (ste -> ste_typeparam_overlays ,
400
+ ste -> ste_current_typeparam_overlay );
401
+ if (inner_ste == NULL ) {
402
+ assert (PyErr_Occurred ());
403
+ return 0 ;
404
+ }
405
+ v = PyDict_GetItemWithError (((PySTEntryObject * )inner_ste )-> ste_symbols , name );
406
+ assert (v != NULL );
407
+ }
408
+ else {
409
+ v = PyDict_GetItemWithError (ste -> ste_symbols , name );
410
+ }
393
411
if (!v )
394
412
return 0 ;
395
413
assert (PyLong_Check (v ));
400
418
_PyST_GetScope (PySTEntryObject * ste , PyObject * name )
401
419
{
402
420
long symbol = _PyST_GetSymbol (ste , name );
421
+ assert (!PyErr_Occurred ());
403
422
return (symbol >> SCOPE_OFFSET ) & SCOPE_MASK ;
404
423
}
405
424
@@ -959,6 +978,46 @@ symtable_exit_block(struct symtable *st)
959
978
return 1 ;
960
979
}
961
980
981
+ static int
982
+ symtable_enter_typeparam_overlay (struct symtable * st , identifier name ,
983
+ void * ast , int lineno , int col_offset ,
984
+ int end_lineno , int end_col_offset )
985
+ {
986
+ PySTEntryObject * ste = ste_new (st , name , TypeParamBlock , ast , lineno , col_offset ,
987
+ end_lineno , end_col_offset );
988
+ if (ste == NULL ) {
989
+ return 0 ;
990
+ }
991
+ PyObject * key = PyLong_FromVoidPtr (ast );
992
+ if (key == NULL ) {
993
+ Py_DECREF (ste );
994
+ return 0 ;
995
+ }
996
+ struct _symtable_entry * cur = st -> st_cur ;
997
+ cur -> ste_current_typeparam_overlay = Py_NewRef (key );
998
+ if (cur -> ste_typeparam_overlays == NULL ) {
999
+ cur -> ste_typeparam_overlays = PyDict_New ();
1000
+ if (cur -> ste_typeparam_overlays == NULL ) {
1001
+ Py_DECREF (key );
1002
+ Py_DECREF (ste );
1003
+ return 0 ;
1004
+ }
1005
+ }
1006
+ if (PyDict_SetItem (cur -> ste_typeparam_overlays , key , (PyObject * )ste ) < 0 ) {
1007
+ Py_DECREF (key );
1008
+ Py_DECREF (ste );
1009
+ return 0 ;
1010
+ }
1011
+ Py_DECREF (key );
1012
+ Py_DECREF (ste );
1013
+ return 1 ;
1014
+ }
1015
+
1016
+ static int symtable_leave_typeparam_overlay (struct symtable * st ) {
1017
+ Py_CLEAR (st -> st_cur -> ste_current_typeparam_overlay );
1018
+ return 1 ;
1019
+ }
1020
+
962
1021
static int
963
1022
symtable_enter_block (struct symtable * st , identifier name , _Py_block_ty block ,
964
1023
void * ast , int lineno , int col_offset ,
@@ -1014,6 +1073,47 @@ symtable_lookup(struct symtable *st, PyObject *name)
1014
1073
return ret ;
1015
1074
}
1016
1075
1076
+ static int
1077
+ symtable_add_typeparam (struct symtable * st , PyObject * name ,
1078
+ int lineno , int col_offset , int end_lineno , int end_col_offset )
1079
+ {
1080
+ PyObject * typeparams ;
1081
+ PyObject * current ;
1082
+ if (!(typeparams = PyDict_GetItemWithError (st -> st_cur -> ste_typeparam_overlays ,
1083
+ st -> st_cur -> ste_current_typeparam_overlay ))) {
1084
+ if (PyErr_Occurred ()) {
1085
+ return 0 ;
1086
+ }
1087
+ else {
1088
+ PyErr_SetString (PyExc_SystemError , "Invalid typeparam overlay" );
1089
+ return 0 ;
1090
+ }
1091
+ }
1092
+ assert (Py_IS_TYPE (typeparams , & PySTEntry_Type ));
1093
+ struct _symtable_entry * ste = (struct _symtable_entry * )typeparams ;
1094
+ PyObject * dict = ste -> ste_symbols ;
1095
+ if ((current = PyDict_GetItemWithError (dict , name ))) {
1096
+ PyErr_Format (PyExc_SyntaxError , "duplicate type parameter '%U'" , name );
1097
+ PyErr_RangedSyntaxLocationObject (st -> st_filename ,
1098
+ lineno , col_offset + 1 ,
1099
+ end_lineno , end_col_offset + 1 );
1100
+ return 0 ;
1101
+ }
1102
+ else if (PyErr_Occurred ()) {
1103
+ return 0 ;
1104
+ }
1105
+ PyObject * flags = PyLong_FromLong (CELL << SCOPE_OFFSET );
1106
+ if (flags == NULL ) {
1107
+ return 0 ;
1108
+ }
1109
+ if (PyDict_SetItem (dict , name , flags ) < 0 ) {
1110
+ Py_DECREF (flags );
1111
+ return 0 ;
1112
+ }
1113
+ Py_DECREF (flags );
1114
+ return 1 ;
1115
+ }
1116
+
1017
1117
static int
1018
1118
symtable_add_def_helper (struct symtable * st , PyObject * name , int flag , struct _symtable_entry * ste ,
1019
1119
int lineno , int col_offset , int end_lineno , int end_col_offset )
@@ -1199,9 +1299,9 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
1199
1299
if (s -> v .FunctionDef .decorator_list )
1200
1300
VISIT_SEQ (st , expr , s -> v .FunctionDef .decorator_list );
1201
1301
if (s -> v .FunctionDef .typeparams ) {
1202
- if (!symtable_enter_block (st , s -> v .FunctionDef .name ,
1203
- TypeParamBlock , (void * )s ,
1204
- LOCATION (s ))) {
1302
+ if (!symtable_enter_typeparam_overlay (st , s -> v .FunctionDef .name ,
1303
+ (void * )s -> v . FunctionDef . typeparams ,
1304
+ LOCATION (s ))) {
1205
1305
VISIT_QUIT (st , 0 );
1206
1306
}
1207
1307
VISIT_SEQ (st , typeparam , s -> v .FunctionDef .typeparams );
@@ -1218,7 +1318,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
1218
1318
if (!symtable_exit_block (st ))
1219
1319
VISIT_QUIT (st , 0 );
1220
1320
if (s -> v .FunctionDef .typeparams &&
1221
- !symtable_exit_block (st )) {
1321
+ !symtable_leave_typeparam_overlay (st )) {
1222
1322
VISIT_QUIT (st , 0 );
1223
1323
}
1224
1324
break ;
@@ -1749,17 +1849,17 @@ symtable_visit_typeparam(struct symtable *st, typeparam_ty tp)
1749
1849
}
1750
1850
switch (tp -> kind ) {
1751
1851
case TypeVar_kind :
1752
- if (!symtable_add_def (st , tp -> v .TypeVar .name , DEF_PARAM , LOCATION (tp )))
1852
+ if (!symtable_add_typeparam (st , tp -> v .TypeVar .name , LOCATION (tp )))
1753
1853
VISIT_QUIT (st , 0 );
1754
1854
if (tp -> v .TypeVar .bound )
1755
1855
VISIT (st , expr , tp -> v .TypeVar .bound );
1756
1856
break ;
1757
1857
case TypeVarTuple_kind :
1758
- if (!symtable_add_def (st , tp -> v .TypeVarTuple .name , DEF_PARAM , LOCATION (tp )))
1858
+ if (!symtable_add_typeparam (st , tp -> v .TypeVarTuple .name , LOCATION (tp )))
1759
1859
VISIT_QUIT (st , 0 );
1760
1860
break ;
1761
1861
case ParamSpec_kind :
1762
- if (!symtable_add_def (st , tp -> v .ParamSpec .name , DEF_PARAM , LOCATION (tp )))
1862
+ if (!symtable_add_typeparam (st , tp -> v .ParamSpec .name , LOCATION (tp )))
1763
1863
VISIT_QUIT (st , 0 );
1764
1864
break ;
1765
1865
}
0 commit comments