[3.9] bpo-37116: Use PEP 570 syntax for positional-only parameters. by serhiy-storchaka · Pull Request #12620 · python/cpython (original) (raw)
I examined the necessity of the proposed '/' insertions in different cases divided first into whether the insertion was before **kwds or *args and secondly whether an original *args was expanded. For insertion before *args, finer distinctions seem relevant. When *args was expanded, I considered reasons it was used instead of explicit naming. In the following, ''self', 'args, and 'kwds' encompass equivalent words (such as 'cls' for 'self'). 'Other' excludes 'self' or 'cls'. Counts might be off, but are close. I hope there are no logic errors. and few typos.
Insertions before **kwds(20).
A(10): no *args. self, [other(s)],**kwds
==> self, [other(s)],/,**kwds
.
Inserting '/' is not necessary. Passing self and other required ars by name is no problem as long as a call follows the standard rule that if an arg is passed by name, following args must be also. Passing self is only possible if the method is called on the class, which is almost never.
B(10): expansion. *args,**kwds
==> self, other,/**kwds
.
*args is obviously inferior to the explicit expansion and delays detection of buggy calls, but it forces self and other to be called positionally. If this was intentional, then '/' should be added after expansion to maintain that aspect of the signature. To me, the result beats the original.
Insertions before *args(47)
The issue here is that named parameters before *args must be passed positionally unless nothing is passed to go into args. If any named parameters are passed by name and any objects are passed that belong in args, some will be bound to the previous parameters and a double-binding error raised. I think 'X must be passed by position' is clearer than 'X has two bindings' (where did the second come from?). I also think 'X must always be passed by position' is clearer than 'X must be passed by position except when nothing is passed for args'.
No expansion (37)
C(14): self,*args
==> self,/,*args
.
Need we add '/' to catch the obscure possibility of passing self by name when the method is called on the class and additional args are passed. A double binding error would be raised anyway.
D(17): self,other(s),*args
==> self,others(s),/,*args
.
E(6): other,*args
==> other,/,*args
.
These are more likely for people to get wrong.
Expansion(10)
F(4): *args
==> self,/,*args
. Treat same as C.
G(3) *args
==> self,other,/,*args
. Treat same as D.
H(2) self,*args
==> self,other,/,*args
. Treat same as D.