Skip to content

Commit b78f4b5

Browse files
authored
Add runtime __slots__ attribute to attrs (#15651)
This is similar to #15649 but for `attrs` :) Refs #15647
1 parent fbe588f commit b78f4b5

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

mypy/plugins/attrs.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,13 @@ def _add_slots(ctx: mypy.plugin.ClassDefContext, attributes: list[Attribute]) ->
896896
# Unlike `@dataclasses.dataclass`, `__slots__` is rewritten here.
897897
ctx.cls.info.slots = {attr.name for attr in attributes}
898898

899+
# Also, inject `__slots__` attribute to class namespace:
900+
slots_type = TupleType(
901+
[ctx.api.named_type("builtins.str") for _ in attributes],
902+
fallback=ctx.api.named_type("builtins.tuple"),
903+
)
904+
add_attribute_to_class(api=ctx.api, cls=ctx.cls, name="__slots__", typ=slots_type)
905+
899906

900907
def _add_match_args(ctx: mypy.plugin.ClassDefContext, attributes: list[Attribute]) -> None:
901908
if (

test-data/unit/check-plugin-attrs.test

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,6 +1676,33 @@ class C:
16761676
self.c = 2 # E: Trying to assign name "c" that is not in "__slots__" of type "__main__.C"
16771677
[builtins fixtures/plugin_attrs.pyi]
16781678

1679+
[case testRuntimeSlotsAttr]
1680+
from attr import dataclass
1681+
1682+
@dataclass(slots=True)
1683+
class Some:
1684+
x: int
1685+
y: str
1686+
z: bool
1687+
1688+
reveal_type(Some.__slots__) # N: Revealed type is "Tuple[builtins.str, builtins.str, builtins.str]"
1689+
1690+
@dataclass(slots=True)
1691+
class Other:
1692+
x: int
1693+
y: str
1694+
1695+
reveal_type(Other.__slots__) # N: Revealed type is "Tuple[builtins.str, builtins.str]"
1696+
1697+
1698+
@dataclass
1699+
class NoSlots:
1700+
x: int
1701+
y: str
1702+
1703+
NoSlots.__slots__ # E: "Type[NoSlots]" has no attribute "__slots__"
1704+
[builtins fixtures/plugin_attrs.pyi]
1705+
16791706
[case testAttrsWithMatchArgs]
16801707
# flags: --python-version 3.10
16811708
import attr

0 commit comments

Comments
 (0)