From 5a9ea7ce8884c3040a21b91b45ab0a7951439f0f Mon Sep 17 00:00:00 2001 From: Claudiu Popa Date: Tue, 29 Dec 2020 10:20:00 +0100 Subject: Fix a crash in `undefined-variable` caused by chained attributes in metaclass Close #3742 --- ChangeLog | 4 ++++ pylint/checkers/variables.py | 5 ++++- tests/functional/u/undefined_variable_crash_on_attribute.py | 6 ++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 tests/functional/u/undefined_variable_crash_on_attribute.py diff --git a/ChangeLog b/ChangeLog index 97ebf5f55..9dfd94060 100644 --- a/ChangeLog +++ b/ChangeLog @@ -28,6 +28,10 @@ What's New in Pylint 2.6.1? =========================== Release date: TBA +* Fix a crash in `undefined-variable` caused by chained attributes in metaclass + + Close #3742 + * Fix false positive for `not-async-context-manager` when `contextlib.asynccontextmanager` is used Close #3862 diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index b6a2978a5..986f76fd2 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -2037,7 +2037,10 @@ class VariablesChecker(BaseChecker): if isinstance(klass._metaclass, astroid.Name): name = klass._metaclass.name elif isinstance(klass._metaclass, astroid.Attribute) and klass._metaclass.expr: - name = klass._metaclass.expr.name + attr = klass._metaclass.expr + while not isinstance(attr, astroid.Name): + attr = attr.expr + name = attr.name elif metaclass: name = metaclass.root().name diff --git a/tests/functional/u/undefined_variable_crash_on_attribute.py b/tests/functional/u/undefined_variable_crash_on_attribute.py new file mode 100644 index 000000000..571efab1c --- /dev/null +++ b/tests/functional/u/undefined_variable_crash_on_attribute.py @@ -0,0 +1,6 @@ +# pylint: disable=import-error,missing-module-docstring,missing-class-docstring,too-few-public-methods +import unknown + + +class Cls(metaclass=unknown.path.MetaFoo): + pass -- cgit v1.2.1