From 364282ea7db7e9515299fe8f9cc5ad9523ea1820 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Mon, 20 May 2024 12:06:45 -0400 Subject: [PATCH] fix: catch TokenError on parse (#1788) * catch TokenError on parse * typo, use env.PYVERSION * Update tests/test_parser.py --------- Co-authored-by: Ned Batchelder --- coverage/parser.py | 8 ++++++-- tests/test_parser.py | 8 ++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/coverage/parser.py b/coverage/parser.py index 2b4e60aa8..9c9ffbf0a 100644 --- a/coverage/parser.py +++ b/coverage/parser.py @@ -263,10 +263,14 @@ def parse_source(self) -> None: try: self._ast_root = ast.parse(self.text) self._raw_parse() - except (IndentationError, SyntaxError) as err: + except (tokenize.TokenError, IndentationError, SyntaxError) as err: + if hasattr(err, "lineno"): + lineno = err.lineno # IndentationError + else: + lineno = err.args[1][0] # TokenError raise NotPython( f"Couldn't parse '{self.filename}' as Python source: " + - f"{err.args[0]!r} at line {err.lineno}", + f"{err.args[0]!r} at line {lineno}", ) from err ignore = self.excluded | self.raw_docstrings diff --git a/tests/test_parser.py b/tests/test_parser.py index bf3ccd28d..f9655d160 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -128,6 +128,14 @@ def foo(): pytest.param("0 spaces\n 2\n 1", id="bad_indent"), pytest.param("'''", id="string_eof"), pytest.param("$hello", id="dollar"), + # on 3.10 this passes ast.parse but fails on tokenize.generate_tokens + pytest.param( + "\r'\\\n'''", + id="leading_newline_eof", + marks=[ + pytest.mark.skipif(env.PYVERSION >= (3, 12), reason="parses fine in 3.12"), + ] + ) ]) def test_not_python(self, text: str) -> None: msg = r"Couldn't parse '' as Python source: '.*' at line \d+"