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/

Reply via email to