Version Information
- vyper Version (output of
vyper --version): 0.4.4+commit.bdf00d31
- OS: Linux Ubuntu Jammy
- Python Version: Python 3.11
What's your issue about?
A deeply-nested array type annotation that CPython parses fine overflows Vyper's own recursive AST-annotation visitor and crashes the compiler with a raw Python RecursionError instead of a clean vyper.exceptions diagnostic. AnnotatingVisitor.generic_visit calls super().generic_visit(node) once per AST-node depth (vyper/ast/parse.py:258). This runs inside annotate_python_ast (called at parse.py:103), which is outside the python_ast.parse try/except at :80-81, and the only enclosing handler parse_to_ast (:31-33) catches SyntaxException — so the RecursionError (a RuntimeError subclass) escapes all handlers and reaches the user with no vyper.exceptions class and no source location. Both a ~500-level static array (uint256[1]…[1]) and a ~200-level DynArray[DynArray[…]] trigger it; a nested HashMap instead hits a CPython-parse SyntaxException that is handled cleanly, so the leak is specific to array-subscript nesting that reaches the annotation visitor.
Code that produces the failing contract:
# both crash with `RecursionError: maximum recursion depth exceeded`
print("x: " + "uint256" + "[1]" * 500 + "\n@external\ndef f(): pass")
print("x: " + "DynArray[" * 200 + "uint256" + ", 2]" * 200 + "\n@external\ndef f(): pass")
Command and full output:
$ vyper nest.vy
RecursionError: maximum recursion depth exceeded # bare — no vyper.exceptions, no location
Source-level evidence:
# vyper/ast/parse.py
# :31-33 parse_to_ast: try: ... except SyntaxException as e: ... # catches Vyper's class only
# :79-81 try: py_ast = python_ast.parse(...) except SyntaxError # CPython parse site
# :103 annotate_python_ast(...) # OUTSIDE the :80 try/except
# :205 class AnnotatingVisitor.generic_visit(self, node):
# :258 node = super().generic_visit(node) # <- RecursionError on deep nesting, unguarded
How can it be fixed?
A sys.setrecursionlimit-aware guard or a typed exception (e.g. StructureException("type nesting too deep")) raised from the annotation pass would convert the raw RecursionError into a clean Vyper diagnostic with a source location.
Version Information
vyper --version): 0.4.4+commit.bdf00d31What's your issue about?
A deeply-nested array type annotation that CPython parses fine overflows Vyper's own recursive AST-annotation visitor and crashes the compiler with a raw Python
RecursionErrorinstead of a cleanvyper.exceptionsdiagnostic.AnnotatingVisitor.generic_visitcallssuper().generic_visit(node)once per AST-node depth (vyper/ast/parse.py:258). This runs insideannotate_python_ast(called atparse.py:103), which is outside thepython_ast.parsetry/except at:80-81, and the only enclosing handlerparse_to_ast(:31-33) catchesSyntaxException— so theRecursionError(aRuntimeErrorsubclass) escapes all handlers and reaches the user with novyper.exceptionsclass and no source location. Both a ~500-level static array (uint256[1]…[1]) and a ~200-levelDynArray[DynArray[…]]trigger it; a nestedHashMapinstead hits a CPython-parseSyntaxExceptionthat is handled cleanly, so the leak is specific to array-subscript nesting that reaches the annotation visitor.Code that produces the failing contract:
Command and full output:
Source-level evidence:
How can it be fixed?
A
sys.setrecursionlimit-aware guard or a typed exception (e.g.StructureException("type nesting too deep")) raised from the annotation pass would convert the rawRecursionErrorinto a clean Vyper diagnostic with a source location.