From 57f7c465ceea877ea04aa3228949fd4b36c7f885 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Sat, 5 Aug 2017 14:45:47 +0200 Subject: [PATCH] Add 'too many levels of indentation' issue. --- parso/python/normalizer.py | 6 ++++++ test/test_python_errors.py | 24 +++++++++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/parso/python/normalizer.py b/parso/python/normalizer.py index ae12115..6f2843a 100644 --- a/parso/python/normalizer.py +++ b/parso/python/normalizer.py @@ -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') # This is the maximal block size given by python. _MAX_BLOCK_SIZE = 20 +_MAX_INDENT_COUNT = 100 ALLOWED_FUTURES = ( 'all_feature_names', 'nested_scopes', 'generators', 'division', 'absolute_import', 'with_statement', 'print_function', 'unicode_literals', @@ -236,6 +237,7 @@ class ErrorFinder(Normalizer): else: parent_scope = search_ancestor(node, allowed) self._context = Context(parent_scope, self._add_syntax_error) + self._indentation_count = 0 @contextmanager def visit_node(self, node): @@ -497,6 +499,10 @@ class ErrorFinder(Normalizer): elif node.type == 'expr_list': for expr in node.children[::2]: 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 diff --git a/test/test_python_errors.py b/test/test_python_errors.py index 6f83cc6..e6a4f3f 100644 --- a/test/test_python_errors.py +++ b/test/test_python_errors.py @@ -11,6 +11,19 @@ import pytest 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 = [ '1 +', '?', @@ -112,6 +125,8 @@ FAILING_EXAMPLES = [ r"'''", r"'", r"\blub", + # IndentationError: too many levels of indentation + _build_nested('pass', 100), # SyntaxErrors from Python/symtable.c 'def f(x, x): pass', @@ -248,7 +263,6 @@ def _get_error_list(code, version=None): tree = grammar.parse(code) return list(tree._iter_errors(grammar)) - def assert_comparison(code, error_code, positions): errors = [(error.start_pos, error.code) for error in _get_error_list(code)] 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 indent(code): - lines = code.splitlines(True) - return ''.join([' ' + line for line in lines]) - def build(code, depth): if depth == 0: return code @@ -485,3 +495,7 @@ def test_escape_decode_literals(each_version): # The positioning information is only available in Python 3. wanted += ' at position 0' assert error.message == wanted + + +def test_passes(): + assert not _get_error_list(_build_nested('pass', 99))