[ty] Support dataclass-transform field_specifiers#20888
Merged
Conversation
Contributor
Diagnostic diff on typing conformance testsChanges were detected when running ty on typing conformance tests--- old-output.txt 2025-10-16 13:58:15.685593376 +0000
+++ new-output.txt 2025-10-16 13:58:19.040608580 +0000
@@ -1,5 +1,5 @@
fatal[panic] Panicked at /home/runner/.cargo/git/checkouts/salsa-e6f3bb7c2a062968/ef9f932/src/function/execute.rs:402:17 when checking `/home/runner/work/ruff/ruff/typing/conformance/tests/aliases_type_statement.py`: `PEP695TypeAliasType < 'db >::value_type_(Id(d417)): execute: too many cycle iterations`
-fatal[panic] Panicked at /home/runner/.cargo/git/checkouts/salsa-e6f3bb7c2a062968/ef9f932/src/function/execute.rs:402:17 when checking `/home/runner/work/ruff/ruff/typing/conformance/tests/aliases_typealiastype.py`: `infer_definition_types(Id(16c43)): execute: too many cycle iterations`
+fatal[panic] Panicked at /home/runner/.cargo/git/checkouts/salsa-e6f3bb7c2a062968/ef9f932/src/function/execute.rs:402:17 when checking `/home/runner/work/ruff/ruff/typing/conformance/tests/aliases_typealiastype.py`: `infer_definition_types(Id(17443)): execute: too many cycle iterations`
_directives_deprecated_library.py:15:31: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `int`
_directives_deprecated_library.py:30:26: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `str`
_directives_deprecated_library.py:36:41: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `Self@__add__`
@@ -279,6 +279,8 @@
dataclasses_transform_converter.py:121:11: error[too-many-positional-arguments] Too many positional arguments to bound method `__init__`: expected 1, got 7
dataclasses_transform_converter.py:130:31: error[invalid-argument-type] Argument to function `model_field` is incorrect: Expected `(Literal[1], /) -> int`, found `def converter_simple(s: str) -> int`
dataclasses_transform_field.py:49:43: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `(...) -> @Todo(unsupported type[X] special form)`
+dataclasses_transform_field.py:64:16: error[unknown-argument] Argument `id` does not match any known parameter
+dataclasses_transform_field.py:75:1: error[missing-argument] No argument provided for required parameter `name`
dataclasses_transform_field.py:75:16: error[too-many-positional-arguments] Too many positional arguments: expected 0, got 1
dataclasses_transform_func.py:57:1: error[invalid-assignment] Object of type `Literal[3]` is not assignable to attribute `name` of type `str`
dataclasses_transform_func.py:61:6: error[unsupported-operator] Operator `<` is not supported for types `Customer1` and `Customer1`
@@ -288,6 +290,7 @@
dataclasses_transform_func.py:77:36: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `T@create_model_frozen`
dataclasses_transform_func.py:97:1: error[invalid-assignment] Property `id` defined in `Customer3` is read-only
dataclasses_transform_meta.py:60:36: error[unknown-argument] Argument `other_name` does not match any known parameter
+dataclasses_transform_meta.py:66:8: error[missing-argument] No arguments provided for required parameters `id`, `name`
dataclasses_transform_meta.py:66:18: error[too-many-positional-arguments] Too many positional arguments: expected 0, got 2
dataclasses_transform_meta.py:73:6: error[unsupported-operator] Operator `<` is not supported for types `Customer1` and `Customer1`
dataclasses_transform_meta.py:79:6: error[unsupported-operator] Operator `<` is not supported for types `Customer2` and `Customer2`
@@ -898,5 +901,5 @@
typeddicts_usage.py:28:17: 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 900 diagnostics
+Found 903 diagnostics
WARN A fatal error occurred while checking some files. Not all project files were analyzed. See the diagnostics list above for details. |
Contributor
|
61112be to
77f6650
Compare
Contributor
|
| Lint rule | Added | Removed | Changed |
|---|---|---|---|
invalid-argument-type |
0 | 52 | 0 |
missing-argument |
5 | 21 | 0 |
call-non-callable |
2 | 0 | 0 |
unresolved-attribute |
1 | 0 | 1 |
unused-ignore-comment |
1 | 0 | 0 |
| Total | 9 | 73 | 1 |
f2dca71 to
ef11297
Compare
sharkdp
commented
Oct 15, 2025
ef11297 to
2354319
Compare
sharkdp
commented
Oct 15, 2025
This comment was marked as resolved.
This comment was marked as resolved.
sharkdp
commented
Oct 15, 2025
AlexWaygood
reviewed
Oct 15, 2025
d2f18d7 to
9645d45
Compare
AlexWaygood
approved these changes
Oct 16, 2025
| reveal_type(alice.age) # revealed: int | None | ||
| ``` | ||
|
|
||
| ### For base-class-based transformers |
Member
There was a problem hiding this comment.
[insert "all your base are belong to us" joke]
Comment on lines
+695
to
+702
| fn from_flags(db: &'db dyn Db, flags: DataclassFlags) -> Self { | ||
| let dataclasses_field = known_module_symbol(db, KnownModule::Dataclasses, "field") | ||
| .place | ||
| .ignore_possibly_undefined() | ||
| .unwrap_or_else(Type::unknown); | ||
|
|
||
| Self::new(db, flags, vec![dataclasses_field].into_boxed_slice()) | ||
| } |
Member
There was a problem hiding this comment.
I am sort-of morbidly curious about what does happen to our inference if you try to define a dataclass, with dataclasses.field for one of the fields, and you're using a custom typeshed that doesn't have dataclasses.field in it. That might be an interesting test, but it's almost certainly not worth spending time on it right now 😄
dcreager
added a commit
that referenced
this pull request
Oct 16, 2025
…rable * origin/main: [ty] Support dataclass-transform `field_specifiers` (#20888) Bump 0.14.1 (#20925) Standardize syntax error construction (#20903) [`pydoclint`] Implement `docstring-extraneous-parameter` (`DOC102`) (#20376) [ty] Fix panic 'missing root' when handling completion request (#20917) [ty] Run file watching tests serial when using nextest (#20918) [ty] Add version hint for failed stdlib attribute accesses (#20909) More CI improvements (#20920) [ty] Check typeshed VERSIONS for parent modules when reporting failed stdlib imports (#20908)
dcreager
added a commit
that referenced
this pull request
Oct 17, 2025
* main: [ty] Prefer declared type for invariant collection literals (#20927) [ty] Don't track inferability via different `Type` variants (#20677) [ty] Use declared variable types as bidirectional type context (#20796) [ty] Avoid unnecessarily widening generic specializations (#20875) [ty] Support dataclass-transform `field_specifiers` (#20888) Bump 0.14.1 (#20925) Standardize syntax error construction (#20903) [`pydoclint`] Implement `docstring-extraneous-parameter` (`DOC102`) (#20376) [ty] Fix panic 'missing root' when handling completion request (#20917) [ty] Run file watching tests serial when using nextest (#20918) [ty] Add version hint for failed stdlib attribute accesses (#20909) More CI improvements (#20920) [ty] Check typeshed VERSIONS for parent modules when reporting failed stdlib imports (#20908)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add support for the
field_specifiersparameter ondataclass_transformdecorator calls.closes astral-sh/ty#1068
Conformance test results
All true positives ✔️
Ecosystem analysis
trio: this is the kind of change that I would expect from this PR. The code makes use of a dataclassOutcomewith a_unwrapped: bool = attr.ib(default=False, eq=False, init=False)field that is excluded from the__init__signature, so we now see a bunch of constructor-call-related errors going away.home-assistant/core: They have adomain: str = attr.ib(init=False, repr=False)field and then usedefaultattribute ondataclasses.Field[…]with a type ofdefault: _T | Literal[_MISSING_TYPE.MISSING], so we get those "Object of type_MISSING_TYPEis not callable" errors. I don't really understand how that is supposed to work. Even if_MISSING_TYPEwould be absent from that union, what does this try to call? pyright also issues an error and it doesn't seem to work at runtime? So this looks like a true positive?attrs: Similar here. There are some new diagnostics on code that tries to access.validatoron a field. This does work at runtime, but I'm not sure how that is supposed to type-check (without a custom plugin). pyright errors on this as well.aliasyetTest Plan
Updated tests.