[Python-ideas] Positional-only parameters

Steven D'Aprano steve at pearwood.info
Thu Mar 2 08:23:18 EST 2017


On Tue, Feb 28, 2017 at 10:17:31PM +0100, Victor Stinner wrote:

> My question is: would it make sense to implement this feature 
[positional only parameters]
> in Python directly? 

+0 on positional-only parameters.


> If yes, what should be the syntax? Use "/" marker?

I think that / makes a nice pun with * and is easy to remember.

I dislike the proposed double-leading-only underscore convention, as 
that makes the names look like *private* parameters the caller shouldn't 
provide at all. And it leads to confusion:

def function(__a, b, _c, * __d):
    ...

So __a is positional-only, b could be positional or keyword, _c is 
private, and __d is keyword-only but just happens to start with two 
underscores. Yuck.

I think that [...] is completely unacceptable. It is a very common 
convention to use square brackets to flag optional arguments when 
writing function signatures in documentation, e.g.:

    Help on class zip in module builtins:

    class zip(object)
     |  zip(iter1 [,iter2 [...]]) --> zip object


It would be confusing to have [...] have syntactic meaning different to 
that convention.


> Use the @positional() decorator?

I suppose a positional() decorator would be useful for backporting, but 
I wouldn't want it to be the One Obvious Way to get positional 
arguments.


> By the way, I read that "/" marker is unknown by almost all Python
> developers, 

Of course it is not well known -- it is only new, and not legal syntax 
yet! Unless they are heavily using Argument Clinic they probably won't 
recognise it.


> and [...] syntax should be preferred, but
> inspect.signature() doesn't support this syntax. Maybe we should fix
> signature() and use [...] format instead?

-1


> Replace "replace(self, old, new, count=-1, /)" with "replace(self,
> old, new[, count=-1])" (or maybe even not document the default
> value?).

That isn't right. It would have to be:

replace([self, old, new, count=-1])

if all of the arguments are positional-only. But that makes it look like 
they are all optional! A very strong -1 to this.


> Python 3.5 help (docstring) uses "S.replace(old, new[, count])".

Should be:

S.replace(old, new[, count], /)

which shows that all three arguments are positional only, but only count 
is optional.



-- 
Steve


More information about the Python-ideas mailing list