-
Notifications
You must be signed in to change notification settings - Fork 64
Adding __match_args__ is backwards incompatible #104
Comments
Consider #100 ? Needs no For the possible reason that you rejected this...
With #100, by providing a utility library: from patma import PNoKwargs, PFixedPosArg
class MyClass:
... # implementations
@PFixedPosArg(1)
@PNoKwargs
def __match__(cls, inst):
return inst which is the same as class MyClass:
... # implementations
def __match__(cls, inst, argc, kwargs):
assert not kwargs, f"pattern {cls} expects no keyword arguments, got {kwargs}."
assert argc == 1, f"pattern {cls} expects 1 positional arguments, got {argc}."
return (inst, ) |
@thautwarm, please let it go. Your suggestion is off-topic, has already been rejected twice, and does not solve this issue being addressed here. |
Okay, but could you please show this?:
|
The current protocol is perfectly capable of accommodating this concern: we would just need to remove the nice default behavior which matches the proxy when Please follow your own advice in the linked issue:
|
Idea: drop the default behavior and instead add it back just to select standard objects like str and int. |
Yeah, that could work (not a huge fan of more special cases, but I see the pragmatism). I think no matter what, we will need to drop the default behavior. But it's generally useful enough (and hard enough to get right as a hack) that I'd like to provide a fairly frictionless way of getting it back for user-defined classes, if it isn't too hard. Perhaps |
I'm not sure I understand the issue, could one of you give a brief explanation? I tried the link but it didn't send me to the correct place. |
Basically, the default |
Got it. I suspect that adding an explicit match_args to every built-in non-reference type is probably the cleaner answer in the long run. I think the motivation for the clever default is partly laziness (in the Perl sense), it avoids having to go and update a whole bunch of value types - but the downside is that you now have a large blast radius for any unforeseen side effects of this new behavior. Probably better to use a scalpel... |
Clairfy: This cannot get avoided because users can arbitrarily decide the first pos arg I saw you all constantly talking about |
I agree, too, that this is probably the most reasonable approach. Pablo's example seems to highlight that this is mainly an issue with "composite" types. As long as we stick to value types for the default behaviour, I think we should be fine. And, luckily, there are not too many of those. |
Some analyses:
|
For most classes the default behavior is not very useful. It works for str(x) and int(x) because those have in fact behavior where str(x) == x etc. But for user classes that behavior is not very common. |
I agree that it's not correct for most classes, but still I think it makes sense for many. I'll link issue #58 since there was a short discussion on this. The trivial use case of It's not a huge deal, but it does feel odd to restrict this magic to select built-in types. If we don't like |
I'm willing to let this go if others feel differently, though. |
I really like to idea of writing stuff like The thing that really sold me on #58 was that it just works out of the box for built-in types (where appropriate). But I can happily live without having similar behaviour (by default) for custom classes. |
Okay, let's kill the default behavior and build a list of classes that will support it instead. I'm tempted to just say "all types in
|
That looks right. |
I imagine we raise |
Why? |
Never mind, I see now that just using the subclass's |
By the way, do we still want to accept We could even use it to enable the old default behavior? |
You’re right, it would remove a bunch of tedious language from the PEP. I think this is ready for an update to the PEP then? |
Sorry, I updated my comment with the last line. Don't know if you saw. |
Let’s not introduce a shortcut for the old default. |
Okay, I'll update the PEP and implementation. |
Possibly |
Not type, type(t) != t. And complex has two attributes, real and imag, so that would be very confusing — does complex(0) match 0j or any complex with real==0 ? |
Sorry, just to clarify: I should remove Funny, |
I think complex should not be given positional args at all, to avoid confusion. Same for type. |
Pablo pointed out that adding this is usually backwards incompatible. Maybe we need to rethink the special casing of object(c)?
https://mail.python.org/archives/list/[email protected]/message/STJSSAETMTUY7FK5AE53IM73Z2WORNYN/
The text was updated successfully, but these errors were encountered: