diff --git a/ChangeLog b/ChangeLog index faccd1456..faed12c04 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,10 @@ What's New in astroid 2.13.0? Release date: TBA +* Prevent returning an empty list for ``ClassDef.slots()`` when the mro list contains one class & it is not ``object``. + + Refs PyCQA/pylint#5099 + * Add ``_value2member_map_`` member to the ``enum`` brain. Refs PyCQA/pylint#3941 diff --git a/astroid/nodes/scoped_nodes/scoped_nodes.py b/astroid/nodes/scoped_nodes/scoped_nodes.py index 475ae46b0..6c161fbe2 100644 --- a/astroid/nodes/scoped_nodes/scoped_nodes.py +++ b/astroid/nodes/scoped_nodes/scoped_nodes.py @@ -2959,8 +2959,10 @@ def slots(self): def grouped_slots( mro: list[ClassDef], ) -> Iterator[node_classes.NodeNG | None]: - # Not interested in object, since it can't have slots. - for cls in mro[:-1]: + for cls in mro: + # Not interested in object, since it can't have slots. + if cls.qname() == "builtins.object": + continue try: cls_slots = cls._slots() except NotImplementedError: diff --git a/tests/unittest_brain.py b/tests/unittest_brain.py index d6d4ef5aa..2b0b7230c 100644 --- a/tests/unittest_brain.py +++ b/tests/unittest_brain.py @@ -1819,6 +1819,26 @@ def __init__(self, value): assert isinstance(slots[0], nodes.Const) assert slots[0].value == "value" + def test_collections_generic_alias_slots(self): + """Test slots for a class which is a subclass of a generic alias type.""" + node = builder.extract_node( + """ + import collections + import typing + Type = typing.TypeVar('Type') + class A(collections.abc.AsyncIterator[Type]): + __slots__ = ('_value',) + def __init__(self, value: collections.abc.AsyncIterator[Type]): + self._value = value + """ + ) + inferred = next(node.infer()) + assert isinstance(inferred, nodes.ClassDef) + slots = inferred.slots() + assert len(slots) == 1 + assert isinstance(slots[0], nodes.Const) + assert slots[0].value == "_value" + def test_has_dunder_args(self) -> None: ast_node = builder.extract_node( """