diff --git a/doc/whatsnew/fragments/3860.bugfix b/doc/whatsnew/fragments/3860.bugfix new file mode 100644 index 0000000000..8dcbe087b2 --- /dev/null +++ b/doc/whatsnew/fragments/3860.bugfix @@ -0,0 +1,4 @@ +Fixed a syntax-error crash that was not handled properly when the declared encoding of a file +was ``utf-9``. + +Closes #3860 diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py index bc54522f37..7cab785869 100644 --- a/pylint/checkers/imports.py +++ b/pylint/checkers/imports.py @@ -28,6 +28,7 @@ ) from pylint.exceptions import EmptyReportError from pylint.graph import DotBackend, get_cycles +from pylint.interfaces import HIGH from pylint.reporters.ureports.nodes import Paragraph, Section, VerbatimText from pylint.typing import MessageDefinitionTuple from pylint.utils import IsortDriver @@ -800,10 +801,10 @@ def _get_imported_module( return None self.add_message("relative-beyond-top-level", node=importnode) except astroid.AstroidSyntaxError as exc: - message = ( - f"Cannot import {modname!r} due to syntax error {str(exc.error)!r}" + message = f"Cannot import {modname!r} due to '{exc.error}'" + self.add_message( + "syntax-error", line=importnode.lineno, args=message, confidence=HIGH ) - self.add_message("syntax-error", line=importnode.lineno, args=message) except astroid.AstroidBuildingError: if not self.linter.is_message_enabled("import-error"): diff --git a/pylint/lint/pylinter.py b/pylint/lint/pylinter.py index bacce60e11..53889ba299 100644 --- a/pylint/lint/pylinter.py +++ b/pylint/lint/pylinter.py @@ -692,11 +692,11 @@ def _check_files( ) msg = get_fatal_error_message(file.filepath, template_path) if isinstance(ex, AstroidError): - symbol = "astroid-error" - self.add_message(symbol, args=(file.filepath, msg)) + self.add_message( + "astroid-error", args=(file.filepath, msg), confidence=HIGH + ) else: - symbol = "fatal" - self.add_message(symbol, args=msg) + self.add_message("fatal", args=msg, confidence=HIGH) def _check_file( self, @@ -918,7 +918,8 @@ def get_ast( "syntax-error", line=getattr(ex.error, "lineno", 0), col_offset=getattr(ex.error, "offset", None), - args=str(ex.error), + args=f"Parsing failed: '{ex.error}'", + confidence=HIGH, ) except astroid.AstroidBuildingError as ex: self.add_message("parse-error", args=ex) diff --git a/tests/functional/i/import_error.txt b/tests/functional/i/import_error.txt index 28e94dc72e..3ffbad9698 100644 --- a/tests/functional/i/import_error.txt +++ b/tests/functional/i/import_error.txt @@ -1,5 +1,5 @@ import-error:3:0:3:22::Unable to import 'totally_missing':UNDEFINED import-error:21:4:21:26::Unable to import 'maybe_missing_2':UNDEFINED no-name-in-module:33:0:33:49::No name 'syntax_error' in module 'functional.s.syntax':UNDEFINED -syntax-error:33:0:None:None::Cannot import 'functional.s.syntax.syntax_error' due to syntax error 'invalid syntax (, line 1)':UNDEFINED +syntax-error:33:0:None:None::Cannot import 'functional.s.syntax.syntax_error' due to 'invalid syntax (, line 1)':HIGH multiple-imports:78:0:78:15::Multiple imports on one line (foo, bar):UNDEFINED diff --git a/tests/functional/s/syntax/syntax_error.txt b/tests/functional/s/syntax/syntax_error.txt index 78a055cf66..3640717728 100644 --- a/tests/functional/s/syntax/syntax_error.txt +++ b/tests/functional/s/syntax/syntax_error.txt @@ -1 +1 @@ -syntax-error:1:5:None:None::invalid syntax (, line 1):UNDEFINED +syntax-error:1:5:None:None::"Parsing failed: 'invalid syntax (, line 1)'":HIGH diff --git a/tests/test_self.py b/tests/test_self.py index 8401195867..efa38fab48 100644 --- a/tests/test_self.py +++ b/tests/test_self.py @@ -569,12 +569,9 @@ def foobar(arg): expected_output=expected, ) - def test_stdin_syntaxerror(self) -> None: - expected_output = ( - "************* Module a\n" - "a.py:1:4: E0001: invalid syntax (, line 1) (syntax-error)" - ) - + def test_stdin_syntax_error(self) -> None: + expected_output = """************* Module a +a.py:1:4: E0001: Parsing failed: 'invalid syntax (, line 1)' (syntax-error)""" with mock.patch( "pylint.lint.pylinter._read_stdin", return_value="for\n" ) as mock_stdin: