[pypy-commit] pypy pep526: Handle AnnAssign in symtable building (WIP).
alcarithemad
pypy.commits at gmail.com
Thu Mar 1 05:07:54 EST 2018
Author: Colin Valliant <alcarithemad at gmail.com>
Branch: pep526
Changeset: r93916:e3f0d3b1a562
Date: 2018-02-13 23:25 -0800
http://bitbucket.org/pypy/pypy/changeset/e3f0d3b1a562/
Log: Handle AnnAssign in symtable building (WIP).
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
@@ -12,6 +12,7 @@
SYM_PARAM = 2 << 1
SYM_NONLOCAL = 2 << 2
SYM_USED = 2 << 3
+SYM_ANNOTATED = 2 << 4
SYM_BOUND = (SYM_PARAM | SYM_ASSIGNED)
# codegen.py actually deals with these:
@@ -44,6 +45,7 @@
self.child_has_free = False
self.nested = False
self.doc_removable = False
+ self.contains_annotated = False
self._in_try_body_depth = 0
def lookup(self, name):
@@ -139,7 +141,7 @@
self.free_vars.append(name)
free[name] = None
self.has_free = True
- elif flags & SYM_BOUND:
+ elif flags & (SYM_BOUND | SYM_ANNOTATED):
self.symbols[name] = SCOPE_LOCAL
local[name] = None
try:
@@ -420,6 +422,18 @@
self.scope.note_return(ret)
ast.GenericASTVisitor.visit_Return(self, ret)
+ def visit_AnnAssign(self, assign):
+ # __annotations__ is not setup or used in functions.
+ if not isinstance(self.scope, FunctionScope):
+ self.scope.contains_annotated = True
+ target = assign.target
+ if isinstance(target, ast.Name):
+ scope = SYM_ANNOTATED
+ name = target.id
+ if assign.value:
+ scope |= SYM_USED
+ self.note_symbol(name, scope)
+
def visit_ClassDef(self, clsdef):
self.note_symbol(clsdef.name, SYM_ASSIGNED)
self.visit_sequence(clsdef.bases)
@@ -485,10 +499,13 @@
msg = "name '%s' is nonlocal and global" % (name,)
raise SyntaxError(msg, glob.lineno, glob.col_offset)
- if old_role & (SYM_USED | SYM_ASSIGNED):
+ if old_role & (SYM_USED | SYM_ASSIGNED | SYM_ANNOTATED):
if old_role & SYM_ASSIGNED:
msg = "name '%s' is assigned to before global declaration"\
% (name,)
+ elif old_role & SYM_ANNOTATED:
+ msg = "annotated name '%s' can't be global" \
+ % (name,)
else:
msg = "name '%s' is used prior to global declaration" % \
(name,)
@@ -498,6 +515,7 @@
def visit_Nonlocal(self, nonl):
for name in nonl.names:
old_role = self.scope.lookup_role(name)
+ print(name, old_role)
msg = ""
if old_role & SYM_GLOBAL:
msg = "name '%s' is nonlocal and global" % (name,)
@@ -505,6 +523,9 @@
msg = "name '%s' is parameter and nonlocal" % (name,)
if isinstance(self.scope, ModuleScope):
msg = "nonlocal declaration not allowed at module level"
+ if old_role & SYM_ANNOTATED:
+ msg = "annotated name '%s' can't be nonlocal" \
+ % (name,)
if msg is not "":
raise SyntaxError(msg, nonl.lineno, nonl.col_offset)
More information about the pypy-commit
mailing list