From 1615634f7bc44157b4ee74148f9af6d392d84bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Fri, 17 Dec 2021 21:37:40 +0100 Subject: [PATCH 1/3] Fix crash on uninferable decorators on Python 3.6 and 3.7 --- ChangeLog | 2 ++ doc/whatsnew/2.13.rst | 2 ++ pylint/checkers/utils.py | 6 +++++- tests/functional/o/overridden_final_method_regression.py | 6 ++++++ tests/functional/o/overridden_final_method_regression.txt | 1 + 5 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tests/functional/o/overridden_final_method_regression.py create mode 100644 tests/functional/o/overridden_final_method_regression.txt diff --git a/ChangeLog b/ChangeLog index 68ec3a7829..7b312ff495 100644 --- a/ChangeLog +++ b/ChangeLog @@ -79,6 +79,8 @@ Release date: TBA Closes #5323 +* Fixed crash on uninferable decorators on Python 3.6 and 3.7 + * Add checker ``unnecessary-ellipsis``: Emitted when the ellipsis constant is used unnecessarily. Closes #5460 diff --git a/doc/whatsnew/2.13.rst b/doc/whatsnew/2.13.rst index ef72d58552..8f71a4b122 100644 --- a/doc/whatsnew/2.13.rst +++ b/doc/whatsnew/2.13.rst @@ -73,6 +73,8 @@ Other Changes Closes #5065 +* Fixed crash on uninferable decorators on Python 3.6 and 3.7 + * Fatal errors now emit a score of 0.0 regardless of whether the linted module contained any statements diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py index 1f85399a7d..9deee663e3 100644 --- a/pylint/checkers/utils.py +++ b/pylint/checkers/utils.py @@ -876,7 +876,11 @@ def uninferable_final_decorators( except AttributeError: continue elif isinstance(decorator, nodes.Name): - import_node = decorator.lookup(decorator.name)[1][0] + lookup_values = decorator.lookup(decorator.name) + if lookup_values[1]: + import_node = decorator.lookup(decorator.name)[1][0] + else: + continue else: continue diff --git a/tests/functional/o/overridden_final_method_regression.py b/tests/functional/o/overridden_final_method_regression.py new file mode 100644 index 0000000000..a1f72b3807 --- /dev/null +++ b/tests/functional/o/overridden_final_method_regression.py @@ -0,0 +1,6 @@ +"""Test a crash regression for the overridden-final-method checker on uninferable decorators""" + + +@unknown_decorator # [undefined-variable] +def crash_test(): + """A docstring""" diff --git a/tests/functional/o/overridden_final_method_regression.txt b/tests/functional/o/overridden_final_method_regression.txt new file mode 100644 index 0000000000..a8cb239542 --- /dev/null +++ b/tests/functional/o/overridden_final_method_regression.txt @@ -0,0 +1 @@ +undefined-variable:4:1:4:18:crash_test:Undefined variable 'unknown_decorator':UNDEFINED From a815957b8dd95dc567710f86e03843faa121ae59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Fri, 17 Dec 2021 22:45:32 +0100 Subject: [PATCH 2/3] Add pragma --- pylint/checkers/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py index 9deee663e3..90654b4d21 100644 --- a/pylint/checkers/utils.py +++ b/pylint/checkers/utils.py @@ -880,7 +880,7 @@ def uninferable_final_decorators( if lookup_values[1]: import_node = decorator.lookup(decorator.name)[1][0] else: - continue + continue # pragma: no cover # Covered on Python < 3.8 else: continue From d5c0ddb1bdfe0b2c7342e42134dcafe18e845491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Fri, 17 Dec 2021 22:48:24 +0100 Subject: [PATCH 3/3] Update pylint/checkers/utils.py Co-authored-by: Mark Byrne <31762852+mbyrnepr2@users.noreply.github.com> --- pylint/checkers/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py index 90654b4d21..cb04c21190 100644 --- a/pylint/checkers/utils.py +++ b/pylint/checkers/utils.py @@ -878,7 +878,7 @@ def uninferable_final_decorators( elif isinstance(decorator, nodes.Name): lookup_values = decorator.lookup(decorator.name) if lookup_values[1]: - import_node = decorator.lookup(decorator.name)[1][0] + import_node = lookup_values[1][0] else: continue # pragma: no cover # Covered on Python < 3.8 else: