Re: [Python-ideas] Positional-only parameters

2018-09-10 Thread Abe Dillon
[Cameron Simpson]

> I've been writing quite a few functions lately where it is reasonable for
> a
> caller to want to pass arbitrary keyword arguments, but where I also want
> some
> additional parameters for control purposes.


I've run into this before and use the trailing '_' convention for names:

def update(self, where_, **column_vals): ...

Because such names are **probably** never going to show up. But, of course;
if such
a name were actually used for a column, it would be a fantastically hard
bug to find!

On Thu, Sep 6, 2018 at 11:01 PM Cameron Simpson  wrote:

> On 01Mar2017 21:25, Serhiy Storchaka  wrote:
> >On 28.02.17 23:17, Victor Stinner wrote:
> >>My question is: would it make sense to implement this feature in
> >>Python directly? If yes, what should be the syntax? Use "/" marker?
> >>Use the @positional() decorator?
> >
> >I'm strongly +1 for supporting positional-only parameters. The main
> >benefit to me is that this allows to declare functions that takes
> >arbitrary keyword arguments like Formatter.format() or
> >MutableMapping.update(). Now we can't use even the "self" parameter
> >and need to use a trick with parsing *args manually. This harms clearness
> and
> >performance.
>
> I was a mild +0.1 on this until I saw this argument; now I am +1 (unless
> there's some horrible unforseen performance penalty).
>
> I've been writing quite a few functions lately where it is reasonable for
> a
> caller to want to pass arbitrary keyword arguments, but where I also want
> some
> additional parameters for control purposes. The most recent example was
> database related: functions accepting arbitrary keyword arguments
> indicating
> column values.
>
> As a specific example, what I _want_ to write includes this method:
>
>   def update(self, where, **column_values):
>
> Now, because "where" happens to be an SQL keyword it is unlikely that
> there
> will be a column of that name, _if_ the database is human designed by an
> SQL
> person. I have other examples where picking a "safe" name is harder. I can
> even
> describe scenarios where "where" is plausible: supposing the the database
> is
> generated from some input data, perhaps supplied by a CSV file (worse, a
> CSV
> file that is an export of a human written spreadsheet with a "Where"
> column
> header).  That isn't really even made up: I've got functions whose purpose
> is
> to import such spreadsheet exports, making namedtuple subclasses
> automatically
> from the column headers.
>
> In many of these situations I've had recently positional-only arguments
> would
> have been very helpful. I even had to bugfix a function recently where a
> positional argument was being trouced by a keyword argument by a caller.
>
> Cheers,
> Cameron Simpson 
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2018-09-10 Thread Abe Dillon
That looks great to me! I also think the '/' syntax looks fine and the pun
works. If part of the motivation for position-only arguments was better
performance and that motivation still holds water, then it makes sense to
allow Python to support that optimization, but I would be happy with just a
decorator too.

I definitely DON'T like the double-underscore. On top of all the other
complaints, I think it's more prone to break code. It's also more ugly than
'/' IMHO.

‪On Thu, Mar 2, 2017 at 5:10 AM ‫אלעזר‬‎  wrote:‬

> Here's a proof-of-concept for the decorator. It does not address the issue
> of passing aliases to positional arguments to **kwargs - I guess this
> requires changes in the CPython's core.
>
> (Sorry about the coloring, that's how it's pasted)
>
> from inspect import signature, Parameter
> from functools import wraps
>
>
> def positional_only(n):
> def wrap(f):
> s = signature(f)
> params = list(s.parameters.values())
> for i in range(n):
> if params[i].kind != Parameter.POSITIONAL_OR_KEYWORD:
> raise TypeError('{} has less than {} positional 
> arguments'.format(f.__name__, n))
> params[i] = params[i].replace(kind=Parameter.POSITIONAL_ONLY)
> f.__signature__ = s.replace(parameters=params)
> @wraps(f)
> def inner(*args, **kwargs):
> if len(args) < n:
> raise TypeError('{} takes at least {} positional 
> arguments'.format(f.__name__, n))
> return f(*args, **kwargs)
> return inner
> return wrap
>
>
> @positional_only(2)
> def f(a, b, c):
> print(a, b, c)
>
>
> help(f)
> # f(a, b, /, c, **kwargs)
>
> f(1, 2, c=2)
>
> # f(1, b=2, c=3)
> # TypeError: f takes at least 2 positional arguments
>
>
> @positional_only(3)
> def g(a, b, *, c):
> print(a, b, c)
>
> # TypeError: g has less than 3 positional arguments
>
> Elazar
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2018-09-06 Thread Yury Selivanov
On Fri, Sep 7, 2018 at 12:31 AM Anders Hovmöller  wrote:
>
> Yury,
>
> I’m sorry if that came off badly, I was not attempting to be snarky. Text is 
> hard and I know I’m not good in emails but rereading the text below I 
> honestly can’t see why my honest attempt at describing my experience can be 
> considered snarky.
>
> I haven’t sought out to discuss positional only parameters, this is something 
> that has just come up in conversation from time to time over the last few 
> years and this has been the response.
>
> If you would explain how you interpreted my mail in this way I would of 
> course be thankful but I also don’t want to take more of your time.

Sure.  (If you choose to reply to this email please do that off-list.)

IMHO your email lacks substance, uses rather strong words like
"disgust" and "disbelief", and ends with "I don't think that's a good
look for Python :P" phrase that doesn't help you to make any point.
You re-surfaced a pretty old email thread where a number of core
developers explained their position and listed quite a few arguments
for having positional-only arguments.  You, on the other hand, didn't
add a lot to the discussion except your own opinion with no serious
arguments to support it.

Please don't feel discouraged from posting to python-ideas though,
just try to keep a higher signal-to-noise ratio. ;)

Yury
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2018-09-06 Thread Cameron Simpson

On 01Mar2017 21:25, Serhiy Storchaka  wrote:

On 28.02.17 23:17, Victor Stinner wrote:

My question is: would it make sense to implement this feature in
Python directly? If yes, what should be the syntax? Use "/" marker?
Use the @positional() decorator?


I'm strongly +1 for supporting positional-only parameters. The main 
benefit to me is that this allows to declare functions that takes 
arbitrary keyword arguments like Formatter.format() or 
MutableMapping.update(). Now we can't use even the "self" parameter 
and need to use a trick with parsing *args manually. This harms clearness and 
performance.


I was a mild +0.1 on this until I saw this argument; now I am +1 (unless 
there's some horrible unforseen performance penalty).


I've been writing quite a few functions lately where it is reasonable for a 
caller to want to pass arbitrary keyword arguments, but where I also want some 
additional parameters for control purposes. The most recent example was 
database related: functions accepting arbitrary keyword arguments indicating 
column values.


As a specific example, what I _want_ to write includes this method:

 def update(self, where, **column_values):

Now, because "where" happens to be an SQL keyword it is unlikely that there 
will be a column of that name, _if_ the database is human designed by an SQL 
person. I have other examples where picking a "safe" name is harder. I can even 
describe scenarios where "where" is plausible: supposing the the database is 
generated from some input data, perhaps supplied by a CSV file (worse, a CSV 
file that is an export of a human written spreadsheet with a "Where" column 
header).  That isn't really even made up: I've got functions whose purpose is 
to import such spreadsheet exports, making namedtuple subclasses automatically 
from the column headers.


In many of these situations I've had recently positional-only arguments would 
have been very helpful. I even had to bugfix a function recently where a 
positional argument was being trouced by a keyword argument by a caller.


Cheers,
Cameron Simpson 
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2018-09-06 Thread Yury Selivanov
On Thu, Sep 6, 2018 at 10:57 PM Anders Hovmöller  wrote:
[..]
> I don't think that's a good look for Python :P

Anders,

Discussing something privately with "a few people", posting snarky
conclusions, and giving baseless recommendations isn't how we strive
to make decisions in Python.  Please refrain from posting in this
manner to python-ideas and python-dev, as emails written this way are
simply distracting and borderline disturbing.

Thanks,
Yury
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2018-09-06 Thread Anders Hovmöller
I think it makes more sense to remove the concept of positional only 
parameters by slowly fixing the standard library. I've discussed the 
existence of positional only with a few people and their response falls in 
to some basic categories:

- disgust
- disbelief
- bargaining (it's not very common right?! in fact yes it is)

I don't think that's a good look for Python :P
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2017-03-02 Thread Victor Stinner
I am thinking at writing a PEP, yes. I need time to think about it, find
all corner cases. Maybe also include something for "optional parameter
without default value".

Don't expect it soon, I have some pending work to finish before :-)

Victor

Le 2 mars 2017 7:16 PM, "Brett Cannon"  a écrit :

> It seems all the core devs who have commented on this are in the positive
> (Victor, Yury, Ethan, Yury, Guido, Terry, and Steven; MAL didn't explicitly
> vote). So to me that suggests there's enough support to warrant writing a
> PEP. Are you up for writing it, Victor, or is someone else going to write
> it?
>
> On Tue, 28 Feb 2017 at 13:18 Victor Stinner 
> wrote:
>
>> Hi,
>>
>> For technical reasons, many functions of the Python standard libraries
>> implemented in C have positional-only parameters. Example:
>> ---
>> $ ./python
>> Python 3.7.0a0 (default, Feb 25 2017, 04:30:32)
>> >>> help(str.replace)
>> replace(self, old, new, count=-1, /)   # <== notice "/" at the end
>> ...
>> >>> "a".replace("x", "y")  # ok
>> 'a'
>>
>> >>> "a".replace(old="x", new="y")   # ERR!
>> TypeError: replace() takes at least 2 arguments (0 given)
>> ---
>>
>> When converting the methods of the builtin str type to the internal
>> "Argument Clinic" tool (tool to generate the function signature,
>> function docstring and the code to parse arguments in C), I asked if
>> we should add support for keyword arguments in str.replace(). The
>> answer was quick: no! It's a deliberate design choice.
>>
>> Quote of Yury Selivanov's message:
>> """
>> I think Guido explicitly stated that he doesn't like the idea to
>> always allow keyword arguments for all methods. I.e. `str.find('aaa')`
>> just reads better than `str.find(needle='aaa')`. Essentially, the idea
>> is that for most of the builtins that accept one or two arguments,
>> positional-only parameters are better.
>> """
>> http://bugs.python.org/issue29286#msg285578
>>
>> I just noticed a module on PyPI to implement this behaviour on Python
>> functions:
>>
>>https://pypi.python.org/pypi/positional
>>
>> My question is: would it make sense to implement this feature in
>> Python directly? If yes, what should be the syntax? Use "/" marker?
>> Use the @positional() decorator?
>>
>> Do you see concrete cases where it's a deliberate choice to deny
>> passing arguments as keywords?
>>
>> Don't you like writing int(x="123") instead of int("123")? :-) (I know
>> that Serhiy Storshake hates the name of the "x" parameter of the int
>> constructor ;-))
>>
>> By the way, I read that "/" marker is unknown by almost all Python
>> developers, and [...] syntax should be preferred, but
>> inspect.signature() doesn't support this syntax. Maybe we should fix
>> signature() and use [...] format instead?
>>
>> Replace "replace(self, old, new, count=-1, /)" with "replace(self,
>> old, new[, count=-1])" (or maybe even not document the default
>> value?).
>>
>> Python 3.5 help (docstring) uses "S.replace(old, new[, count])".
>>
>> Victor
>> ___
>> Python-ideas mailing list
>> Python-ideas@python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] Positional-only parameters

