Skip to content

Commit

Permalink
Add runtime __slots__ attribute to attrs (#15651)
Browse files Browse the repository at this point in the history
This is similar to #15649 but for
`attrs` :)
Refs #15647
  • Loading branch information
sobolevn authored Jul 12, 2023
1 parent fbe588f commit b78f4b5
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
7 changes: 7 additions & 0 deletions mypy/plugins/attrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,13 @@ def _add_slots(ctx: mypy.plugin.ClassDefContext, attributes: list[Attribute]) ->
# Unlike `@dataclasses.dataclass`, `__slots__` is rewritten here.
ctx.cls.info.slots = {attr.name for attr in attributes}

# Also, inject `__slots__` attribute to class namespace:
slots_type = TupleType(
[ctx.api.named_type("builtins.str") for _ in attributes],
fallback=ctx.api.named_type("builtins.tuple"),
)
add_attribute_to_class(api=ctx.api, cls=ctx.cls, name="__slots__", typ=slots_type)


def _add_match_args(ctx: mypy.plugin.ClassDefContext, attributes: list[Attribute]) -> None:
if (
Expand Down
27 changes: 27 additions & 0 deletions test-data/unit/check-plugin-attrs.test
Original file line number Diff line number Diff line change
Expand Up @@ -1676,6 +1676,33 @@ class C:
self.c = 2 # E: Trying to assign name "c" that is not in "__slots__" of type "__main__.C"
[builtins fixtures/plugin_attrs.pyi]

[case testRuntimeSlotsAttr]
from attr 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/plugin_attrs.pyi]

[case testAttrsWithMatchArgs]
# flags: --python-version 3.10
import attr
Expand Down

0 comments on commit b78f4b5

Please sign in to comment.