[ty] Implement DataClassInstance protocol for dataclasses. (#18018)

Fixes: https://github.com/astral-sh/ty/issues/92

## Summary

We currently get a `invalid-argument-type` error when using
`dataclass.fields` on a dataclass, because we do not synthesize the
`__dataclass_fields__` member.

This PR fixes this diagnostic.

Note that we do not yet model the `Field` type correctly. After that is
done, we can assign a more precise `tuple[Field, ...]` type to this new
member.

## Test Plan
New mdtest.

---------

Co-authored-by: David Peter <mail@david-peter.de>
This commit is contained in:
Abhijeet Prasad Bodas 2025-05-13 14:01:26 +05:30 committed by GitHub
parent 0ae07cdd1f
commit 68b0386007
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 47 additions and 5 deletions

View file

@ -616,6 +616,25 @@ reveal_type(C.__init__) # revealed: (field: str | int = int) -> None
To do
## `dataclass.fields`
Dataclasses have `__dataclass_fields__` in them, which makes them a subtype of the
`DataclassInstance` protocol.
Here, we verify that dataclasses can be passed to `dataclasses.fields` without any errors, and that
the return type of `dataclasses.fields` is correct.
```py
from dataclasses import dataclass, fields
@dataclass
class Foo:
x: int
reveal_type(Foo.__dataclass_fields__) # revealed: dict[str, Field[Any]]
reveal_type(fields(Foo)) # revealed: tuple[Field[Any], ...]
```
## Other special cases
### `dataclasses.dataclass`