2017-03-02 Thread Brett Cannon
It seems all the core devs who have commented on this are in the positive
(Victor, Yury, Ethan, Yury, Guido, Terry, and Steven; MAL didn't explicitly
vote). So to me that suggests there's enough support to warrant writing a
PEP. Are you up for writing it, Victor, or is someone else going to write
it?

On Tue, 28 Feb 2017 at 13:18 Victor Stinner 
wrote:

> Hi,
>
> For technical reasons, many functions of the Python standard libraries
> implemented in C have positional-only parameters. Example:
> ---
> $ ./python
> Python 3.7.0a0 (default, Feb 25 2017, 04:30:32)
> >>> help(str.replace)
> replace(self, old, new, count=-1, /)   # <== notice "/" at the end
> ...
> >>> "a".replace("x", "y")  # ok
> 'a'
>
> >>> "a".replace(old="x", new="y")   # ERR!
> TypeError: replace() takes at least 2 arguments (0 given)
> ---
>
> When converting the methods of the builtin str type to the internal
> "Argument Clinic" tool (tool to generate the function signature,
> function docstring and the code to parse arguments in C), I asked if
> we should add support for keyword arguments in str.replace(). The
> answer was quick: no! It's a deliberate design choice.
>
> Quote of Yury Selivanov's message:
> """
> I think Guido explicitly stated that he doesn't like the idea to
> always allow keyword arguments for all methods. I.e. `str.find('aaa')`
> just reads better than `str.find(needle='aaa')`. Essentially, the idea
> is that for most of the builtins that accept one or two arguments,
> positional-only parameters are better.
> """
> http://bugs.python.org/issue29286#msg285578
>
> I just noticed a module on PyPI to implement this behaviour on Python
> functions:
>
>https://pypi.python.org/pypi/positional
>
> My question is: would it make sense to implement this feature in
> Python directly? If yes, what should be the syntax? Use "/" marker?
> Use the @positional() decorator?
>
> Do you see concrete cases where it's a deliberate choice to deny
> passing arguments as keywords?
>
> Don't you like writing int(x="123") instead of int("123")? :-) (I know
> that Serhiy Storshake hates the name of the "x" parameter of the int
> constructor ;-))
>
> By the way, I read that "/" marker is unknown by almost all Python
> developers, and [...] syntax should be preferred, but
> inspect.signature() doesn't support this syntax. Maybe we should fix
> signature() and use [...] format instead?
>
> Replace "replace(self, old, new, count=-1, /)" with "replace(self,
> old, new[, count=-1])" (or maybe even not document the default
> value?).
>
> Python 3.5 help (docstring) uses "S.replace(old, new[, count])".
>
> Victor
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] Positional-only parameters

