[Python-ideas] Passing positional arguments as keyword arguments (to provide function arguments out of order)

Anders Hovmöller boxed at killingar.net
Thu May 16 01:46:30 EDT 2019



> On 15 May 2019, at 21:55, Jonathan Goble <jcgoble3 at gmail.com> wrote:
> 
>> On Wed, May 15, 2019 at 3:45 AM Anders Hovmöller <boxed at killingar.net> wrote:
>> 
>>> On 15 May 2019, at 07:51, Jonathan Goble <jcgoble3 at gmail.com> wrote:
>>> 
>>> That's not a realistic goal; there are some use cases, including in
>>> CPython builtins, that cannot be accomplished without positional-only
>>> arguments. For example, the current behavior of the `dict` constructor
>>> is to accept both certain iterables as a positional-only argument
>>> and/or keyword arguments from which a dict can be created. If the
>>> iterable argument was not positional-only, then it would be forced to
>>> consume a keyword (even if the caller passes it as a positional
>>> argument), meaning that that keyword could never be included in
>>> **kwargs and could not become a dict key via keyword arguments.
>> 
>> You lost me. How is this not handled by *args and **kwargs? I think it is. "Positional only" isn't needed in this case.
> 
> Because `def func(*args, **kwargs):` obfuscates the true signature,
> making `help()` and the `inspect` module less useful and forcing one
> to analyze the implementation code or study the docs to understand
> what and how many arguments are actually expected.

In the general case because of features that until / was introduced was unique to functions defined in C. But in the case of the dict constructor that's just a weird misfeature. If it did in fact take *args and handled it it would be perfectly fine and useful. It would have meant people wouldn't have written all those merge() utility functions over the years. And it would make dict(a, b) valid syntax instead of the current overly verbose dict(**a, **b). 

For / to be a good idea one needs a strong argument for why a function must exist that tales a bounded amount of arguments (ie not *args) where calling it with the parameters named would be a bad thing. There are certainly cases where the names don't add much, like most functions with one argument but that is a different thing. 

/ Anders 


More information about the Python-ideas mailing list