<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Mon, Nov 27, 2017 at 10:13 AM Larry Hastings <<a href="mailto:larry@hastings.org">larry@hastings.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div text="#000000" bgcolor="#FFFFFF">
<br>
<br>
First, a thirty-second refresher, so we're all using the same
terminology:<br>
<blockquote>A *parameter* is a declared input variable to a
function.<br>
An *argument* is a value passed into a function. (*Arguments* are
stored in *parameters.*)<br>
<br>
So in the example "def foo(clonk): pass; foo(3)", clonk is a
parameter, and 3 is an argument. ++<br>
</blockquote>
<br>
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.<br>
<br>
But that's arguments. What about parameters?<br>
<br>
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.<br>
<br>
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.<br>
<br>
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.<br>
<br>
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.<br>
<br>
Does this sound reasonable? Would it need a PEP? I'm hoping for
"yes" and "no", respectively.<br></div></blockquote><div><br></div><div>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.</div><div><br></div><div>-gps</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF">
<br>
<br>
Three final notes:<br>
<ul>
<li>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.</li>
<li>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.<br>
</li>
<li>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.<br>
</li>
</ul>
<br>
<br>
<i>/arry</i><br>
<br>
++ Yes, that means "Argument Clinic" should really have been called
"Parameter Clinic". But the "Parameter Clinic" sketch is nowhere
near as funny.
</div>
_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" target="_blank">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/greg%40krypto.org" rel="noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/greg%40krypto.org</a><br>
</blockquote></div></div>