Add two more issues one about strings and one about an import.

This commit is contained in:
Dave Halter
2017-07-24 00:34:14 +02:00
parent c2ab9a9e25
commit d1eb1d61ec
4 changed files with 32 additions and 0 deletions

View File

@@ -8,6 +8,10 @@ _STAR_EXPR_PARENTS = ('testlist_star_expr', 'testlist_comp', 'exprlist')
_MAX_BLOCK_SIZE = 20
def _is_bytes_literal(string):
return 'b' in string.string_prefix.lower()
def _iter_stmts(scope):
"""
Iterates over all statements and splits up simple_stmt.
@@ -123,6 +127,11 @@ class ErrorFinder(Normalizer):
and _is_future_import(node) and not _is_future_import_first(node):
message = "from __future__ imports must occur at the beginning of the file"
self._add_syntax_error(message, node)
elif node.type == 'import_as_names':
if node.children[-1] == ',':
# from foo import a,
message = "trailing comma not allowed without surrounding parentheses"
self._add_syntax_error(message, node)
elif node.type in _STAR_EXPR_PARENTS:
if node.parent.type == 'del_stmt':
self._add_syntax_error("can't use starred expression here", node.parent)
@@ -153,6 +162,17 @@ class ErrorFinder(Normalizer):
# foo(x for x in [], b)
message = "Generator expression must be parenthesized if not sole argument"
self._add_syntax_error(message, node)
elif node.type == 'atom':
first = node.children[0]
# e.g. 's' b''
message = "cannot mix bytes and nonbytes literals"
# TODO this check is only relevant for Python 3+
if first.type == 'string':
first_is_bytes = _is_bytes_literal(first)
for string in node.children[1:]:
if first_is_bytes != _is_bytes_literal(string):
self._add_syntax_error(message, node)
break
yield

View File

@@ -25,6 +25,8 @@ Any subclasses of :class:`Scope`, including :class:`Module` has an attribute
[<ImportName: import os@1,0>]
"""
import re
from parso._compatibility import utf8_repr, unicode
from parso.tree import Node, BaseNode, Leaf, ErrorNode, ErrorLeaf, \
search_ancestor
@@ -208,6 +210,10 @@ class String(Literal):
type = 'string'
__slots__ = ()
@property
def string_prefix(self):
return re.match('\w*(?=[\'"])', self.value).group(0)
class _StringComparisonMixin(object):
def __eq__(self, other):

View File

@@ -5,6 +5,10 @@ gather some of the potentially dangerous ones.
from __future__ import division
'' ''
''r''u''
b'' BR''
for x in [1]:
try:
continue # Only the other continue and pass is an error.

View File

@@ -72,6 +72,7 @@ def test_indentation_errors(code, positions):
'yield',
'try: pass\nexcept: pass\nexcept X: pass',
'f(x for x in bar, 1)',
'from foo import a,',
# IndentationError
' foo',
@@ -111,6 +112,7 @@ def test_python_exception_matches(code):
('async def foo():\n def nofoo():[x async for x in []]', '3.6'),
('[*[] for a in [1]]', '3.5'),
('{**{} for a in [1]}', '3.5'),
('"s" b""', '3.5'),
]
)
def test_python_exception_matches_version(code, version):