Skip to content

Commit

Permalink
change the type annotation error heuristic (#2583)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
temyurchenko committed Sep 26, 2024
1 parent a3f5c4a commit 62c5bad
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 10 deletions.
10 changes: 6 additions & 4 deletions astroid/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import ast
import os
import re
import textwrap
import types
import warnings
Expand All @@ -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)
Expand Down Expand Up @@ -478,9 +478,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)
Expand Down
6 changes: 0 additions & 6 deletions tests/test_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -883,12 +883,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(
"""
Expand Down
4 changes: 4 additions & 0 deletions tests/test_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 62c5bad

Please sign in to comment.