Skip to content

Commit

Permalink
Fix a crash when a subclass extends __slots__ (#9817)
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobtylerwalls authored Jul 20, 2024
1 parent c9c768e commit 8e18fc0
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 4 deletions.
3 changes: 3 additions & 0 deletions doc/whatsnew/fragments/9814.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix a crash when a subclass extends ``__slots__``.

Closes #9814
20 changes: 16 additions & 4 deletions pylint/checkers/classes/class_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1537,7 +1537,11 @@ def _has_valid_slots(self, node: nodes.ClassDef) -> bool:
if "__slots__" not in node.locals:
return False

for slots in node.ilookup("__slots__"):
try:
inferred_slots = tuple(node.ilookup("__slots__"))
except astroid.InferenceError:
return False
for slots in inferred_slots:
# check if __slots__ is a valid type
if isinstance(slots, util.UninferableBase):
return False
Expand All @@ -1555,7 +1559,11 @@ def _check_slots(self, node: nodes.ClassDef) -> None:
if "__slots__" not in node.locals:
return

for slots in node.ilookup("__slots__"):
try:
inferred_slots = tuple(node.ilookup("__slots__"))
except astroid.InferenceError:
return
for slots in inferred_slots:
# check if __slots__ is a valid type
if isinstance(slots, util.UninferableBase):
continue
Expand Down Expand Up @@ -1586,8 +1594,12 @@ def _check_slots(self, node: nodes.ClassDef) -> None:

def _get_classdef_slots_names(self, node: nodes.ClassDef) -> list[str]:

slots_names = []
for slots in node.ilookup("__slots__"):
slots_names: list[str] = []
try:
inferred_slots = tuple(node.ilookup("__slots__"))
except astroid.InferenceError: # pragma: no cover
return slots_names
for slots in inferred_slots:
if isinstance(slots, nodes.Dict):
values = [item[0] for item in slots.items]
else:
Expand Down
14 changes: 14 additions & 0 deletions tests/functional/s/slots_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,17 @@ class ClassWithEmptySlotsAndAnnotation:
__slots__ = ()

a: int


# https://github.com/pylint-dev/pylint/issues/9814
class SlotsManipulationTest:
__slots__ = ["a", "b", "c"]


class TestChild(SlotsManipulationTest):
__slots__ += ["d", "e", "f"] # pylint: disable=undefined-variable


t = TestChild()

print(t.__slots__)

0 comments on commit 8e18fc0

Please sign in to comment.