@@ -56,6 +56,8 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block,
5656 if (ste -> ste_children == NULL )
5757 goto fail ;
5858
59+ ste -> ste_directives = NULL ;
60+
5961 ste -> ste_type = block ;
6062 ste -> ste_unoptimized = 0 ;
6163 ste -> ste_nested = 0 ;
@@ -102,6 +104,7 @@ ste_dealloc(PySTEntryObject *ste)
102104 Py_XDECREF (ste -> ste_symbols );
103105 Py_XDECREF (ste -> ste_varnames );
104106 Py_XDECREF (ste -> ste_children );
107+ Py_XDECREF (ste -> ste_directives );
105108 PyObject_Del (ste );
106109}
107110
@@ -319,6 +322,24 @@ PyST_GetScope(PySTEntryObject *ste, PyObject *name)
319322 return (PyLong_AS_LONG (v ) >> SCOPE_OFFSET ) & SCOPE_MASK ;
320323}
321324
325+ static int
326+ error_at_directive (PySTEntryObject * ste , PyObject * name )
327+ {
328+ Py_ssize_t i ;
329+ PyObject * data ;
330+ assert (ste -> ste_directives );
331+ for (i = 0 ; ; i ++ ) {
332+ data = PyList_GET_ITEM (ste -> ste_directives , i );
333+ assert (PyTuple_CheckExact (data ));
334+ if (PyTuple_GET_ITEM (data , 0 ) == name )
335+ break ;
336+ }
337+ PyErr_SyntaxLocationEx (ste -> ste_table -> st_filename ,
338+ PyLong_AsLong (PyTuple_GET_ITEM (data , 1 )),
339+ PyLong_AsLong (PyTuple_GET_ITEM (data , 2 )));
340+ return 0 ;
341+ }
342+
322343
323344/* Analyze raw symbol information to determine scope of each name.
324345
@@ -393,16 +414,13 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags,
393414 PyErr_Format (PyExc_SyntaxError ,
394415 "name '%U' is parameter and global" ,
395416 name );
396- PyErr_SyntaxLocationEx (ste -> ste_table -> st_filename ,
397- ste -> ste_lineno , ste -> ste_col_offset );
398-
399- return 0 ;
417+ return error_at_directive (ste , name );
400418 }
401419 if (flags & DEF_NONLOCAL ) {
402420 PyErr_Format (PyExc_SyntaxError ,
403421 "name '%U' is nonlocal and global" ,
404422 name );
405- return 0 ;
423+ return error_at_directive ( ste , name ) ;
406424 }
407425 SET_SCOPE (scopes , name , GLOBAL_EXPLICIT );
408426 if (PySet_Add (global , name ) < 0 )
@@ -416,19 +434,19 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags,
416434 PyErr_Format (PyExc_SyntaxError ,
417435 "name '%U' is parameter and nonlocal" ,
418436 name );
419- return 0 ;
437+ return error_at_directive ( ste , name ) ;
420438 }
421439 if (!bound ) {
422440 PyErr_Format (PyExc_SyntaxError ,
423441 "nonlocal declaration not allowed at module level" );
424- return 0 ;
442+ return error_at_directive ( ste , name ) ;
425443 }
426444 if (!PySet_Contains (bound , name )) {
427445 PyErr_Format (PyExc_SyntaxError ,
428446 "no binding for nonlocal '%U' found" ,
429447 name );
430448
431- return 0 ;
449+ return error_at_directive ( ste , name ) ;
432450 }
433451 SET_SCOPE (scopes , name , FREE );
434452 ste -> ste_free = 1 ;
@@ -1068,6 +1086,25 @@ symtable_new_tmpname(struct symtable *st)
10681086}
10691087
10701088
1089+ static int
1090+ symtable_record_directive (struct symtable * st , identifier name , stmt_ty s )
1091+ {
1092+ PyObject * data ;
1093+ int res ;
1094+ if (!st -> st_cur -> ste_directives ) {
1095+ st -> st_cur -> ste_directives = PyList_New (0 );
1096+ if (!st -> st_cur -> ste_directives )
1097+ return 0 ;
1098+ }
1099+ data = Py_BuildValue ("(Oii)" , name , s -> lineno , s -> col_offset );
1100+ if (!data )
1101+ return 0 ;
1102+ res = PyList_Append (st -> st_cur -> ste_directives , data );
1103+ Py_DECREF (data );
1104+ return res == 0 ;
1105+ }
1106+
1107+
10711108static int
10721109symtable_visit_stmt (struct symtable * st , stmt_ty s )
10731110{
@@ -1223,6 +1260,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
12231260 }
12241261 if (!symtable_add_def (st , name , DEF_GLOBAL ))
12251262 return 0 ;
1263+ if (!symtable_record_directive (st , name , s ))
1264+ return 0 ;
12261265 }
12271266 break ;
12281267 }
@@ -1252,6 +1291,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
12521291 }
12531292 if (!symtable_add_def (st , name , DEF_NONLOCAL ))
12541293 return 0 ;
1294+ if (!symtable_record_directive (st , name , s ))
1295+ return 0 ;
12551296 }
12561297 break ;
12571298 }
0 commit comments