From 4a1a38eee6b1558c0891584a6fdff84eab49c7a6 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Wed, 12 Jul 2023 22:51:50 +0300 Subject: [PATCH] Add runtime `__slots__` attribute to dataclasses (#15649) Closes https://github.com/python/mypy/issues/15647 --- mypy/plugins/dataclasses.py | 8 +++++++- test-data/unit/check-dataclasses.test | 29 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/mypy/plugins/dataclasses.py b/mypy/plugins/dataclasses.py index c78a1b313878..b1dc016a0279 100644 --- a/mypy/plugins/dataclasses.py +++ b/mypy/plugins/dataclasses.py @@ -469,9 +469,15 @@ def add_slots( self._cls, ) return - info.slots = generated_slots + # Now, insert `.__slots__` attribute to class namespace: + slots_type = TupleType( + [self._api.named_type("builtins.str") for _ in generated_slots], + self._api.named_type("builtins.tuple"), + ) + add_attribute_to_class(self._api, self._cls, "__slots__", slots_type) + def reset_init_only_vars(self, info: TypeInfo, attributes: list[DataclassAttribute]) -> None: """Remove init-only vars from the class and reset init var declarations.""" for attr in attributes: diff --git a/test-data/unit/check-dataclasses.test b/test-data/unit/check-dataclasses.test index 4a6e737ddd8d..131521aa98e4 100644 --- a/test-data/unit/check-dataclasses.test +++ b/test-data/unit/check-dataclasses.test @@ -1547,6 +1547,35 @@ class Other: [builtins fixtures/dataclasses.pyi] +[case testDataclassWithSlotsRuntimeAttr] +# flags: --python-version 3.10 +from dataclasses import dataclass + +@dataclass(slots=True) +class Some: + x: int + y: str + z: bool + +reveal_type(Some.__slots__) # N: Revealed type is "Tuple[builtins.str, builtins.str, builtins.str]" + +@dataclass(slots=True) +class Other: + x: int + y: str + +reveal_type(Other.__slots__) # N: Revealed type is "Tuple[builtins.str, builtins.str]" + + +@dataclass +class NoSlots: + x: int + y: str + +NoSlots.__slots__ # E: "Type[NoSlots]" has no attribute "__slots__" +[builtins fixtures/dataclasses.pyi] + + [case testSlotsDefinitionWithTwoPasses1] # flags: --python-version 3.10 # https://github.com/python/mypy/issues/11821