diff options
author | Huw Jones <huw@huwcbjones.co.uk> | 2022-06-06 04:21:54 +0100 |
---|---|---|
committer | Pierre Sassoulas <pierre.sassoulas@gmail.com> | 2022-06-06 22:27:46 +0200 |
commit | 5913cb7cd7cde24ccea6bcd6b4b8a80961a4d1c2 (patch) | |
tree | 9e437174e2a138edd02f1788c4fb3c945b15c629 | |
parent | 4621ad5a0d66f529a4c71b5e18382a44760c7b43 (diff) | |
download | pylint-git-5913cb7cd7cde24ccea6bcd6b4b8a80961a4d1c2.tar.gz |
Fix a crash when linting ``__new__()`` methods that return a call (#6822)
Only check for Enum attributes when metaclass is an Enum metaclass
-rw-r--r-- | doc/whatsnew/2/2.14/full.rst | 4 | ||||
-rw-r--r-- | pylint/checkers/typecheck.py | 8 | ||||
-rw-r--r-- | tests/functional/e/enum_self_defined_member_6805.py | 43 | ||||
-rw-r--r-- | tests/functional/e/enum_self_defined_member_6805.txt | 1 |
4 files changed, 52 insertions, 4 deletions
diff --git a/doc/whatsnew/2/2.14/full.rst b/doc/whatsnew/2/2.14/full.rst index 46eebb217..524c759bd 100644 --- a/doc/whatsnew/2/2.14/full.rst +++ b/doc/whatsnew/2/2.14/full.rst @@ -14,6 +14,10 @@ Release date: TBA Closes #6800 +* Fixed a crash when linting ``__new__()`` methods that return a call expression. + + Closes #6805 + * Don't crash if we can't find the user's home directory. Closes #6802 diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py index 413a93c3b..0a1307ffe 100644 --- a/pylint/checkers/typecheck.py +++ b/pylint/checkers/typecheck.py @@ -451,10 +451,10 @@ def _emit_no_member( except astroid.MroError: return False if metaclass: - if _enum_has_attribute(owner, node): - return False # Renamed in Python 3.10 to `EnumType` - return metaclass.qname() in {"enum.EnumMeta", "enum.EnumType"} + if metaclass.qname() in {"enum.EnumMeta", "enum.EnumType"}: + return not _enum_has_attribute(owner, node) + return False return False if not has_known_bases(owner): return False @@ -583,7 +583,7 @@ def _enum_has_attribute( (c.value for c in dunder_new.get_children() if isinstance(c, nodes.Return)), None, ) - if returned_obj_name is not None: + if isinstance(returned_obj_name, nodes.Name): # Find all attribute assignments to the returned object enum_attributes |= _get_all_attribute_assignments( dunder_new, returned_obj_name.name diff --git a/tests/functional/e/enum_self_defined_member_6805.py b/tests/functional/e/enum_self_defined_member_6805.py new file mode 100644 index 000000000..bcf0c8e10 --- /dev/null +++ b/tests/functional/e/enum_self_defined_member_6805.py @@ -0,0 +1,43 @@ +"""Tests for self-defined Enum members (https://github.com/PyCQA/pylint/issues/6805)""" +# pylint: disable=missing-docstring +# pylint: disable=too-few-public-methods +from enum import IntEnum + + +class Foo(type): + pass + + +class Parent: + def __new__(cls, *_args, **_kwargs): + return object.__new__(cls) + + +class NotEnumHasDynamicGetAttrMetaclass(metaclass=Foo): + def __new__(cls): + return Parent.__new__(cls) + + def __getattr__(self, item): + return item + + def magic(self): + return self.dynamic + + +NotEnumHasDynamicGetAttrMetaclass().magic() + + +class Day(IntEnum): + MONDAY = (1, "Mon") + TUESDAY = (2, "Tue") + WEDNESDAY = (3, "Wed") + THURSDAY = (4, "Thu") + FRIDAY = (5, "Fri") + SATURDAY = (6, "Sat") + SUNDAY = (7, "Sun") + + def __new__(cls, value, _abbr=None): + return int.__new__(cls, value) + + +print(Day.FRIDAY.foo) # [no-member] diff --git a/tests/functional/e/enum_self_defined_member_6805.txt b/tests/functional/e/enum_self_defined_member_6805.txt new file mode 100644 index 000000000..f7e1c1e13 --- /dev/null +++ b/tests/functional/e/enum_self_defined_member_6805.txt @@ -0,0 +1 @@ +no-member:43:6:43:20::Instance of 'FRIDAY' has no 'foo' member:INFERENCE |