mirror of
https://github.com/davidhalter/parso.git
synced 2025-12-07 21:34:32 +08:00
Add two more issues one about strings and one about an import.
This commit is contained in:
@@ -8,6 +8,10 @@ _STAR_EXPR_PARENTS = ('testlist_star_expr', 'testlist_comp', 'exprlist')
|
|||||||
_MAX_BLOCK_SIZE = 20
|
_MAX_BLOCK_SIZE = 20
|
||||||
|
|
||||||
|
|
||||||
|
def _is_bytes_literal(string):
|
||||||
|
return 'b' in string.string_prefix.lower()
|
||||||
|
|
||||||
|
|
||||||
def _iter_stmts(scope):
|
def _iter_stmts(scope):
|
||||||
"""
|
"""
|
||||||
Iterates over all statements and splits up simple_stmt.
|
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):
|
and _is_future_import(node) and not _is_future_import_first(node):
|
||||||
message = "from __future__ imports must occur at the beginning of the file"
|
message = "from __future__ imports must occur at the beginning of the file"
|
||||||
self._add_syntax_error(message, node)
|
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:
|
elif node.type in _STAR_EXPR_PARENTS:
|
||||||
if node.parent.type == 'del_stmt':
|
if node.parent.type == 'del_stmt':
|
||||||
self._add_syntax_error("can't use starred expression here", node.parent)
|
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)
|
# foo(x for x in [], b)
|
||||||
message = "Generator expression must be parenthesized if not sole argument"
|
message = "Generator expression must be parenthesized if not sole argument"
|
||||||
self._add_syntax_error(message, node)
|
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
|
yield
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ Any subclasses of :class:`Scope`, including :class:`Module` has an attribute
|
|||||||
[<ImportName: import os@1,0>]
|
[<ImportName: import os@1,0>]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
from parso._compatibility import utf8_repr, unicode
|
from parso._compatibility import utf8_repr, unicode
|
||||||
from parso.tree import Node, BaseNode, Leaf, ErrorNode, ErrorLeaf, \
|
from parso.tree import Node, BaseNode, Leaf, ErrorNode, ErrorLeaf, \
|
||||||
search_ancestor
|
search_ancestor
|
||||||
@@ -208,6 +210,10 @@ class String(Literal):
|
|||||||
type = 'string'
|
type = 'string'
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def string_prefix(self):
|
||||||
|
return re.match('\w*(?=[\'"])', self.value).group(0)
|
||||||
|
|
||||||
|
|
||||||
class _StringComparisonMixin(object):
|
class _StringComparisonMixin(object):
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ gather some of the potentially dangerous ones.
|
|||||||
|
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
|
|
||||||
|
'' ''
|
||||||
|
''r''u''
|
||||||
|
b'' BR''
|
||||||
|
|
||||||
for x in [1]:
|
for x in [1]:
|
||||||
try:
|
try:
|
||||||
continue # Only the other continue and pass is an error.
|
continue # Only the other continue and pass is an error.
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ def test_indentation_errors(code, positions):
|
|||||||
'yield',
|
'yield',
|
||||||
'try: pass\nexcept: pass\nexcept X: pass',
|
'try: pass\nexcept: pass\nexcept X: pass',
|
||||||
'f(x for x in bar, 1)',
|
'f(x for x in bar, 1)',
|
||||||
|
'from foo import a,',
|
||||||
|
|
||||||
# IndentationError
|
# IndentationError
|
||||||
' foo',
|
' foo',
|
||||||
@@ -111,6 +112,7 @@ def test_python_exception_matches(code):
|
|||||||
('async def foo():\n def nofoo():[x async for x in []]', '3.6'),
|
('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'),
|
||||||
('{**{} for a in [1]}', '3.5'),
|
('{**{} for a in [1]}', '3.5'),
|
||||||
|
('"s" b""', '3.5'),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
def test_python_exception_matches_version(code, version):
|
def test_python_exception_matches_version(code, version):
|
||||||
|
|||||||
Reference in New Issue
Block a user