From e47e3b8a2283559d6918a3c02689f6b821562b6b Mon Sep 17 00:00:00 2001 From: Synrom Date: Thu, 28 Aug 2025 09:33:52 +0000 Subject: [PATCH 1/3] [fix] Fix parsing deeply nested parentheses causing MemoryError --- ChangeLog | 4 ++++ astroid/builder.py | 2 +- tests/test_regrtest.py | 11 ++++++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 47bb4d19b..08d1f67d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,10 @@ What's New in astroid 4.0.0? ============================ Release date: TBA +* Fix parsing deeply nested parentheses causing MemoryError + + Closes #2643 + * Fix crash when inferring namedtuple with invalid field name looking like f-string formatting. Closes #2519 diff --git a/astroid/builder.py b/astroid/builder.py index 6205f83d4..a107fed99 100644 --- a/astroid/builder.py +++ b/astroid/builder.py @@ -181,7 +181,7 @@ def _data_build( node, parser_module = _parse_string( data, type_comments=True, modname=modname ) - except (TypeError, ValueError, SyntaxError) as exc: + except (TypeError, ValueError, SyntaxError, MemoryError) as exc: raise AstroidSyntaxError( "Parsing Python code failed:\n{error}", source=data, diff --git a/tests/test_regrtest.py b/tests/test_regrtest.py index 1b16662c6..0294cdeea 100644 --- a/tests/test_regrtest.py +++ b/tests/test_regrtest.py @@ -13,7 +13,7 @@ from astroid.builder import AstroidBuilder, _extract_single_node, extract_node from astroid.const import PY312_PLUS from astroid.context import InferenceContext -from astroid.exceptions import InferenceError +from astroid.exceptions import AstroidSyntaxError, InferenceError from astroid.manager import AstroidManager from astroid.raw_building import build_module from astroid.util import Uninferable @@ -561,3 +561,12 @@ def test_regression_infer_namedtuple_invalid_fieldname_error() -> None: node = extract_node(code) inferred = next(node.infer()) assert inferred.value == Uninferable + + +def test_regression_parse_deeply_nested_parentheses() -> None: + """Regression test for issue #2643.""" + with pytest.raises(AstroidSyntaxError, match="Parsing Python code failed:") as ctx: + extract_node( + "A=((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((c,j=t" + ) + assert isinstance(ctx.value.error, MemoryError) From c93f6a704db57654fe820041d59f85a9fa496e86 Mon Sep 17 00:00:00 2001 From: Synrom Date: Thu, 28 Aug 2025 10:03:50 +0000 Subject: [PATCH 2/3] tests: fix regression test for deeply nested parentheses on PyPy3.10 --- tests/test_regrtest.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_regrtest.py b/tests/test_regrtest.py index 0294cdeea..0ff3b6f52 100644 --- a/tests/test_regrtest.py +++ b/tests/test_regrtest.py @@ -2,6 +2,7 @@ # For details: https://github.com/pylint-dev/astroid/blob/main/LICENSE # Copyright (c) https://github.com/pylint-dev/astroid/blob/main/CONTRIBUTORS.txt +import platform import sys import textwrap import unittest @@ -569,4 +570,7 @@ def test_regression_parse_deeply_nested_parentheses() -> None: extract_node( "A=((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((c,j=t" ) - assert isinstance(ctx.value.error, MemoryError) + expected = ( + SyntaxError if platform.python_implementation() == "PyPy" else MemoryError + ) + assert isinstance(ctx.value.error, expected) From cf2227a8dd6d4aae2d7bb05ab07611c80a5b9de2 Mon Sep 17 00:00:00 2001 From: Synrom Date: Thu, 28 Aug 2025 11:42:29 +0000 Subject: [PATCH 3/3] Update ChangeLog --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 08d1f67d3..379a2a748 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,7 +7,7 @@ What's New in astroid 4.0.0? ============================ Release date: TBA -* Fix parsing deeply nested parentheses causing MemoryError +* Prevent crash when parsing deeply nested parentheses causing MemoryError in python's built-in ast. Closes #2643