From 98a580bbdc217a8b1a47b772d2140ed29cdc587a Mon Sep 17 00:00:00 2001 From: Sam Burnett <95222040+smb55@users.noreply.github.com> Date: Mon, 9 Sep 2024 05:24:54 +0800 Subject: [PATCH] Added Python and grammar versions to a parser error message (#4378) --------- Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Co-authored-by: Shantanu Jain --- CHANGES.md | 2 ++ src/black/mode.py | 4 ++++ src/black/parsing.py | 16 ++++++++++++---- tests/test_format.py | 4 +++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index b9909b8..583a0be 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -47,6 +47,8 @@ +- Added Python target version information on parse error (#4378) + ### _Blackd_ diff --git a/src/black/mode.py b/src/black/mode.py index 43c6004..2260890 100644 --- a/src/black/mode.py +++ b/src/black/mode.py @@ -26,6 +26,10 @@ class TargetVersion(Enum): PY312 = 12 PY313 = 13 + def pretty(self) -> str: + assert self.name[:2] == "PY" + return f"Python {self.name[2]}.{self.name[3:]}" + class Feature(Enum): F_STRINGS = 2 diff --git a/src/black/parsing.py b/src/black/parsing.py index e8664b5..a046034 100644 --- a/src/black/parsing.py +++ b/src/black/parsing.py @@ -5,7 +5,7 @@ import ast import sys import warnings -from typing import Iterable, Iterator, List, Set, Tuple +from typing import Collection, Iterator, List, Set, Tuple from black.mode import VERSION_TO_FEATURES, Feature, TargetVersion, supports_feature from black.nodes import syms @@ -52,12 +52,20 @@ def get_grammars(target_versions: Set[TargetVersion]) -> List[Grammar]: return grammars -def lib2to3_parse(src_txt: str, target_versions: Iterable[TargetVersion] = ()) -> Node: +def lib2to3_parse( + src_txt: str, target_versions: Collection[TargetVersion] = () +) -> Node: """Given a string with source, return the lib2to3 Node.""" if not src_txt.endswith("\n"): src_txt += "\n" grammars = get_grammars(set(target_versions)) + if target_versions: + max_tv = max(target_versions, key=lambda tv: tv.value) + tv_str = f" for target version {max_tv.pretty()}" + else: + tv_str = "" + errors = {} for grammar in grammars: drv = driver.Driver(grammar) @@ -73,14 +81,14 @@ def lib2to3_parse(src_txt: str, target_versions: Iterable[TargetVersion] = ()) - except IndexError: faulty_line = "" errors[grammar.version] = InvalidInput( - f"Cannot parse: {lineno}:{column}: {faulty_line}" + f"Cannot parse{tv_str}: {lineno}:{column}: {faulty_line}" ) except TokenError as te: # In edge cases these are raised; and typically don't have a "faulty_line". lineno, column = te.args[1] errors[grammar.version] = InvalidInput( - f"Cannot parse: {lineno}:{column}: {te.args[0]}" + f"Cannot parse{tv_str}: {lineno}:{column}: {te.args[0]}" ) else: diff --git a/tests/test_format.py b/tests/test_format.py index 9162c58..ade7761 100644 --- a/tests/test_format.py +++ b/tests/test_format.py @@ -87,4 +87,6 @@ def test_patma_invalid() -> None: with pytest.raises(black.parsing.InvalidInput) as exc_info: assert_format(source, expected, mode, minimum_version=(3, 10)) - exc_info.match("Cannot parse: 10:11") + exc_info.match( + "Cannot parse for target version Python 3.10: 10:11: case a := b:" + )