mirror of
https://github.com/davidhalter/parso.git
synced 2025-12-08 13:45:01 +08:00
Adjust invalid aug assign target for 3.9+
This commit is contained in:
committed by
Dave Halter
parent
d6b1d19d87
commit
6f29c551fd
@@ -18,6 +18,79 @@ ALLOWED_FUTURES = (
|
|||||||
)
|
)
|
||||||
_COMP_FOR_TYPES = ('comp_for', 'sync_comp_for')
|
_COMP_FOR_TYPES = ('comp_for', 'sync_comp_for')
|
||||||
|
|
||||||
|
def _get_rhs_name(node, version):
|
||||||
|
type_ = node.type
|
||||||
|
if type_ == "lambdef":
|
||||||
|
return "lambda"
|
||||||
|
elif type_ == "atom":
|
||||||
|
comprehension = _get_comprehension_type(node)
|
||||||
|
first, second = node.children[:2]
|
||||||
|
if comprehension is not None:
|
||||||
|
return comprehension
|
||||||
|
elif second.type == "dictorsetmaker":
|
||||||
|
if version < (3, 8):
|
||||||
|
return "literal"
|
||||||
|
else:
|
||||||
|
if second.children[1] == ":" or second.children[0] == "**":
|
||||||
|
return "dict display"
|
||||||
|
else:
|
||||||
|
return "set display"
|
||||||
|
elif (
|
||||||
|
first == "("
|
||||||
|
and (second == ")"
|
||||||
|
or (len(node.children) == 3 and node.children[1].type == "testlist_comp"))
|
||||||
|
):
|
||||||
|
return "tuple"
|
||||||
|
elif first == "(":
|
||||||
|
return _get_rhs_name(_remove_parens(node), version=version)
|
||||||
|
elif first == "[":
|
||||||
|
return "list"
|
||||||
|
elif first == "{" and second == "}":
|
||||||
|
return "dict display"
|
||||||
|
elif first == "{" and len(node.children) > 2:
|
||||||
|
return "set display"
|
||||||
|
elif type_ == "keyword":
|
||||||
|
if "yield" in node.value:
|
||||||
|
return "yield expression"
|
||||||
|
if version < (3, 8):
|
||||||
|
return "keyword"
|
||||||
|
else:
|
||||||
|
return str(node.value)
|
||||||
|
elif type_ == "operator" and node.value == "...":
|
||||||
|
return "Ellipsis"
|
||||||
|
elif type_ == "comparison":
|
||||||
|
return "comparison"
|
||||||
|
elif type_ in ("string", "number", "strings"):
|
||||||
|
return "literal"
|
||||||
|
elif type_ == "yield_expr":
|
||||||
|
return "yield expression"
|
||||||
|
elif type_ == "test":
|
||||||
|
return "conditional expression"
|
||||||
|
elif type_ in ("atom_expr", "power"):
|
||||||
|
if node.children[0] == "await":
|
||||||
|
return "await expression"
|
||||||
|
elif node.children[-1].type == "trailer":
|
||||||
|
trailer = node.children[-1]
|
||||||
|
if trailer.children[0] == "(":
|
||||||
|
return "function call"
|
||||||
|
elif trailer.children[0] == "[":
|
||||||
|
return "subscript"
|
||||||
|
elif trailer.children[0] == ".":
|
||||||
|
return "attribute"
|
||||||
|
elif (
|
||||||
|
("expr" in type_
|
||||||
|
and "star_expr" not in type_) # is a substring
|
||||||
|
or "_test" in type_
|
||||||
|
or type_ in ("term", "factor")
|
||||||
|
):
|
||||||
|
return "operator"
|
||||||
|
elif type_ == "star_expr":
|
||||||
|
return "starred"
|
||||||
|
elif type_ == "testlist_star_expr":
|
||||||
|
return "tuple"
|
||||||
|
elif type_ == "fstring":
|
||||||
|
return "f-string expression"
|
||||||
|
return type_ # shouldn't reach here
|
||||||
|
|
||||||
def _iter_stmts(scope):
|
def _iter_stmts(scope):
|
||||||
"""
|
"""
|
||||||
@@ -926,6 +999,16 @@ class _CheckAssignmentRule(SyntaxRule):
|
|||||||
error = 'dict display'
|
error = 'dict display'
|
||||||
else:
|
else:
|
||||||
error = 'set display'
|
error = 'set display'
|
||||||
|
elif first == "{" and second == "}":
|
||||||
|
if self._normalizer.version < (3, 8):
|
||||||
|
error = 'literal'
|
||||||
|
else:
|
||||||
|
error = "dict display"
|
||||||
|
elif first == "{" and len(node.children) > 2:
|
||||||
|
if self._normalizer.version < (3, 8):
|
||||||
|
error = 'literal'
|
||||||
|
else:
|
||||||
|
error = "set display"
|
||||||
elif first in ('(', '['):
|
elif first in ('(', '['):
|
||||||
if second.type == 'yield_expr':
|
if second.type == 'yield_expr':
|
||||||
error = 'yield expression'
|
error = 'yield expression'
|
||||||
@@ -945,7 +1028,9 @@ class _CheckAssignmentRule(SyntaxRule):
|
|||||||
else: # Everything handled, must be useless brackets.
|
else: # Everything handled, must be useless brackets.
|
||||||
self._check_assignment(second, is_deletion, is_namedexpr)
|
self._check_assignment(second, is_deletion, is_namedexpr)
|
||||||
elif type_ == 'keyword':
|
elif type_ == 'keyword':
|
||||||
if self._normalizer.version < (3, 8):
|
if node.value == "yield":
|
||||||
|
error = "yield expression"
|
||||||
|
elif self._normalizer.version < (3, 8):
|
||||||
error = 'keyword'
|
error = 'keyword'
|
||||||
else:
|
else:
|
||||||
error = str(node.value)
|
error = str(node.value)
|
||||||
@@ -977,6 +1062,11 @@ class _CheckAssignmentRule(SyntaxRule):
|
|||||||
error = 'subscript'
|
error = 'subscript'
|
||||||
elif is_namedexpr and trailer.children[0] == '.':
|
elif is_namedexpr and trailer.children[0] == '.':
|
||||||
error = 'attribute'
|
error = 'attribute'
|
||||||
|
elif type_ == "fstring":
|
||||||
|
if self._normalizer.version < (3, 8):
|
||||||
|
error = 'literal'
|
||||||
|
else:
|
||||||
|
error = "f-string expression"
|
||||||
elif type_ in ('testlist_star_expr', 'exprlist', 'testlist'):
|
elif type_ in ('testlist_star_expr', 'exprlist', 'testlist'):
|
||||||
for child in node.children[::2]:
|
for child in node.children[::2]:
|
||||||
self._check_assignment(child, is_deletion, is_namedexpr)
|
self._check_assignment(child, is_deletion, is_namedexpr)
|
||||||
@@ -1012,15 +1102,35 @@ class _CompForRule(_CheckAssignmentRule):
|
|||||||
@ErrorFinder.register_rule(type='expr_stmt')
|
@ErrorFinder.register_rule(type='expr_stmt')
|
||||||
class _ExprStmtRule(_CheckAssignmentRule):
|
class _ExprStmtRule(_CheckAssignmentRule):
|
||||||
message = "illegal expression for augmented assignment"
|
message = "illegal expression for augmented assignment"
|
||||||
|
extended_message = "'{target}' is an " + message
|
||||||
def is_issue(self, node):
|
def is_issue(self, node):
|
||||||
for before_equal in node.children[:-2:2]:
|
|
||||||
self._check_assignment(before_equal)
|
|
||||||
|
|
||||||
augassign = node.children[1]
|
augassign = node.children[1]
|
||||||
if augassign != '=' and augassign.type != 'annassign': # Is augassign.
|
is_aug_assign = augassign != '=' and augassign.type != 'annassign'
|
||||||
return node.children[0].type in ('testlist_star_expr', 'atom', 'testlist')
|
|
||||||
|
|
||||||
|
if self._normalizer.version <= (3, 8) or not is_aug_assign:
|
||||||
|
for before_equal in node.children[:-2:2]:
|
||||||
|
self._check_assignment(before_equal)
|
||||||
|
|
||||||
|
if is_aug_assign:
|
||||||
|
target = _remove_parens(node.children[0])
|
||||||
|
# a, a[b], a.b
|
||||||
|
|
||||||
|
if target.type == "name" or (
|
||||||
|
target.type in ("atom_expr", "power")
|
||||||
|
and target.children[1].type == "trailer"
|
||||||
|
and target.children[-1].children[0] != "("
|
||||||
|
):
|
||||||
|
return False
|
||||||
|
|
||||||
|
if self._normalizer.version <= (3, 8):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.add_issue(
|
||||||
|
node,
|
||||||
|
message=self.extended_message.format(
|
||||||
|
target=_get_rhs_name(node.children[0], self._normalizer.version)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
@ErrorFinder.register_rule(type='with_item')
|
@ErrorFinder.register_rule(type='with_item')
|
||||||
class _WithItemRule(_CheckAssignmentRule):
|
class _WithItemRule(_CheckAssignmentRule):
|
||||||
|
|||||||
@@ -52,9 +52,37 @@ FAILING_EXAMPLES = [
|
|||||||
'f(x=2, y)',
|
'f(x=2, y)',
|
||||||
'f(**x, *y)',
|
'f(**x, *y)',
|
||||||
'f(**x, y=3, z)',
|
'f(**x, y=3, z)',
|
||||||
|
# augassign
|
||||||
'a, b += 3',
|
'a, b += 3',
|
||||||
'(a, b) += 3',
|
'(a, b) += 3',
|
||||||
'[a, b] += 3',
|
'[a, b] += 3',
|
||||||
|
'f() += 1',
|
||||||
|
'lambda x:None+=1',
|
||||||
|
'{} += 1',
|
||||||
|
'{a:b} += 1',
|
||||||
|
'{1} += 1',
|
||||||
|
'{*x} += 1',
|
||||||
|
'(x,) += 1',
|
||||||
|
'(x, y if a else q) += 1',
|
||||||
|
'[] += 1',
|
||||||
|
'[1,2] += 1',
|
||||||
|
'[] += 1',
|
||||||
|
'None += 1',
|
||||||
|
'... += 1',
|
||||||
|
'a > 1 += 1',
|
||||||
|
'"test" += 1',
|
||||||
|
'1 += 1',
|
||||||
|
'1.0 += 1',
|
||||||
|
'(yield) += 1',
|
||||||
|
'(yield from x) += 1',
|
||||||
|
'(x if x else y) += 1',
|
||||||
|
'a() += 1',
|
||||||
|
'a + b += 1',
|
||||||
|
'+a += 1',
|
||||||
|
'a and b += 1',
|
||||||
|
'*a += 1',
|
||||||
|
'a, b += 1',
|
||||||
|
'f"xxx" += 1',
|
||||||
# All assignment tests
|
# All assignment tests
|
||||||
'lambda a: 1 = 1',
|
'lambda a: 1 = 1',
|
||||||
'[x for x in y] = 1',
|
'[x for x in y] = 1',
|
||||||
|
|||||||
Reference in New Issue
Block a user