mirror of
https://github.com/davidhalter/parso.git
synced 2026-02-22 17:48:47 +08:00
Raise violation on starred expressions where the child is a boolean/none
This commit is contained in:
@@ -5,7 +5,7 @@ import re
|
|||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
from parso.normalizer import Normalizer, NormalizerConfig, Issue, Rule
|
from parso.normalizer import Normalizer, NormalizerConfig, Issue, Rule
|
||||||
from parso.python.tree import search_ancestor
|
from parso.python.tree import Keyword, search_ancestor
|
||||||
|
|
||||||
_BLOCK_STMTS = ('if_stmt', 'while_stmt', 'for_stmt', 'try_stmt', 'with_stmt')
|
_BLOCK_STMTS = ('if_stmt', 'while_stmt', 'for_stmt', 'try_stmt', 'with_stmt')
|
||||||
_STAR_EXPR_PARENTS = ('testlist_star_expr', 'testlist_comp', 'exprlist')
|
_STAR_EXPR_PARENTS = ('testlist_star_expr', 'testlist_comp', 'exprlist')
|
||||||
@@ -643,6 +643,9 @@ class _StarExprRule(SyntaxRule):
|
|||||||
message = "starred assignment target must be in a list or tuple"
|
message = "starred assignment target must be in a list or tuple"
|
||||||
message_iterable_unpacking = "iterable unpacking cannot be used in comprehension"
|
message_iterable_unpacking = "iterable unpacking cannot be used in comprehension"
|
||||||
message_assignment = "can use starred expression only as assignment target"
|
message_assignment = "can use starred expression only as assignment target"
|
||||||
|
message_cannot_assign = "cannot assign to {target}"
|
||||||
|
|
||||||
|
_FORBIDDEN = frozenset(("True", "False", "None"))
|
||||||
|
|
||||||
def is_issue(self, node):
|
def is_issue(self, node):
|
||||||
if node.parent.type not in _STAR_EXPR_PARENTS:
|
if node.parent.type not in _STAR_EXPR_PARENTS:
|
||||||
@@ -651,19 +654,29 @@ class _StarExprRule(SyntaxRule):
|
|||||||
# [*[] for a in [1]]
|
# [*[] for a in [1]]
|
||||||
if node.parent.children[1].type in _COMP_FOR_TYPES:
|
if node.parent.children[1].type in _COMP_FOR_TYPES:
|
||||||
self.add_issue(node, message=self.message_iterable_unpacking)
|
self.add_issue(node, message=self.message_iterable_unpacking)
|
||||||
if self._normalizer.version <= (3, 4):
|
|
||||||
n = search_ancestor(node, 'for_stmt', 'expr_stmt')
|
|
||||||
found_definition = False
|
|
||||||
if n is not None:
|
|
||||||
if n.type == 'expr_stmt':
|
|
||||||
exprs = _get_expr_stmt_definition_exprs(n)
|
|
||||||
else:
|
|
||||||
exprs = _get_for_stmt_definition_exprs(n)
|
|
||||||
if node in exprs:
|
|
||||||
found_definition = True
|
|
||||||
|
|
||||||
if not found_definition:
|
assignment_ancestor = search_ancestor(node, 'for_stmt', 'expr_stmt')
|
||||||
self.add_issue(node, message=self.message_assignment)
|
found_definition = False
|
||||||
|
if assignment_ancestor is not None:
|
||||||
|
if assignment_ancestor.type == 'expr_stmt':
|
||||||
|
exprs = _get_expr_stmt_definition_exprs(assignment_ancestor)
|
||||||
|
else:
|
||||||
|
exprs = _get_for_stmt_definition_exprs(assignment_ancestor)
|
||||||
|
if node in exprs:
|
||||||
|
found_definition = True
|
||||||
|
|
||||||
|
if found_definition:
|
||||||
|
for child in node.children:
|
||||||
|
if isinstance(child, Keyword) and child.value in self._FORBIDDEN:
|
||||||
|
self.add_issue(
|
||||||
|
node,
|
||||||
|
message=self.message_cannot_assign.format(
|
||||||
|
target=child.value
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
if self._normalizer.version <= (3, 4) and not found_definition:
|
||||||
|
self.add_issue(node, message=self.message_assignment)
|
||||||
|
|
||||||
|
|
||||||
@ErrorFinder.register_rule(types=_STAR_EXPR_PARENTS)
|
@ErrorFinder.register_rule(types=_STAR_EXPR_PARENTS)
|
||||||
|
|||||||
@@ -12,13 +12,6 @@ from .__future__ import absolute_import
|
|||||||
''r''u''
|
''r''u''
|
||||||
b'' BR''
|
b'' BR''
|
||||||
|
|
||||||
for x in [1]:
|
|
||||||
try:
|
|
||||||
continue # Only the other continue and pass is an error.
|
|
||||||
finally:
|
|
||||||
#: E901
|
|
||||||
continue
|
|
||||||
|
|
||||||
|
|
||||||
for x in [1]:
|
for x in [1]:
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -339,3 +339,26 @@ def test_continue_in_finally():
|
|||||||
assert _get_error_list(code, version="3.7")
|
assert _get_error_list(code, version="3.7")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'template', [
|
||||||
|
"a, b, {target}, c = d",
|
||||||
|
"a, b, *{target}, c = d",
|
||||||
|
"(a, *{target}), c = d",
|
||||||
|
"for x, {target} in y: pass",
|
||||||
|
"for x, q, {target} in y: pass",
|
||||||
|
"for x, q, *{target} in y: pass",
|
||||||
|
"for (x, *{target}), q in y: pass",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'target', [
|
||||||
|
"True",
|
||||||
|
"False",
|
||||||
|
"None",
|
||||||
|
"__debug__"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def test_forbidden_name(template, target):
|
||||||
|
assert _get_error_list(template.format(target=target), version="3")[0].message
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user