Skip to content

gh-102699: Add dataclasses.DataclassLike #102933

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

Closed
wants to merge 11 commits into from

Conversation

AlexWaygood
Copy link
Member

@AlexWaygood AlexWaygood commented Mar 22, 2023

Add dataclasses.DataclassLike, an abstract base class for dataclasses. Mainly useful for type-hinting. See the issue for a more complete rationale for why this class would be useful.

@AlexWaygood AlexWaygood requested a review from carljm March 22, 2023 21:27
@AlexWaygood AlexWaygood requested a review from ericvsmith as a code owner March 22, 2023 21:27
@AlexWaygood AlexWaygood added type-feature A feature request or enhancement stdlib Python modules in the Lib dir 3.12 only security fixes labels Mar 22, 2023
# __dataclass_fields__ here is really an "abstract class variable",
# but there's no good way of expressing that at runtime,
# so just make it a regular class variable with a dummy value
__dataclass_fields__ = {}
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need this? In my opinion, def __subclasshook__(cls, other): is enough.

For example, your own tests do not use this attribute.

Copy link
Member Author

@AlexWaygood AlexWaygood Mar 23, 2023

Choose a reason for hiding this comment

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

Without this attribute, the abstract base class for all dataclasses would not itself be considered a dataclass by the dataclasses internal machinery, which would be quite bizarre in my opinion:

>>> from dataclasses import *
>>> is_dataclass(DataclassLike)
True
>>> del DataclassLike.__dataclass_fields__
>>> is_dataclass(DataclassLike)
False

But you are correct that this currently isn't covered. I will add a test for this :)

Copy link
Member

Choose a reason for hiding this comment

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

But, is DataclassLike a dataclass? :)

You can have two opinions here.

Copy link
Member Author

Choose a reason for hiding this comment

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

The contract here is that "all classes for which is_dataclass evaluates to True shall be considered subclasses of DataclassLike. But DataclassLike is considered a subclass of DataclassLike (because all classes are considered subclasses of themselves in Python). So it would be very strange, in my opinion, for there to be one class (DataclassLike itself) where is_dataclass(x) evaluates to False but it's nonetheless considered a subclass of DataclassLike.

Copy link
Member Author

@AlexWaygood AlexWaygood Mar 23, 2023

Choose a reason for hiding this comment

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

Alternatively, I could make DataclassLike an actual dataclass, I suppose? Rather than "faking it". What do you think?

Copy link
Member Author

@AlexWaygood AlexWaygood Mar 23, 2023

Choose a reason for hiding this comment

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

Do you like it better after adad189? :)

@AlexWaygood
Copy link
Member Author

The feature freeze is fast approaching now, but here's why I haven't merged this yet:

  1. I don't want to do so without @ericvsmith's approval. Once this is added to dataclasses, it'll be hard to remove again.
  2. I'm not 100% sure adding this to the stdlib now is appropriate. @hauntsaninja is working on a useful_types package, to be published on PyPI, that would distribute useful types that we make common use of in typeshed. Once that package has been set up, it might be better to add DataclassLike to that library and wait for a bit, instead of adding it straight to the stdlib. That way, we can see if any major bugs or usability issues crop up before we add it to the stdlib.

@AlexWaygood
Copy link
Member Author

This protocol is now available in the third-party useful_types package, maintained by @hauntsaninja, @JelleZijlstra and myself. I'm closing this PR for now, until we see whether people find it useful.

@AlexWaygood AlexWaygood deleted the dataclass-protocol branch August 21, 2023 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.12 only security fixes awaiting merge stdlib Python modules in the Lib dir type-feature A feature request or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants