mirror of
https://github.com/davidhalter/parso.git
synced 2025-12-09 22:25:53 +08:00
Add 'too many levels of indentation' issue.
This commit is contained in:
@@ -9,6 +9,7 @@ _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')
|
||||||
# This is the maximal block size given by python.
|
# This is the maximal block size given by python.
|
||||||
_MAX_BLOCK_SIZE = 20
|
_MAX_BLOCK_SIZE = 20
|
||||||
|
_MAX_INDENT_COUNT = 100
|
||||||
ALLOWED_FUTURES = (
|
ALLOWED_FUTURES = (
|
||||||
'all_feature_names', 'nested_scopes', 'generators', 'division',
|
'all_feature_names', 'nested_scopes', 'generators', 'division',
|
||||||
'absolute_import', 'with_statement', 'print_function', 'unicode_literals',
|
'absolute_import', 'with_statement', 'print_function', 'unicode_literals',
|
||||||
@@ -236,6 +237,7 @@ class ErrorFinder(Normalizer):
|
|||||||
else:
|
else:
|
||||||
parent_scope = search_ancestor(node, allowed)
|
parent_scope = search_ancestor(node, allowed)
|
||||||
self._context = Context(parent_scope, self._add_syntax_error)
|
self._context = Context(parent_scope, self._add_syntax_error)
|
||||||
|
self._indentation_count = 0
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def visit_node(self, node):
|
def visit_node(self, node):
|
||||||
@@ -497,6 +499,10 @@ class ErrorFinder(Normalizer):
|
|||||||
elif node.type == 'expr_list':
|
elif node.type == 'expr_list':
|
||||||
for expr in node.children[::2]:
|
for expr in node.children[::2]:
|
||||||
self._check_assignment(expr)
|
self._check_assignment(expr)
|
||||||
|
elif node.type == 'suite':
|
||||||
|
self._indentation_count += 1
|
||||||
|
if self._indentation_count == _MAX_INDENT_COUNT:
|
||||||
|
self._add_indentation_error("too many levels of indentation", node.children[1])
|
||||||
|
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,19 @@ import pytest
|
|||||||
import parso
|
import parso
|
||||||
|
|
||||||
|
|
||||||
|
def indent(code):
|
||||||
|
lines = code.splitlines(True)
|
||||||
|
return ''.join([' ' + line for line in lines])
|
||||||
|
|
||||||
|
|
||||||
|
def _build_nested(code, depth):
|
||||||
|
if depth == 0:
|
||||||
|
return code
|
||||||
|
|
||||||
|
new_code = 'def f():\n' + indent(code)
|
||||||
|
return _build_nested(new_code, depth - 1)
|
||||||
|
|
||||||
|
|
||||||
FAILING_EXAMPLES = [
|
FAILING_EXAMPLES = [
|
||||||
'1 +',
|
'1 +',
|
||||||
'?',
|
'?',
|
||||||
@@ -112,6 +125,8 @@ FAILING_EXAMPLES = [
|
|||||||
r"'''",
|
r"'''",
|
||||||
r"'",
|
r"'",
|
||||||
r"\blub",
|
r"\blub",
|
||||||
|
# IndentationError: too many levels of indentation
|
||||||
|
_build_nested('pass', 100),
|
||||||
|
|
||||||
# SyntaxErrors from Python/symtable.c
|
# SyntaxErrors from Python/symtable.c
|
||||||
'def f(x, x): pass',
|
'def f(x, x): pass',
|
||||||
@@ -248,7 +263,6 @@ def _get_error_list(code, version=None):
|
|||||||
tree = grammar.parse(code)
|
tree = grammar.parse(code)
|
||||||
return list(tree._iter_errors(grammar))
|
return list(tree._iter_errors(grammar))
|
||||||
|
|
||||||
|
|
||||||
def assert_comparison(code, error_code, positions):
|
def assert_comparison(code, error_code, positions):
|
||||||
errors = [(error.start_pos, error.code) for error in _get_error_list(code)]
|
errors = [(error.start_pos, error.code) for error in _get_error_list(code)]
|
||||||
assert [(pos, error_code) for pos in positions] == errors
|
assert [(pos, error_code) for pos in positions] == errors
|
||||||
@@ -382,10 +396,6 @@ def test_python_exception_matches_version(code, version):
|
|||||||
|
|
||||||
|
|
||||||
def test_statically_nested_blocks():
|
def test_statically_nested_blocks():
|
||||||
def indent(code):
|
|
||||||
lines = code.splitlines(True)
|
|
||||||
return ''.join([' ' + line for line in lines])
|
|
||||||
|
|
||||||
def build(code, depth):
|
def build(code, depth):
|
||||||
if depth == 0:
|
if depth == 0:
|
||||||
return code
|
return code
|
||||||
@@ -485,3 +495,7 @@ def test_escape_decode_literals(each_version):
|
|||||||
# The positioning information is only available in Python 3.
|
# The positioning information is only available in Python 3.
|
||||||
wanted += ' at position 0'
|
wanted += ' at position 0'
|
||||||
assert error.message == wanted
|
assert error.message == wanted
|
||||||
|
|
||||||
|
|
||||||
|
def test_passes():
|
||||||
|
assert not _get_error_list(_build_nested('pass', 99))
|
||||||
|
|||||||
Reference in New Issue
Block a user