Plus 1 from me. I'm not 100% sure the signature / inspect backport does this, but as you say, it should be trivial to do, to whatever extent the python version we're hosted on does it.

Rob

On 28 Nov. 2017 07:14, "Larry Hastings" <larry@hastings.org> wrote:


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.

_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: https://mail.python.org/mailman/options/python-dev/robertc%40robertcollins.net