2017-03-02 Thread Victor Stinner
2017-03-02 14:23 GMT+01:00 Steven D'Aprano :
>> 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.

Oh, I didn't notice the weird count parameter: positional-only, but no
default value?

I would prefer to avoid weird parameters and use a syntax which can be
written in Python, like:

   def replace(self, old, new, /, count=-1): ...

When a function has more than 3 parameters, I like the ability to pass
arguments by keyword for readability:

   "xxx".replace("x", "y", count=2)

It's more explicit than:

   "xxx".replace("x", "y", 2)

By the way, I proposed once to convert open() parameters after
filename and mode to keyword-only arguments, but Guido didn't want to
break the backward compatibility ;-)

   open(filename, mode, *, buffering=-1, ...)

Victor
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2017-03-02 Thread Victor Stinner
2017-03-01 21:52 GMT+01:00 Terry Reedy :
> + 1 also. When people write a Python equivalent of a built-in function for
> documentation or teaching purposes, they should be able to exactly mimic the
> API.

Yeah, Serhiy said basically the same thing: it's doable, but complex
without builtin support for positional-only arguments.

I dislike subtle differences between C and Python, and positional-only
is a major difference since it has a very visible effect on the API.

After having used PHP for years, I really enjoyed Python keyword
arguments and default values. I was very happy to not have to
"reimplement" the "keyword arguments with default values" feature in
each function (*).

