Skip to content
This repository has been archived by the owner on Nov 21, 2022. It is now read-only.

dataclasses integration / defer __match_args_required__? #79

Open
viridia opened this issue Jun 14, 2020 · 15 comments
Open

dataclasses integration / defer __match_args_required__? #79

viridia opened this issue Jun 14, 2020 · 15 comments
Labels
accepted Discussion leading to a final decision to include in the PEP fully pepped Issues that have been fully documented in the PEP

Comments

@viridia
Copy link
Collaborator

viridia commented Jun 14, 2020

I've added code to Brandt's reference implementation to support dataclasses as specified in the PEP. This causes the @dataclass decorator to generate a __match_args__ property for the target class.

However, my implementation is minimal, and leaves out a number of things that could have been done.

The various properties that @dataclass creates are controlled by two flags: one flag that is global to the class, and one that is per-field. So for example, there is an init flag that controls whether an __init__ method should be generated; there is another per-field init flag which determines whether a given field should be included in the constructor signature.

My implementation does not include either of these flags for __match_args__. It always generates a __match_args__ attribute, unless the class already has such an attribute defined; I see no reason not to generate it.

As to which fields are included in __match_args__, I simply include all of the fields that have the init flag set to True - in other words, if it's a constructor parameter, I also include it in __match_args__. Fields which are not constructor parameters must be matched by name.

However, I could envision a more flexible approach, in which there is a per-field match flag, which would default to the per-field init flag (which in turn defaults to True). Thus, if you didn't specify this flag, it would default to including all of the constructor params as match args, but you could also override this on a per-field basis.

(I'm also tempted to update my example to leverage dataclasses, although I would want to show how match works both with and without dataclasses.)

@viridia viridia added the unpeppable Doesn't need to be added to the PEP label Jun 14, 2020
@gvanrossum
Copy link
Owner

I'd want to know of a solid use case for that extra flag -- IOW KISS. When would you want to have a positional argument to __init__ not be allowable as a positional pattern argument, or vice versa? AFAIK there isn't even a way to indicate that an init field should always be passed as a keyword argument. (But I'm personally a very unsophisticated user of dataclasses, and it's been ages since I read the PEP.)

To show how it works using both dataclasses and regular classes you could leave BinaryOp a regular class but turn UnaryOp and VarExpr into dataclasses. BinaryOp has a precedence attribute that's not a parameter, so you'd have to define a __post_init__ method, and at that point it's hardly a win.

@viridia
Copy link
Collaborator Author

viridia commented Jun 14, 2020

Well, it's a two-way door in any case, we can always add it later if someone decides they need it. I'm fine with leaving things as-is.

@brandtbucher
Copy link
Collaborator

Do we have any plans for __match_args_required__ for dataclasses?

@gvanrossum
Copy link
Owner

I propose to leave that unset. Users wishing that feature can set it.

@brandtbucher
Copy link
Collaborator

The PEP says we set it. So either we should set it, or change the PEP!

@gvanrossum
Copy link
Owner

So set it if not already set. To 0, I suppose. What difference does make though?

@brandtbucher
Copy link
Collaborator

For dataclasses the __match_args_required__ includes all fields without a default value, or a default factory.

@gvanrossum
Copy link
Owner

I privately worry that will constrain us. While 'Point(0)' seems perhaps an odd shortcut for 'Point(0, _)', I am not so sure that we want to disallow 'Point(x=0)'.

@brandtbucher
Copy link
Collaborator

Well, we could just strike the line from the PEP. Like you said, anyone who wants to require args can set __match_args_required__ on the class manually.

I could go either way, honestly. The deconstruction signature will never be perfectly compatible with the constructor signature, but it does seem that we haven't found a real-world use-case where we're willing to set __match_args_required__... I mean, the PEP uses your exact example of a Point class to sell the feature.

So either we should choose to set it for named tuples and dataclasses, find a more compelling example for the PEP, or consider dropping it from the spec.

@gvanrossum
Copy link
Owner

What do others think? @Tobias-Kohn ?

@brandtbucher
Copy link
Collaborator

I'm slightly in favor of killing it off. Looking it up and validating it takes time and effort, and we haven't really found any good use cases.

Since we probably wouldn't add it to any built-in types, we could always add it back later with minimal disruption.

@brandtbucher
Copy link
Collaborator

Plus, I think it currently holds the world record for "most ridiculously long dunder".

@brandtbucher
Copy link
Collaborator

For some background, here's the comment that first suggested it:

#19 (comment)

Later, @ilevkivskyi said:

Anyway, you at least convinced me that your approach is extensible in the direction I want (i.e. __required_match_args__ can be added later without breaking backwards compatibility).

@gvanrossum
Copy link
Owner

So you propose to kill it completely? That sounds fine to me, we can add it to Rejected (or Postponed) ideas.

@brandtbucher brandtbucher added accepted Discussion leading to a final decision to include in the PEP needs more pep An issue which needs to be documented in the PEP and removed unpeppable Doesn't need to be added to the PEP labels Jun 15, 2020
@brandtbucher brandtbucher changed the title dataclasses integration dataclasses integration / defer __match_args_required__? Jun 15, 2020
@Tobias-Kohn
Copy link
Collaborator

I am also at most lukewarm towards the __match_args_required__ and am absolutely happy to remove it. @brandtbucher makes a couple of very good points, particularly that we only have a single use case so far.

@gvanrossum gvanrossum added fully pepped Issues that have been fully documented in the PEP and removed needs more pep An issue which needs to be documented in the PEP labels Jun 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
accepted Discussion leading to a final decision to include in the PEP fully pepped Issues that have been fully documented in the PEP
Projects
None yet
Development

No branches or pull requests

4 participants