[Python-Dev] Can Python guarantee the order of keyword-only parameters?

Gregory P. Smith greg at krypto.org
Mon Nov 27 17:13:32 EST 2017

On Mon, Nov 27, 2017 at 10:13 AM Larry Hastings <larry at 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.

Seems reasonable to me.  I'm in the "yes" and "no" respectively "just do
it" camp on this if want to see it happen.  The groundwork was already laid
for this by using the order preserving dict in 3.6.  Having the inspect
module behave in a similar manner follows naturally from that.


> 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 at python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/greg%40krypto.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20171127/fa26d9d9/attachment.html>

More information about the Python-Dev mailing list