<div dir="ltr">Sure. I think it's a good idea to make this a guaranteed language behavior, and it doesn't need a PEP.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Dec 10, 2017 at 1:52 PM, Larry Hastings <span dir="ltr"><<a href="mailto:larry@hastings.org" target="_blank">larry@hastings.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  

    
  
  <div text="#000000" bgcolor="#FFFFFF">
    <p><br>
    </p>
    <div class="m_-7947368193309189741moz-forward-container">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.<br>
      <br>
      <br>
      <i>/arry</i><div><div class="h5"><br>
      <br>
      -------- Forwarded Message --------
      <table class="m_-7947368193309189741moz-email-headers-table" cellspacing="0" cellpadding="0" border="0">
        <tbody>
          <tr>
            <th valign="BASELINE" nowrap align="RIGHT">Subject:
            </th>
            <td>Can Python guarantee the order of keyword-only
              parameters?</td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap align="RIGHT">Date: </th>
            <td>Mon, 27 Nov 2017 09:05:57 -0800</td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap align="RIGHT">From: </th>
            <td>Larry Hastings <a class="m_-7947368193309189741moz-txt-link-rfc2396E" href="mailto:larry@hastings.org" target="_blank"><larry@hastings.org></a></td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap align="RIGHT">To: </th>
            <td>Python-Dev <a class="m_-7947368193309189741moz-txt-link-rfc2396E" href="mailto:python-dev@python.org" target="_blank"><python-dev@python.org></a></td>
          </tr>
        </tbody>
      </table>
      <br>
      <br>
      
      <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>
      <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></div></div>
  </div>

</blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div>
</div>