Can I get a ruling on this?  I       got +1s from the community, but as it's a (minor) language thing I       feel like you're the only one who can actually okay it.
      
      
      /arry

      
      -------- Forwarded Message --------                                        Subject:                          Can Python guarantee the order of keyword-only               parameters?                                   Date:              Mon, 27 Nov 2017 09:05:57 -0800                                   From:              Larry Hastings                                    To:              Python-Dev                                   
      
">

(original) (raw)

Sure. I think it's a good idea to make this a guaranteed language behavior, and it doesn't need a PEP.

On Sun, Dec 10, 2017 at 1:52 PM, Larry Hastings <larry@hastings.org> wrote:


Can I get a ruling on this? I got +1s from the community, but as it's a (minor) language thing I feel like you're the only one who can actually okay it.


/arry


\-------- Forwarded Message --------
Subject: Can Python guarantee the order of keyword-only parameters?
Date: Mon, 27 Nov 2017 09:05:57 -0800
From: Larry Hastings
To: Python-Dev




First, a thirty-second refresher, so we're all using the same terminology:
A \*parameter\* is a declared input variable to a function.
An \*argument\* is a value passed into a function. (\*Arguments\* are stored in \*parameters.\*)

So in the example "def foo(clonk): pass; foo(3)", clonk is a parameter, and 3 is an argument. ++

Keyword-only arguments were conceived of as being unordered. They're stored in a dictionary--by convention called \*\*kwargs--and dictionaries didn't preserve order. But knowing the order of arguments is occasionally very useful. PEP 468 proposed that Python preserve the order of keyword-only arguments in kwargs. This became easy with the order-preserving dictionaries added to Python 3.6\. I don't recall the order of events, but in the end PEP 468 was accepted, and as of 3.6 Python guarantees order in \*\*kwargs.

But that's arguments. What about parameters?

Although this isn't as directly impactful, the order of keyword-only parameters \*is\* visible to the programmer. The best way to see a function's parameters is with inspect.signature, although there's also the deprecated inspect.getfullargspec; in CPython you can also directly examine fn.\_\_code\_\_.co\_varnames. Two of these methods present their data in a way that preserves order for all parameters, including keyword-only parameters--and the third one is deprecated.

Python must (and does) guarantee the order of positional and positional-or-keyword parameters, because it uses position to map arguments to parameters when the function is called. But conceptually this isn't necessary for keyword-only parameters because their position is irrelevant. I only see one place in the language & library that addresses the ordering of keyword-only parameters, by way of omission. The PEP for inspect.signature (PEP 362) says that when comparing two signatures for equality, their positional and positional-or-keyword parameters must be in the same order. It makes a point of \*not\* requiring that the two functions' keyword-only parameters be in the same order.

For every currently supported version of Python 3, inspect.signature and fn.\_\_code\_\_.co\_varnames preserve the order of keyword-only parameters. This isn't surprising; it's basically the same code path implementing those as the two types of positional-relevant parameters, so the most straightforward implementation would naturally preserve their order. It's just not guaranteed.

I'd like inspect.signature to guarantee that the order of keyword-only parameters always matches the order they were declared in. Technically this isn't a language feature, it's a library feature. But making this guarantee would require that CPython internally cooperate, so it's kind of a language feature too.

Does this sound reasonable? Would it need a PEP? I'm hoping for "yes" and "no", respectively.


Three final notes:
  • Yes, I do have a use case. I'm using inspect.signature metadata to mechanically map arguments from an external domain (command-line arguments) to a Python function. Relying on the declaration order of keyword-only parameters would elegantly solve one small problem.
  • I asked Armin Rigo about PyPy's support for Python 3\. He said it should already maintain the order of keyword-only parameters, and if I ever catch it not maintaining them in order I should file a bug. I assert that making this guarantee would be nearly zero effort for any Python implementation--I bet they all already behave this way, all they need is a test case and some documentation.
  • One can extend this concept to functools.partial and inspect.Signature.bind: should its transformations of keyword-only parameters also maintain order in a consistent way? I suspect the answer there is much the same--there's an obvious way it should behave, it almost certainly already behaves that way, but it doesn't guarantee it. I don't think I need this for my use case.


/arry

++ Yes, that means "Argument Clinic" should really have been called "Parameter Clinic". But the "Parameter Clinic" sketch is nowhere near as funny.



--
--Guido van Rossum (python.org/\~guido)