diff --git a/parso/python/normalizer.py b/parso/python/normalizer.py index 2760dcb..794a37d 100644 --- a/parso/python/normalizer.py +++ b/parso/python/normalizer.py @@ -51,13 +51,13 @@ class ErrorFinder(Normalizer): self._add_syntax_error("invalid syntax", leaf) elif node.type in _BLOCK_STMTS: with self._context.add_block(node): + if len(self._context.blocks) == _MAX_BLOCK_SIZE: + self._add_syntax_error("too many statically nested blocks", node) yield return elif node.type in ('classdef', 'funcdef'): context = self._context with self._context.add_context(node) as new_context: - if len(context.blocks) == _MAX_BLOCK_SIZE: - self._add_syntax_error("Too many statically nested blocks", node) self._context = new_context yield self._context = context diff --git a/test/test_python_errors.py b/test/test_python_errors.py index cfd9b78..759b603 100644 --- a/test/test_python_errors.py +++ b/test/test_python_errors.py @@ -58,6 +58,7 @@ def test_indentation_errors(code, positions): 'code', [ # SyntaxError '1 +', + '?', # IndentationError ' foo', 'def x():\n 1\n 2', @@ -73,3 +74,32 @@ def test_python_exception_matches(code): else: assert False, "The piece of code should raise an exception." assert wanted == error.message + + +def test_statically_nested_blocks(): + def indent(code): + lines = code.splitlines(keepends=True) + return ''.join([' ' + line for line in lines]) + + def build(code, depth): + if depth == 0: + return code + + new_code = 'if 1:\n' + indent(code) + return build(new_code, depth - 1) + + def get_error(depth, add_func=False): + code = build('foo', depth) + if add_func: + code = 'def bar():\n' + indent(code) + errors = _get_error_list(code) + if errors: + assert errors[0].message == 'SyntaxError: too many statically nested blocks' + return errors[0] + return None + + assert get_error(19) is None + assert get_error(19, add_func=True) is None + + assert get_error(20) + assert get_error(20, add_func=True)