Basically, I would like the same thing for positional-only arguments :-)

(*) Example (found on the Internet) of PHP code pattern for keywords, enjoy ;-)

function doSomething($arguments = array()) {
// set defaults
$arguments = array_merge(array(
"argument" => "default value",
), $arguments);

var_dump($arguments);
}

Victor
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2017-03-02 Thread Steven D'Aprano
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
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2017-03-02 Thread אלעזר
Here's a proof-of-concept for the decorator. It does not address the issue
of passing aliases to positional arguments to **kwargs - I guess this
requires changes in the CPython's core.

(Sorry about the coloring, that's how it's pasted)

from inspect import signature, Parameter
from functools import wraps


def positional_only(n):
def wrap(f):
s = signature(f)
params = list(s.parameters.values())
for i in range(n):
if params[i].kind != Parameter.POSITIONAL_OR_KEYWORD:
raise TypeError('{} has less than {} positional
arguments'.format(f.__name__, n))
params[i] = params[i].replace(kind=Parameter.POSITIONAL_ONLY)
f.__signature__ = s.replace(parameters=params)
@wraps(f)
def inner(*args, **kwargs):
if len(args) < n:
raise TypeError('{} takes at least {} positional
arguments'.format(f.__name__, n))
return f(*args, **kwargs)
return inner
return wrap


@positional_only(2)
def f(a, b, c):
print(a, b, c)


help(f)
# f(a, b, /, c, **kwargs)

f(1, 2, c=2)

# f(1, b=2, c=3)
# TypeError: f takes at least 2 positional arguments


@positional_only(3)
def g(a, b, *, c):
print(a, b, c)

# TypeError: g has less than 3 positional arguments

Elazar
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] Positional-only parameters

2017-03-02 Thread Ethan Furman

On 03/01/2017 11:41 PM, Stephan Houben wrote:


I have a slight variant of the decorator proposal.
Rather than specify a count, let the decorator implement the typeshed dunder 
convention:

@positional_only
 def replace(self, __old, __new, count=-1):

(I imagine this decorator would also treat "self" as position_only,
so no need for __self.)

Pros:
1. Consistent with the typeshed convention.


Only a pro if you like that convention.  ;)


