From 7d98c4eae618d9f977d12abc79ea97fd7d805bc6 Mon Sep 17 00:00:00 2001 From: temyurchenko <44875844+temyurchenko@users.noreply.github.com> Date: Thu, 26 Sep 2024 00:29:36 -0400 Subject: [PATCH] change the type annotation error heuristic (#2583) The previous one depended on the message from "typed_ast", which is not used anymore. Instead, we check if there is a "# type:" substring in the source line of the exception. This can yield some false positives, but probably rarely. (cherry picked from commit 62c5badc838419090ee319acfcef3b651ffb1e94) --- astroid/builder.py | 10 ++++++---- tests/test_builder.py | 6 ------ tests/test_nodes.py | 4 ++++ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/astroid/builder.py b/astroid/builder.py index 932b461fa5..f4be6972b8 100644 --- a/astroid/builder.py +++ b/astroid/builder.py @@ -12,6 +12,7 @@ import ast import os +import re import textwrap import types import warnings @@ -33,7 +34,6 @@ # The comment used to select a statement to be extracted # when calling extract_node. _STATEMENT_SELECTOR = "#@" -MISPLACED_TYPE_ANNOTATION_ERROR = "misplaced type annotation" if PY312_PLUS: warnings.filterwarnings("ignore", "invalid escape sequence", SyntaxWarning) @@ -479,9 +479,11 @@ def _parse_string( ) except SyntaxError as exc: # If the type annotations are misplaced for some reason, we do not want - # to fail the entire parsing of the file, so we need to retry the parsing without - # type comment support. - if exc.args[0] != MISPLACED_TYPE_ANNOTATION_ERROR or not type_comments: + # to fail the entire parsing of the file, so we need to retry the + # parsing without type comment support. We use a heuristic for + # determining if the error is due to type annotations. + type_annot_related = re.search(r"#\s+type:", exc.text or "") + if not (type_annot_related and type_comments): raise parser_module = get_parser_module(type_comments=False) diff --git a/tests/test_builder.py b/tests/test_builder.py index f9dac6169e..b5335d5667 100644 --- a/tests/test_builder.py +++ b/tests/test_builder.py @@ -914,12 +914,6 @@ def test_module_build_dunder_file() -> None: assert module.path[0] == collections.__file__ -@pytest.mark.xfail( - reason=( - "The builtin ast module does not fail with a specific error " - "for syntax error caused by invalid type comments." - ), -) def test_parse_module_with_invalid_type_comments_does_not_crash(): node = builder.parse( """ diff --git a/tests/test_nodes.py b/tests/test_nodes.py index 64cae2f676..dced983625 100644 --- a/tests/test_nodes.py +++ b/tests/test_nodes.py @@ -1304,6 +1304,10 @@ def test_type_comments_invalid_expression() -> None: def test_type_comments_invalid_function_comments() -> None: module = builder.parse( """ + def func( + # type: () -> int # inside parentheses + ): + pass def func(): # type: something completely invalid pass