Add python3.4/3.3 issue 'can use starred expression only as assignment target'.

This commit is contained in:
Dave Halter
2017-08-06 01:38:05 +02:00
parent 97525958b6
commit f4b51d91ee
3 changed files with 49 additions and 17 deletions

View File

@@ -238,6 +238,16 @@ class ErrorFinder(Normalizer):
self._context = Context(parent_scope, self._add_syntax_error) self._context = Context(parent_scope, self._add_syntax_error)
self._indentation_count = 0 self._indentation_count = 0
def visit(self, node):
if node.type == 'error_node':
with self.visit_node(node):
# Don't need to investigate the inners of an error node. We
# might find errors in there that should be ignored, because
# the error node itself already shows that there's an issue.
return ''
return super(ErrorFinder, self).visit(node)
@contextmanager @contextmanager
def visit_node(self, node): def visit_node(self, node):
if node.type == 'error_node': if node.type == 'error_node':
@@ -345,6 +355,19 @@ class ErrorFinder(Normalizer):
if node.parent.children[1].type == 'comp_for': if node.parent.children[1].type == 'comp_for':
message = "iterable unpacking cannot be used in comprehension" message = "iterable unpacking cannot be used in comprehension"
self._add_syntax_error(message, node) self._add_syntax_error(message, node)
if self._version <= (3, 4):
from parso.python.tree import search_ancestor
n = search_ancestor(node, 'for_stmt', 'expr_stmt')
found_definition = False
if n is not None:
for name in n.get_defined_names():
if node.start_pos < name.start_pos < node.end_pos:
found_definition = True
break
if not found_definition:
message = "can use starred expression only as assignment target"
self._add_syntax_error(message, node)
elif node.type == 'comp_for': elif node.type == 'comp_for':
# Some of the nodes here are already used, so no else if # Some of the nodes here are already used, so no else if
expr_list = node.children[1 + int(node.children[0] == 'async')] expr_list = node.children[1 + int(node.children[0] == 'async')]

View File

@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
import sys import sys
from textwrap import dedent from textwrap import dedent
@@ -283,3 +284,11 @@ else:
'async def foo():\n yield x\n return 1', 'async def foo():\n yield x\n return 1',
'async def foo():\n yield x\n return 1', 'async def foo():\n yield x\n return 1',
] ]
if sys.version_info[:2] <= (3, 4):
# Python > 3.4 this is valid code.
FAILING_EXAMPLES += [
'a = *[1], 2',
'(*[1], 2)',
]

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
""" """
Testing if parso finds syntax errors and indentation errors. Testing if parso finds syntax errors and indentation errors.
""" """
@@ -21,6 +20,20 @@ def assert_comparison(code, error_code, positions):
assert [(pos, error_code) for pos in positions] == errors assert [(pos, error_code) for pos in positions] == errors
@pytest.mark.parametrize('code', FAILING_EXAMPLES)
def test_python_exception_matches(code):
wanted, line_nr = _get_actual_exception(code)
errors = _get_error_list(code)
actual = None
if errors:
error, = errors
actual = error.message
assert actual in wanted
# Somehow in Python3.3 the SyntaxError().lineno is sometimes None
assert line_nr is None or line_nr == error.start_pos[0]
@pytest.mark.parametrize( @pytest.mark.parametrize(
('code', 'positions'), [ ('code', 'positions'), [
('1 +', [(1, 3)]), ('1 +', [(1, 3)]),
@@ -56,20 +69,6 @@ def test_indentation_errors(code, positions):
assert_comparison(code, 903, positions) assert_comparison(code, 903, positions)
@pytest.mark.parametrize('code', FAILING_EXAMPLES)
def test_python_exception_matches(code):
wanted, line_nr = _get_actual_exception(code)
errors = _get_error_list(code)
actual = None
if errors:
error, = errors
actual = error.message
assert actual in wanted
# Somehow in Python3.3 the SyntaxError().lineno is sometimes None
assert line_nr is None or line_nr == error.start_pos[0]
def _get_actual_exception(code): def _get_actual_exception(code):
with warnings.catch_warnings(): with warnings.catch_warnings():
# We don't care about warnings where locals/globals misbehave here. # We don't care about warnings where locals/globals misbehave here.
@@ -105,8 +104,9 @@ def _get_actual_exception(code):
# Python 2.6 does has a slightly different error. # Python 2.6 does has a slightly different error.
wanted = 'SyntaxError: cannot assign to __debug__' wanted = 'SyntaxError: cannot assign to __debug__'
elif wanted == 'SyntaxError: can use starred expression only as assignment target': elif wanted == 'SyntaxError: can use starred expression only as assignment target':
# Python 3.4/3.4 have a bit of a different warning than 3.5/3.6 # Python 3.4/3.4 have a bit of a different warning than 3.5/3.6 in
wanted = "SyntaxError: can't use starred expression here" # certain places. But in others this error makes sense.
return [wanted, "SyntaxError: can't use starred expression here"], line_nr
return [wanted], line_nr return [wanted], line_nr