2. Avoids a count.
3. Strictly opt-in, so hopefully keeps those @#?! underscore preservationists 
from picketing my lawn (again!).


Using a decorator is also strictly opt-in.

Oh, and did someone say it was time for the protest?

[--]   [--]
[  ]   [  ]
[ NO MORE UNDERSCORES! ]   [ NO MORE UNDERSCORES! ]
[  ]   [  ]
[--]   [--]
  | | | |
  | | | |
  | | | |
  | | | |
  |-| |-|

--
~Ethan~
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2017-03-01 Thread Chris Barker
On Wed, Mar 1, 2017 at 2:16 PM, אלעזר  wrote:

> I like the idea, but I wanted to note that since it has no meaning from
> the point of view of the defined function, it can be done with a magic
> decorator, so new syntax is not required:
>
> @positional_only[:4]
> def replace(self, old, new, count=-1):
> ...
>

I"m confused, what does the [:4] mean?

if you want old and new to be positional only, wouldn't it be something
like:

@positional_only(3)
def replace(self, old, new, count=-1):
...

i.e. the first three parameters are positional only.

and why indexing/slice syntax???

+! on the idea -- still on the fence about syntax.

-CHB


-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR(206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115   (206) 526-6317   main reception

chris.bar...@noaa.gov
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] Positional-only parameters

2017-03-01 Thread אלעזר
On Wed, Mar 1, 2017 at 9:26 PM Serhiy Storchaka  wrote:

> On 28.02.17 23:17, Victor Stinner wrote:
> > My question is: would it make sense to implement this feature in
> > Python directly? If yes, what should be the syntax? Use "/" marker?
> > Use the @positional() decorator?
>
> 


> The problem with the "/" marker is that it looks ugly. There was an
> excuse for the "*" marker -- it came from omitting the name in "*args".
> The "*" prefix itself means an iterable unpacking, but "/" is not used
> neither as prefix nor suffix.
>

I like the idea, but I wanted to note that since it has no meaning from the
point of view of the defined function, it can be done with a magic
decorator, so new syntax is not required:

@positional_only[:4]
def replace(self, old, new, count=-1):
...

It may ease googling and backporting, by defining positional_only[slice] to
be the identity function.

Elazar
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] Positional-only parameters

2017-03-01 Thread MRAB

On 2017-03-01 21:32, Ethan Furman wrote:

On 03/01/2017 11:53 AM, Guido van Rossum wrote:


FWIW in typeshed we've started using double leading underscore as a convention 
for positional-only parameters, e.g. here:

https://github.com/python/typeshed/blob/master/stdlib/3/builtins.pyi#L936


I would much rather have a single '/' to denote where positional-only ends, 
than have multiple leading '__'.


