-
Couldn't load subscription status.
- Fork 1.6k
[ty] Support dataclass-transform field_specifiers
#20888
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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. |
|
61112be to
77f6650
Compare
|
| 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
ef11297 to
2354319
Compare
This comment was marked as resolved.
This comment was marked as resolved.
d2f18d7 to
9645d45
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
| reveal_type(alice.age) # revealed: int | None | ||
| ``` | ||
|
|
||
| ### For base-class-based transformers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[insert "all your base are belong to us" joke]
| 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()) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 😄
…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)
* 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)
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.