diff --git a/mypy/plugins/dataclasses.py b/mypy/plugins/dataclasses.py index e916ded01dd2..97faadbad064 100644 --- a/mypy/plugins/dataclasses.py +++ b/mypy/plugins/dataclasses.py @@ -457,10 +457,9 @@ def add_slots( ) return - generated_slots = {attr.name for attr in attributes} - if (info.slots is not None and info.slots != generated_slots) or info.names.get( - "__slots__" - ): + existing_slots = info.names.get("__slots__") + slots_defined_by_plugin = existing_slots is not None and existing_slots.plugin_generated + if existing_slots is not None and not slots_defined_by_plugin: # This means we have a slots conflict. # Class explicitly specifies a different `__slots__` field. # And `@dataclass(slots=True)` is used. @@ -478,6 +477,7 @@ def add_slots( # does not have concrete `__slots__` defined. Ignoring. return + generated_slots = {attr.name for attr in attributes} info.slots = generated_slots # Now, insert `.__slots__` attribute to class namespace: @@ -485,7 +485,13 @@ def add_slots( [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) + add_attribute_to_class( + self._api, + self._cls, + "__slots__", + slots_type, + overwrite_existing=slots_defined_by_plugin, + ) def reset_init_only_vars(self, info: TypeInfo, attributes: list[DataclassAttribute]) -> None: """Remove init-only vars from the class and reset init var declarations.""" diff --git a/test-data/unit/check-dataclasses.test b/test-data/unit/check-dataclasses.test index 3cc4a03ffb11..b12d12393ff5 100644 --- a/test-data/unit/check-dataclasses.test +++ b/test-data/unit/check-dataclasses.test @@ -1606,6 +1606,20 @@ class PublishedMessages: left: int [builtins fixtures/dataclasses.pyi] +[case testDataclassSlotsWithDeferredBase] +# flags: --python-version 3.10 +from dataclasses import dataclass + +@dataclass +class A(B): ... + +@dataclass +class B: ... + +@dataclass(slots=True) +class C: ... +[builtins fixtures/dataclasses.pyi] + [case testDataclassesAnyInherit] from dataclasses import dataclass from typing import Any