+1

This also not clear what would happen if some of the parameters had the 
leading underscores and others didn't.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2017-03-01 Thread Ethan Furman

On 03/01/2017 11:53 AM, Guido van Rossum wrote:


FWIW in typeshed we've started using double leading underscore as a convention 
for positional-only parameters, e.g. here:

https://github.com/python/typeshed/blob/master/stdlib/3/builtins.pyi#L936


I would much rather have a single '/' to denote where positional-only ends, 
than have multiple leading '__'.

Newest-member-of-the-society-for-the-preservation-of-underscores-ly yrs,
--
~Ethan~

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2017-03-01 Thread Guido van Rossum
On Wed, Mar 1, 2017 at 11:25 AM, Serhiy Storchaka 
wrote:

> On 28.02.17 23:17, Victor Stinner wrote:
>
>> My question is: would it make sense to implement this feature in
>> Python directly? If yes, what should be the syntax? Use "/" marker?
>> Use the @positional() decorator?
>>
>
> I'm strongly +1 for supporting positional-only parameters. The main
> benefit to me is that this allows to declare functions that takes arbitrary
> keyword arguments like Formatter.format() or MutableMapping.update(). Now
> we can't use even the "self" parameter and need to use a trick with parsing
> *args manually. This harms clearness and performance.
>

Agreed.


> The problem with the "/" marker is that it looks ugly. There was an excuse
> for the "*" marker -- it came from omitting the name in "*args". The "*"
> prefix itself means an iterable unpacking, but "/" is not used neither as
> prefix nor suffix.
>

It's in a sense a pun -- * and / are "opposites" in mathematics, and so are
the usages here.


> Do you see concrete cases where it's a deliberate choice to deny
>> passing arguments as keywords?
>>
>
> dict.__init__(), dict.update(), partial.__new__() and partial.__call__()
> are obvious examples. There are others.
>
> And there was performance reason. Just making the function supporting
> keyword arguments added an overhead even to calls with only positional
> arguments. This was changed recently, but I didn't checked whether some
> overhead is left.
>
> Don't you like writing int(x="123") instead of int("123")? :-) (I know
>> that Serhiy Storshake hates the name of the "x" parameter of the int
>> constructor ;-))
>>
>
> I believe weird names like "x" was added when the support of "base"
> keyword was added due to the limitation of PyArg_ParseTupleAndKeywords().
> All or nothing, either builtin function didn't support keyword arguments,
> or it supported passing by keyword for all arguments.
>
> But now it is possible to support passing by keyword only the part of
> parameters. I want to propose to deprecate badly designed keyword names of
> builtins.
>

+1


> By the way, I read that "/" marker is unknown by almost all Python
>> developers, and [...] syntax should be preferred, but
>> inspect.signature() doesn't support this syntax. Maybe we should fix
>> signature() and use [...] format instead?
>>
>
> [...] is not Python syntax too. And it is orthogonal to positional-only
> parameters. [...] doesn't mean that parameters are positional-only. They
> can be passed by keyword, but just don't have default value. On other side,
> mandatory parameters can be positional-only.


FWIW in typeshed we've started using double leading underscore as a
convention for positional-only parameters, e.g. here:

https://github.com/python/typeshed/blob/master/stdlib/3/builtins.pyi#L936

FWIW I think 'self' should also be special-cased as positional-only. Nobody
wants to write 'C.foo(self=C())'. :-)

-- 
--Guido van Rossum (python.org/~guido )
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] Positional-only parameters

2017-03-01 Thread Serhiy Storchaka

On 28.02.17 23:17, Victor Stinner wrote:

My question is: would it make sense to implement this feature in
Python directly? If yes, what should be the syntax? Use "/" marker?
Use the @positional() decorator?


I'm strongly +1 for supporting positional-only parameters. The main 
benefit to me is that this allows to declare functions that takes 
arbitrary keyword arguments like Formatter.format() or 
MutableMapping.update(). Now we can't use even the "self" parameter and 
need to use a trick with parsing *args manually. This harms clearness 
and performance.


