Some issues regarding annotations.

This commit is contained in:
Dave Halter
2017-07-25 00:38:27 +02:00
parent 319a0cc56f
commit 6085c91df1
3 changed files with 61 additions and 0 deletions

View File

@@ -33,6 +33,21 @@ def _is_future_import(import_from):
return [n.value for n in from_names] == ['__future__']
def _remove_parens(atom):
"""
Returns the inner part of an expression like `(foo)`. Also removes nested
parens.
"""
try:
children = atom.children
except AttributeError:
pass
else:
if len(children) == 3 and children[0] == '(':
return _remove_parens(atom.children[1])
return atom
def _iter_params(parent_node):
return (n for n in parent_node.children if n.type == 'param')
@@ -187,6 +202,35 @@ class ErrorFinder(Normalizer):
self._add_syntax_error(message, node)
else:
default_only = True
elif node.type == 'annassign':
# x, y: str
type_ = None
message = "only single target (not %s) can be annotated"
lhs = node.parent.children[0]
lhs = _remove_parens(lhs)
try:
children = lhs.children
except AttributeError:
pass
else:
if ',' in children or lhs.type == 'atom' and children[0] == '(':
type_ = 'tuple'
elif lhs.type == 'atom' and children[0] == '[':
type_ = 'list'
trailer = children[-1]
if type_ is None:
if not (lhs.type == 'name'
# subscript/attributes are allowed
or lhs.type in ('atom_expr', 'power')
and trailer.type == 'trailer'
and trailer.children[0] != '('):
# True: int
# {}: float
message = "illegal target for annotation"
self._add_syntax_error(message, lhs.parent)
else:
self._add_syntax_error(message % type_, lhs.parent)
yield

View File

@@ -9,6 +9,12 @@ from __future__ import division
''r''u''
b'' BR''
foo: int = 4
(foo): int = 3
((foo)): int = 3
foo.bar: int
foo[3]: int
for x in [1]:
try:
continue # Only the other continue and pass is an error.

View File

@@ -79,6 +79,17 @@ def test_indentation_errors(code, positions):
#'(True,) = x',
#'([False], a) = x',
#'__debug__ = 1'
# Mostly 3.6 relevant
'[]: int',
'[a, b]: int',
'(): int',
'(()): int',
'((())): int',
'{}: int',
'True: int',
'(a, b): int',
'*star,: int',
'a, b: int = 3',
# IndentationError
' foo',