On Fri, Apr 2, 2021 at 3:38 AM Mark Shannon <m...@hotpy.org> wrote: > Hi Brandt, > > On 02/04/2021 7:19 am, Brandt Bucher wrote: > > Guido van Rossum wrote: > >> Well, now I have egg on my face, because the current implementation > does reject multiple occurrences of the same identifier in __match_args__. > We generate an error like "TypeError: C() got multiple sub-patterns for > attribute 'a'". However, I cannot find this uniqueness requirement in PEP > 634, so I think it was a mistake to implement it. > >> > >> Researching this led me to find another issue where PEP 634 and the > implementation differ, but this time it's the other way around: PEP 634 > says about types which accept a single positional subpattern (int(x), > str(x) etc.) "for these types no keyword patterns are accepted." Mark's > example `case int(real=0, imag=0):` makes me think this requirement is > wrong and I would like to amend PEP 634 to strike this requirement. > Fortunately, this is not what is implemented. E.g. `case int(1, real=1):` > is accepted and works, as does `case int(real=0):`. > >> > >> Calling out Brandt to get his opinion. And thanks to Mark for finding > these! > > > > The current implementation will reject any attribute being looked up > more than once, by position *or* keyword. It's actually a bit tricky to do, > which is why the `MATCH_CLASS` op is such a beast... it needs to look up > positional and keyword attributes all in one go, keeping track of > everything it's seen and checking for duplicates. > > > > I believe this behavior is a holdover from PEP 622: > > > >> The interpreter will check that two match items are not targeting the > same attribute, for example `Point2d(1, 2, y=3)` is an error. > > > > (https://www.python.org/dev/peps/pep-0622/#overlapping-sub-patterns) > > > > PEP 634 explicitly disallows duplicate keywords, but as far as I can > tell it says nothing about duplicate `__match_args__` or keywords that also > appear in `__match_args__`. It looks like an accidental omission during the > 622 -> 634 rewrite. > > > > (I guess I figured that if somebody matches `Spam(foo, y=bar)`, where > `Spam.__match_args__` is `("y",)`, that's probably a bug in the user's > code. Ditto for `Spam(y=foo, y=bar)` and `Spam(foo, bar)` where > `Spam.__match_args__` is `("y", "y")` But it's not a hill I'm willing to > die on.) > > Repeated keywords do seem likely to be a bug. >
Agreed. But as I sketched in a previous email I think duplicates ought to be acceptable in __match_args__. At the very least we should align the PEP and the implementation here, by adjusting one or the other. Most checks are cheap though. > Checking for duplicates in `__match_args__` can be done at class > creation time, Hm, what about dynamic updates to __match_args__? I've done that in the REPL. > and checking for duplicates in the pattern can be done at > compile time. > I'd prefer not to do that check at all. > So how about explicitly disallowing those, but not checking that the > intersection of `__match_args__` and keywords is empty? > We would get most of the error checking without the performance impact. > +1 on the latter (not checking the intersection). > > > > > I agree that self-matching classes should absolutely allow keyword > matches. I had no idea the PEP forbade it. > > PEP 634 allows it. PEP 653 currently forbids it, mainly for consistency > reasons. > The purpose of self-matching is to prevent deconstruction, so it seems > inconsistent to allow it for keyword arguments. > The purpose of self-matching is user convenience. It should be seen as a shorthand for the code fragment in PEP 634 showing how to do this for any class. > Are there are any use-cases? > The test-case `int(real=0+0j, imag=0-0j)` is contrived, > but I'm struggling to come up with less contrived examples for any of > float, list, dict, tuple, str. > There could be a subclass that adds an attribute. That's still contrived though. But if we start supporting this for *general* classes we should allow combining it with keywords/attributes. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/EWAO6PEFCNT3AXL6IKOIPYMWT3KHD7ZL/ Code of Conduct: http://python.org/psf/codeofconduct/