The problem with the "/" marker is that it looks ugly. There was an 
excuse for the "*" marker -- it came from omitting the name in "*args". 
The "*" prefix itself means an iterable unpacking, but "/" is not used 
neither as prefix nor suffix.



Do you see concrete cases where it's a deliberate choice to deny
passing arguments as keywords?


dict.__init__(), dict.update(), partial.__new__() and partial.__call__() 
are obvious examples. There are others.


And there was performance reason. Just making the function supporting 
keyword arguments added an overhead even to calls with only positional 
arguments. This was changed recently, but I didn't checked whether some 
overhead is left.



Don't you like writing int(x="123") instead of int("123")? :-) (I know
that Serhiy Storshake hates the name of the "x" parameter of the int
constructor ;-))


I believe weird names like "x" was added when the support of "base" 
keyword was added due to the limitation of 
PyArg_ParseTupleAndKeywords(). All or nothing, either builtin function 
didn't support keyword arguments, or it supported passing by keyword for 
all arguments.


But now it is possible to support passing by keyword only the part of 
parameters. I want to propose to deprecate badly designed keyword names 
of builtins.



By the way, I read that "/" marker is unknown by almost all Python
developers, and [...] syntax should be preferred, but
inspect.signature() doesn't support this syntax. Maybe we should fix
signature() and use [...] format instead?


[...] is not Python syntax too. And it is orthogonal to positional-only 
parameters. [...] doesn't mean that parameters are positional-only. They 
can be passed by keyword, but just don't have default value. On other 
side, mandatory parameters can be positional-only.



___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2017-02-28 Thread M.-A. Lemburg
On 28.02.2017 22:17, Victor Stinner wrote:
> Hi,
> 
> For technical reasons, many functions of the Python standard libraries
> implemented in C have positional-only parameters.

Keyword argument handling is comparatively slow and rarely
needed for non-optional positional parameters of built-ins.

You might make a case for optional ones, but then: how often are
these used in practice to warrant the drop in performance ?

Note: All this is different for Python methods/functions. The
overhead of keyword parsing is small compared to what Python
has to do to setup new frames for execution.

> Example:
> ---
> $ ./python
> Python 3.7.0a0 (default, Feb 25 2017, 04:30:32)
 help(str.replace)
> replace(self, old, new, count=-1, /)   # <== notice "/" at the end
> ...
 "a".replace("x", "y")  # ok
> 'a'
> 
 "a".replace(old="x", new="y")   # ERR!
> TypeError: replace() takes at least 2 arguments (0 given)
> ---
> 
> When converting the methods of the builtin str type to the internal
> "Argument Clinic" tool (tool to generate the function signature,
> function docstring and the code to parse arguments in C), I asked if
> we should add support for keyword arguments in str.replace(). The
> answer was quick: no! It's a deliberate design choice.
> 
> Quote of Yury Selivanov's message:
> """
> I think Guido explicitly stated that he doesn't like the idea to
> always allow keyword arguments for all methods. I.e. `str.find('aaa')`
> just reads better than `str.find(needle='aaa')`. Essentially, the idea
> is that for most of the builtins that accept one or two arguments,
> positional-only parameters are better.
> """
> http://bugs.python.org/issue29286#msg285578
> 
> I just noticed a module on PyPI to implement this behaviour on Python 
> functions:
> 
>https://pypi.python.org/pypi/positional
> 
> My question is: would it make sense to implement this feature in
> Python directly? If yes, what should be the syntax? Use "/" marker?
> Use the @positional() decorator?
> 
> Do you see concrete cases where it's a deliberate choice to deny
> passing arguments as keywords?
>
> Don't you like writing int(x="123") instead of int("123")? :-) (I know
> that Serhiy Storshake hates the name of the "x" parameter of the int
> constructor ;-))

... and that's another reason why to avoid them: the naming
of positional parameters was never really taken into account
when writing the C functions and it does even change
sometimes without warning.

> By the way, I read that "/" marker is unknown by almost all Python
> developers, 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?).
> 
> Python 3.5 help (docstring) uses "S.replace(old, new[, count])".

Using "count=-1" looks confusing when the method doesn't
allow keyword arguments, so it's probably better to use the 3.5
style and document the defaults in the doc-string.

