mirror of
https://github.com/davidhalter/parso.git
synced 2025-12-07 21:34:32 +08:00
Some issues regarding annotations.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user