-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
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
Add a Dataclass abstract base class for instance checking and type annotations #102699
Comments
Thanks for opening this issue. I'm supportive of this idea -- I agree it would be quite helpful for typing. To give context for those who don't follow stuff that goes on at typeshed/typing_extensions: we recently changed how we annotate some I think Cc. @ericvsmith and @carljm for dataclasses. |
I see your point about And the function that currently checks dataclasses is called But |
Sure, but |
I don't have an issue with this. I think to some extent the dataclass design originally pushed in the direction of "this is just a utility to create ordinary classes, nobody should care that they were created by this particular utility." But in practice when you have a utility to create classes with a structured set of field metadata, people are going to find useful things to do with that field metadata, and in order to do that, they'll need to know which types have it. And this ship has long sailed, with the existence of free functions like So given that we already clearly support all of this, I don't see any reason we shouldn't make it a bit more ergonomic (and static type-checking friendly.) Would like to know what @ericvsmith thinks. |
If you're interested in the history of this, from my discussion with the attrs creator, he was strongly opposed to inheritance in Python. Like you say, that ship has long sailed now 😄 |
I agree with Hynek about inheritance :) IMO this proposal is mostly orthogonal to inheritance; it's about ergonomically detecting whether a type has dataclass-style field metadata, which is relevant regardless of whether anyone is inheriting anything. |
Yup, I was just providing some interesting history 😄 Glad to see there's so much agreement about having a base class. |
I think that adding such an interface would make concrete assumptions about the internals of a dataclass. Right now As far as I understand, |
Maybe we could just remove that from the proposal? In retrospect it was a mistake to add it. |
Typeshed's stub for the class will have to have the |
Okay, to put some flesh on the bones of this proposal: here's a PR showing what this could look like: |
I don't really see the point of reserving the Also, why use an abstract base class here, instead of a |
Other classes from third-party libraries that have dataclass-like semantics, and also synthesize As a concrete example: >>> from pydantic.dataclasses import dataclass
>>> @dataclass
... class Foo: ...
...
>>> Foo.__dataclass_fields__
{}
>>> import dataclasses
>>> dataclasses.is_dataclass(Foo)
True I think a
What would using a protocol get us here? The runtime implementation for For
Correct, but we need the |
Using a protocol and allowing subclassing would allow composition with other protocols, which in my opinion would be useful. It allows creating a function that takes as argument a value that both can be passed to asdict, and has some special attribute or method. (Keeping in mind that Python doesn't have intersections, and that the only way to compose protocols is by using subclassing). |
Would DataclassType make sense for name? |
Feature or enhancement
Add the class
dataclasses.Dataclass
thatdataclasses.is_dataclass
, and__init_subclass__
.(Edit: removed "has an attribute
__dataclass_fields__
for the purpose of type checking")Pitch
This class would simplify runtime type-checking of dataclasses:
and similarly
Besides being simpler, it would also allow combined instance checks like
isinstance(x, Dataclass | SomeOtherBase)
, which is arguably more Pythonic than the combined function calls above (marked "Previously").It would also allow users to annotate dataclasses using
Dataclass
ortype[Dataclass]
, which is currently impossible without reaching into protected areas of the typeshed.Inheritance could be blocked for now with a friendly error message (that perhaps tells you to use the decorator either directly or in a base class's
__init_subclass__
).Previous discussion
There's some discussion here: python/typing_extensions#115
@AlexWaygood
@JelleZijlstra
@henryiii
Linked PRs
dataclasses.DataclassLike
#102933The text was updated successfully, but these errors were encountered: