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.) I agree that self-matching classes should absolutely allow keyword matches. I had no idea the PEP forbade it. _______________________________________________ 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/EKXKRZBJAUWVJVMF3MCNJA6I7HLLL26B/ Code of Conduct: http://python.org/psf/codeofconduct/