AFAIR, some of these don't even have a (documented) default value.

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Experts (#1, Feb 28 2017)
>>> Python Projects, Coaching and Consulting ...  http://www.egenix.com/
>>> Python Database Interfaces ...   http://products.egenix.com/
>>> Plone/Zope Database Interfaces ...   http://zope.egenix.com/


::: We implement business ideas - efficiently in both time and costs :::

   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
   Registered at Amtsgericht Duesseldorf: HRB 46611
   http://www.egenix.com/company/contact/
  http://www.malemburg.com/

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2017-02-28 Thread Ethan Furman

https://www.python.org/dev/peps/pep-0457/

https://mail.python.org/pipermail/python-dev/2014-January/131865.html

--
~Ethan~
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2017-02-28 Thread Frazer McLean

On 28 Feb 2017, at 22:17, Victor Stinner wrote:

I just noticed a module on PyPI to implement this behaviour on Python 
functions:


   https://pypi.python.org/pypi/positional


Tangential to the main topic, but this module doesn’t enforce 
positional-only
arguments. It allows you enforce keyword-only arguments like on Python 
3:


>>> from positional import positional
>>> @positional(1)
... def replace(old, new):
... ...
...
>>> replace(old='a', new='b')
>>> replace('a', 'b')
Traceback (most recent call last):
  File "", line 1, in 
  File “…/site-packages/positional/__init__.py", line 97, in inner
raise TypeError(message)
TypeError: replace takes at most 1 positional argument (2 given)

Frazer
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] Positional-only parameters

2017-02-28 Thread Yury Selivanov

I'm +0.5 to add positional-only parameters.

Pros:

* A lot of people don't know what '/' currently means in
functions signatures rendered by `help` and docs.  Because
it's not a real syntax, it's really hard to find what it
means.

* Some APIs do look better with positional-only parameters,
especially functions with one argument.

* We already have this feature half-implemented: some
builtin methods have positional-only arguments,
inspect.signature API supports it already.

Cons:

* Function declarations will become a bit more complex,
making a bump in Python learning curve.

* Performance? I'm not sure if adding another set of checks
will make a huge impact, but we'll need to benchmark this.

Yury


On 2017-02-28 4:17 PM, Victor Stinner wrote:

Hi,

For technical reasons, many functions of the Python standard libraries
implemented in C have positional-only parameters. Example:
---
$ ./python
Python 3.7.0a0 (default, Feb 25 2017, 04:30:32)

help(str.replace)

replace(self, old, new, count=-1, /)   # <== notice "/" at the end
 ...

"a".replace("x", "y")  # ok

'a'


"a".replace(old="x", new="y")   # ERR!

TypeError: replace() takes at least 2 arguments (0 given)
---

When converting the methods of the builtin str type to the internal
"Argument Clinic" tool (tool to generate the function signature,
function docstring and the code to parse arguments in C), I asked if
we should add support for keyword arguments in str.replace(). The
answer was quick: no! It's a deliberate design choice.

Quote of Yury Selivanov's message:
"""
I think Guido explicitly stated that he doesn't like the idea to
always allow keyword arguments for all methods. I.e. `str.find('aaa')`
just reads better than `str.find(needle='aaa')`. Essentially, the idea
is that for most of the builtins that accept one or two arguments,
positional-only parameters are better.
"""
http://bugs.python.org/issue29286#msg285578

I just noticed a module on PyPI to implement this behaviour on Python functions:

https://pypi.python.org/pypi/positional

My question is: would it make sense to implement this feature in
Python directly? If yes, what should be the syntax? Use "/" marker?
Use the @positional() decorator?

Do you see concrete cases where it's a deliberate choice to deny
passing arguments as keywords?

Don't you like writing int(x="123") instead of int("123")? :-) (I know
that Serhiy Storshake hates the name of the "x" parameter of the int
constructor ;-))

By the way, I read that "/" marker is unknown by almost all Python
developers, and [...] syntax should be preferred, but
inspect.signature() doesn't support this syntax. Maybe we should fix
signature() and use [...] format instead?

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

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

Victor
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/