Skip to content

Comments

[ty] initial support for slots=True in dataclasses#20278

Merged
AlexWaygood merged 1 commit intoastral-sh:mainfrom
thejchap:thejchap/dataclass-slots
Sep 7, 2025
Merged

[ty] initial support for slots=True in dataclasses#20278
AlexWaygood merged 1 commit intoastral-sh:mainfrom
thejchap:thejchap/dataclass-slots

Conversation

@thejchap
Copy link
Contributor

@thejchap thejchap commented Sep 6, 2025

Summary

astral-sh/ty#111
https://docs.python.org/3/library/dataclasses.html

this pr adds initial support for slots=True in the dataclass decorator. synthesizes __slots__ as returning a fixed-length tuple of strs (field names)

Test Plan

@github-actions
Copy link
Contributor

github-actions bot commented Sep 6, 2025

Diagnostic diff on typing conformance tests

Changes were detected when running ty on typing conformance tests
--- old-output.txt	2025-09-07 17:09:46.191064468 +0000
+++ new-output.txt	2025-09-07 17:09:48.844087184 +0000
@@ -221,8 +221,6 @@
 dataclasses_order.py:50:4: error[unsupported-operator] Operator `<` is not supported for types `DC1` and `DC2`
 dataclasses_postinit.py:28:7: error[unresolved-attribute] Type `DC1` has no attribute `x`
 dataclasses_postinit.py:29:7: error[unresolved-attribute] Type `DC1` has no attribute `y`
-dataclasses_slots.py:56:1: error[unresolved-attribute] Type `<class 'DC5'>` has no attribute `__slots__`
-dataclasses_slots.py:57:1: error[unresolved-attribute] Type `DC5` has no attribute `__slots__`
 dataclasses_slots.py:66:1: error[unresolved-attribute] Type `<class 'DC6'>` has no attribute `__slots__`
 dataclasses_slots.py:69:1: error[unresolved-attribute] Type `DC6` has no attribute `__slots__`
 dataclasses_transform_class.py:60:8: error[missing-argument] No argument provided for required parameter `not_a_field` of bound method `__init__`
@@ -868,5 +866,5 @@
 typeddicts_usage.py:28:1: error[missing-typed-dict-key] Missing required key 'name' in TypedDict `Movie` constructor
 typeddicts_usage.py:28:18: error[invalid-key] Invalid key access on TypedDict `Movie`: Unknown key "title"
 typeddicts_usage.py:40:24: error[invalid-type-form] The special form `typing.TypedDict` is not allowed in type expressions. Did you mean to use a concrete TypedDict or `collections.abc.Mapping[str, object]` instead?
-Found 869 diagnostics
+Found 867 diagnostics
 WARN A fatal error occurred while checking some files. Not all project files were analyzed. See the diagnostics list above for details.

@thejchap thejchap force-pushed the thejchap/dataclass-slots branch from 3031c3f to ede543e Compare September 6, 2025 01:46
@github-actions
Copy link
Contributor

github-actions bot commented Sep 6, 2025

mypy_primer results

No ecosystem changes detected ✅
No memory usage changes detected ✅

@thejchap thejchap marked this pull request as ready for review September 6, 2025 01:57
@thejchap thejchap changed the title [ty] support slots=True for dataclasses [ty] initial support for slots=True in dataclasses Sep 6, 2025
@ntBre ntBre added the ty Multi-file analysis & type inference label Sep 6, 2025
Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is great! A couple of small points below.

Could you also add something like this test case to https://github.com/astral-sh/ruff/blob/main/crates/ty_python_semantic/resources/mdtest/instance_layout_conflict.md (it already passes on your branch!):

from dataclasses import dataclass

@dataclass(slots=True)
class F: ...

@dataclass(slots=True)
class G: ...

class H(F, G): ...  # fine because both classes have empty `__slots__`

@dataclass(slots=True)
class I:
    x: int

@dataclass(slots=True)
class J:
    y: int

class K(I, J): ...  # error: [instance-layout-conflict]

And something like this test case to https://github.com/astral-sh/ruff/blob/main/crates/ty_python_semantic/resources/mdtest/type_properties/is_disjoint_from.md (it also already passes on your branch!):

from dataclasses import dataclass
from ty_extensions import is_disjoint_from, static_assert

@dataclass(slots=True)
class F: ...

@dataclass(slots=True)
class G: ...

@dataclass(slots=True)
class I:
    x: int

@dataclass(slots=True)
class J:
    y: int

# A dataclass with empty `__slots__` is not disjoint from another dataclass with `__slots__`
static_assert(not is_disjoint_from(F, G))
static_assert(not is_disjoint_from(F, I))
static_assert(not is_disjoint_from(G, I))
static_assert(not is_disjoint_from(F, J))
static_assert(not is_disjoint_from(G, J))

# But two dataclasses with non-empty `__slots__` are disjoint
static_assert(is_disjoint_from(I, J))

@thejchap thejchap force-pushed the thejchap/dataclass-slots branch from ede543e to 6d1515c Compare September 7, 2025 17:08
Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@AlexWaygood AlexWaygood merged commit 08fcf7e into astral-sh:main Sep 7, 2025
38 checks passed
second-ed pushed a commit to second-ed/ruff that referenced this pull request Sep 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants