Author: Robert Zaremba <robert.zare...@scale-it.pl> Branch: py3.5-fix-globals Changeset: r90410:baf2561c870c Date: 2017-02-27 13:36 +0100 http://bitbucket.org/pypy/pypy/changeset/baf2561c870c/
Log: (stevie, robert-zaremba) Test and fix global variable reporting error. diff --git a/pypy/interpreter/astcompiler/symtable.py b/pypy/interpreter/astcompiler/symtable.py --- a/pypy/interpreter/astcompiler/symtable.py +++ b/pypy/interpreter/astcompiler/symtable.py @@ -8,7 +8,7 @@ # These are for internal use only: SYM_BLANK = 0 SYM_GLOBAL = 1 -SYM_ASSIGNED = 2 # Or deleted actually. +SYM_ASSIGNED = 2 # Or deleted actually. SYM_PARAM = 2 << 1 SYM_NONLOCAL = 2 << 2 SYM_USED = 2 << 3 @@ -123,9 +123,6 @@ def _finalize_name(self, name, flags, local, bound, free, globs): """Decide on the scope of a name.""" if flags & SYM_GLOBAL: - if flags & SYM_PARAM: - err = "name '%s' is parameter and global" % (name,) - raise SyntaxError(err, self.lineno, self.col_offset) if flags & SYM_NONLOCAL: err = "name '%s' is nonlocal and global" % (name,) raise SyntaxError(err, self.lineno, self.col_offset) @@ -293,7 +290,8 @@ def _pass_on_bindings(self, local, bound, globs, new_bound, new_globs): new_bound.update(local) - Scope._pass_on_bindings(self, local, bound, globs, new_bound, new_globs) + Scope._pass_on_bindings(self, local, bound, globs, new_bound, + new_globs) def _finalize_cells(self, free): for name, role in self.symbols.iteritems(): @@ -496,14 +494,19 @@ "implemented in PyPy") raise SyntaxError(msg, glob.lineno, glob.col_offset, filename=self.compile_info.filename) + if old_role & SYM_PARAM: + msg = "name '%s' is parameter and global" % (name,) + raise SyntaxError(msg, glob.lineno, glob.col_offset) + if old_role & (SYM_USED | SYM_ASSIGNED): if old_role & SYM_ASSIGNED: - msg = "name '%s' is assigned to before global declaration" \ + msg = "name '%s' is assigned to before global declaration"\ % (name,) else: msg = "name '%s' is used prior to global declaration" % \ (name,) - misc.syntax_warning(self.space, msg, self.compile_info.filename, + misc.syntax_warning(self.space, msg, + self.compile_info.filename, glob.lineno, glob.col_offset) self.note_symbol(name, SYM_GLOBAL) @@ -519,7 +522,8 @@ else: msg = "name '%s' is used prior to nonlocal declaration" % \ (name,) - misc.syntax_warning(self.space, msg, self.compile_info.filename, + misc.syntax_warning(self.space, msg, + self.compile_info.filename, nonl.lineno, nonl.col_offset) self.note_symbol(name, SYM_NONLOCAL) @@ -589,7 +593,7 @@ def visit_arguments(self, arguments): scope = self.scope - assert isinstance(scope, FunctionScope) # Annotator hint. + assert isinstance(scope, FunctionScope) # Annotator hint. if arguments.args: self._handle_params(arguments.args, True) if arguments.kwonlyargs: diff --git a/pypy/interpreter/astcompiler/test/test_symtable.py b/pypy/interpreter/astcompiler/test/test_symtable.py --- a/pypy/interpreter/astcompiler/test/test_symtable.py +++ b/pypy/interpreter/astcompiler/test/test_symtable.py @@ -283,7 +283,6 @@ def test_global(self): scp = self.func_scope("def f():\n global x\n x = 4") assert scp.lookup("x") == symtable.SCOPE_GLOBAL_EXPLICIT - input = "def f(x):\n global x" scp = self.func_scope("""def f(): y = 3 def x(): @@ -295,9 +294,30 @@ xscp, zscp = scp.children assert xscp.lookup("y") == symtable.SCOPE_GLOBAL_EXPLICIT assert zscp.lookup("y") == symtable.SCOPE_FREE - exc = py.test.raises(SyntaxError, self.func_scope, input).value + + code = "def f(x):\n global x" + exc = py.test.raises(SyntaxError, self.func_scope, code).value + assert exc.lineno == 2 assert exc.msg == "name 'x' is parameter and global" + def test_global_nested(self): + code = """ +def f(x): + def g(x): + global x""" + exc = py.test.raises(SyntaxError, self.func_scope, code).value + assert exc.lineno == 4 + assert exc.msg == "name 'x' is parameter and global" + + scp = self.func_scope(""" +def f(x): + def g(): + global x""") + g = scp.children[0] + assert g.name == 'g' + x = g.lookup_role('x') + assert x == symtable.SYM_GLOBAL + def test_nonlocal(self): src = str(py.code.Source(""" def f(): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit