@@ -312,7 +312,6 @@ PyCode_New(int argcount, int nlocals, int stacksize, int flags,
312312 co -> co_firstlineno = firstlineno ;
313313 Py_INCREF (lnotab );
314314 co -> co_lnotab = lnotab ;
315- /* PyObject_Print((PyObject *)co, stderr, 0); */
316315 }
317316 return co ;
318317}
@@ -1151,7 +1150,8 @@ parsestr(char *s)
11511150 * p ++ = c ;
11521151 break ;
11531152 case 'x' :
1154- if (isxdigit (Py_CHARMASK (s [0 ])) && isxdigit (Py_CHARMASK (s [1 ]))) {
1153+ if (isxdigit (Py_CHARMASK (s [0 ]))
1154+ && isxdigit (Py_CHARMASK (s [1 ]))) {
11551155 unsigned int x = 0 ;
11561156 c = Py_CHARMASK (* s );
11571157 s ++ ;
@@ -1173,7 +1173,8 @@ parsestr(char *s)
11731173 * p ++ = x ;
11741174 break ;
11751175 }
1176- PyErr_SetString (PyExc_ValueError , "invalid \\x escape" );
1176+ PyErr_SetString (PyExc_ValueError ,
1177+ "invalid \\x escape" );
11771178 Py_DECREF (v );
11781179 return NULL ;
11791180 default :
@@ -2647,7 +2648,7 @@ com_import_stmt(struct compiling *c, node *n)
26472648 for (i = 3 ; i < NCH (n ); i += 2 ) {
26482649 PyTuple_SET_ITEM (tup , (i - 3 )/2 ,
26492650 PyString_FromString (STR (
2650- CHILD (CHILD (n , i ), 0 ))));
2651+ CHILD (CHILD (n , i ), 0 ))));
26512652 }
26522653 }
26532654 com_addoparg (c , LOAD_CONST , com_addconst (c , tup ));
@@ -3985,7 +3986,7 @@ get_ref_type(struct compiling *c, char *name)
39853986
39863987/* Helper function to issue symbol table warnings */
39873988
3988- static void
3989+ static int
39893990symtable_warn (struct symtable * st , char * msg )
39903991{
39913992 if (PyErr_WarnExplicit (PyExc_SyntaxWarning , msg , st -> st_filename ,
@@ -3996,7 +3997,9 @@ symtable_warn(struct symtable *st, char *msg)
39963997 st -> st_cur -> ste_lineno );
39973998 }
39983999 st -> st_errors ++ ;
4000+ return -1 ;
39994001 }
4002+ return 0 ;
40004003}
40014004
40024005/* Helper function for setting lineno and filename */
@@ -4119,6 +4122,98 @@ symtable_freevar_offsets(PyObject *freevars, int offset)
41194122 return 0 ;
41204123}
41214124
4125+ static int
4126+ symtable_check_unoptimized (struct compiling * c ,
4127+ PySymtableEntryObject * ste ,
4128+ struct symbol_info * si )
4129+ {
4130+ char buf [300 ];
4131+
4132+ if (!(si -> si_ncells || si -> si_nfrees || ste -> ste_child_free
4133+ || (ste -> ste_nested && si -> si_nimplicit )))
4134+ return 0 ;
4135+
4136+ #define ILLEGAL_IMPORT_STAR \
4137+ "import * is not allowed in function '%.100s' " \
4138+ "because it contains a nested function with free variables"
4139+
4140+ #define ILLEGAL_BARE_EXEC \
4141+ "unqualified exec is not allowed in function '%.100s' " \
4142+ "because it contains a nested function with free variables"
4143+
4144+ #define ILLEGAL_EXEC_AND_IMPORT_STAR \
4145+ "function '%.100s' uses import * and bare exec, which are illegal" \
4146+ "because it contains a nested function with free variables"
4147+
4148+ /* XXX perhaps the linenos for these opt-breaking statements
4149+ should be stored so the exception can point to them. */
4150+
4151+ if (ste -> ste_optimized == OPT_IMPORT_STAR )
4152+ sprintf (buf , ILLEGAL_IMPORT_STAR ,
4153+ PyString_AS_STRING (ste -> ste_name ));
4154+ else if (ste -> ste_optimized == (OPT_BARE_EXEC | OPT_EXEC ))
4155+ sprintf (buf , ILLEGAL_BARE_EXEC ,
4156+ PyString_AS_STRING (ste -> ste_name ));
4157+ else {
4158+ sprintf (buf , ILLEGAL_EXEC_AND_IMPORT_STAR ,
4159+ PyString_AS_STRING (ste -> ste_name ));
4160+ }
4161+
4162+ if (c -> c_symtable -> st_nested_scopes ) {
4163+ PyErr_SetString (PyExc_SyntaxError , buf );
4164+ PyErr_SyntaxLocation (c -> c_symtable -> st_filename ,
4165+ ste -> ste_lineno );
4166+ return -1 ;
4167+ } else {
4168+ /* XXX if the warning becomes an exception, we should
4169+ attached more info to it. */
4170+ if (PyErr_Warn (PyExc_SyntaxWarning , buf ) < 0 )
4171+ return -1 ;
4172+ }
4173+ return 0 ;
4174+ }
4175+
4176+ static int
4177+ symtable_check_shadow (struct symtable * st , PyObject * name , int flags )
4178+ {
4179+ char buf [500 ];
4180+ PyObject * children , * v ;
4181+ PySymtableEntryObject * child ;
4182+ int i ;
4183+
4184+ if (!(flags & DEF_BOUND ))
4185+ return 0 ;
4186+ /* The semantics of this code will change with nested scopes.
4187+ It is defined in the current scope and referenced in a
4188+ child scope. Under the old rules, the child will see a
4189+ global. Under the new rules, the child will see the
4190+ binding in the current scope.
4191+ */
4192+
4193+ /* Find name of child function that has free variable */
4194+ children = st -> st_cur -> ste_children ;
4195+ for (i = 0 ; i < PyList_GET_SIZE (children ); i ++ ) {
4196+ int cflags ;
4197+ child = (PySymtableEntryObject * )PyList_GET_ITEM (children , i );
4198+ v = PyDict_GetItem (child -> ste_symbols , name );
4199+ if (v == NULL )
4200+ continue ;
4201+ cflags = PyInt_AS_LONG (v );
4202+ if (!(cflags & DEF_BOUND ))
4203+ break ;
4204+ }
4205+
4206+ sprintf (buf , "local name '%.100s' in '%.100s' shadows "
4207+ "use of '%.100s' as global in nested scope '%.100s'" ,
4208+ PyString_AS_STRING (name ),
4209+ PyString_AS_STRING (st -> st_cur -> ste_name ),
4210+ PyString_AS_STRING (name ),
4211+ PyString_AS_STRING (child -> ste_name )
4212+ );
4213+
4214+ return symtable_warn (st , buf );
4215+ }
4216+
41224217static int
41234218symtable_update_flags (struct compiling * c , PySymtableEntryObject * ste ,
41244219 struct symbol_info * si )
@@ -4129,26 +4224,8 @@ symtable_update_flags(struct compiling *c, PySymtableEntryObject *ste,
41294224 c -> c_nlocals = si -> si_nlocals ;
41304225 if (ste -> ste_optimized == 0 )
41314226 c -> c_flags |= CO_OPTIMIZED ;
4132- else if (si -> si_ncells || si -> si_nfrees
4133- || (ste -> ste_nested && si -> si_nimplicit )
4134- || ste -> ste_child_free ) {
4135- if (c -> c_symtable -> st_nested_scopes ) {
4136- PyErr_Format (PyExc_SyntaxError ,
4137- ILLEGAL_DYNAMIC_SCOPE ,
4138- PyString_AS_STRING (ste -> ste_name ));
4139- PyErr_SyntaxLocation (c -> c_symtable -> st_filename ,
4140- ste -> ste_lineno );
4141- return -1 ;
4142- } else {
4143- char buf [200 ];
4144- sprintf (buf , ILLEGAL_DYNAMIC_SCOPE ,
4145- PyString_AS_STRING (ste -> ste_name ));
4146- if (PyErr_Warn (PyExc_SyntaxWarning ,
4147- buf ) < 0 ) {
4148- return -1 ;
4149- }
4150- }
4151- }
4227+ else if (ste -> ste_optimized != OPT_EXEC )
4228+ return symtable_check_unoptimized (c , ste , si );
41524229 }
41534230 return 0 ;
41544231}
@@ -4191,6 +4268,12 @@ symtable_load_symbols(struct compiling *c)
41914268 while (PyDict_Next (ste -> ste_symbols , & pos , & name , & v )) {
41924269 flags = PyInt_AS_LONG (v );
41934270
4271+ if (st -> st_nested_scopes == 0
4272+ && (flags & (DEF_FREE | DEF_FREE_CLASS ))) {
4273+ if (symtable_check_shadow (st , name , flags ) < 0 )
4274+ goto fail ;
4275+ }
4276+
41944277 if (flags & DEF_FREE_GLOBAL )
41954278 /* undo the original DEF_FREE */
41964279 flags &= ~(DEF_FREE | DEF_FREE_CLASS );
@@ -4340,6 +4423,16 @@ symtable_update_free_vars(struct symtable *st)
43404423 return -1 ;
43414424 }
43424425 }
4426+ /*
4427+ if (st->st_nested_scopes == 0
4428+ && list && PyList_GET_SIZE(list) > 0) {
4429+ fprintf(stderr, "function %s has children with "
4430+ "the following free vars:\n%s\n",
4431+ PyString_AS_STRING(ste->ste_name),
4432+ PyObject_REPR(list));
4433+ continue;
4434+ }
4435+ */
43434436 for (j = 0 ; list && j < PyList_GET_SIZE (list ); j ++ ) {
43444437 name = PyList_GET_ITEM (list , j );
43454438 if (ste -> ste_nested ) {
@@ -4432,7 +4525,7 @@ symtable_exit_scope(struct symtable *st)
44324525{
44334526 int end ;
44344527
4435- if (st -> st_pass == 1 && st -> st_nested_scopes )
4528+ if (st -> st_pass == 1 )
44364529 symtable_update_free_vars (st );
44374530 Py_DECREF (st -> st_cur );
44384531 end = PyList_GET_SIZE (st -> st_stack ) - 1 ;
0 commit comments