[Python-Dev] PEP 3102: Keyword-only arguments

Fredrik Lundh fredrik at pythonware.com
Mon May 1 19:43:03 CEST 2006


Edward Loper wrote:

> >> And again, why would you *make* me, the user-programmer, type
> >>
> >> make_person(name=namex, age=agex, phone=phonex, location = locationx)
> >> #instead of
> >> make_person(namex,agex,phonex,locationx)
> >> ?
> >
> > because a good API designer needs to consider more than just the current
> > release.
>
> I believe that it's quite possible that you're right, but I think more
> concrete answers would be helpful.  I.e., how does having parameters
> that are syntactically keyword-only (as opposed to being simply
> documented as keyword-only) help you develop an API over time?

As you've figured out, the main advantage is that by forcing people to do what
you intended, you can change things around without breaking existing code.

And others can implement your API:s without having to emulate every possible
implementation artifact.  (I guess this is something that distinguish me from most
other Pythoneers; I don't consider an API design good enough until it has at least
two semi-independent implementations...)

> I gave some thought to it, and can come up with a few answers.  In all
> cases, assume a user BadUser, who decided to use positional arguments
> for arguments that you documented as keyword-only.
>
> - You would like to deprecate, and eventually remove, an argument to
>    a function.  For people who read your documentation, and use
>    keyword args for the keyword-only arguments, their code will break
>    in a clean, easy-to-understand way.  But BadUser's code may break in
>    strange hard-to-understand ways, since their positional arguments will
>    get mapped to the wrong function arguments.
>
> - You would like to add a new parameter to a function, and would like
>    to make that new parameter available for positional argument use.
>    So you'd like to add it before all the keyword arguments.  But this
>    will break BadUser's code.
>
> - You have a function that takes one argument and a bunch of keyword
>    options, and would like to change it to accept *varargs instead of
>    just one argument.  But this will break BadUser's code.
>
> I think that this kind of *concrete* use-case provides a better
> justification for the feature than just saying "it will help API
> design."  As someone who has had a fair amount of experience designing &
> maintaining APIs over time, perhaps you'd care to contribute some more
> use cases where you think having syntactically keyword-only arguments
> would help?

In addition to your cases, the major remaining use case is the "one or more
standard arguments, and one or more options"-style interface.  ET's write
method is a typical example.  The documented interface is

    tree.write(out, **options)

where 'out' is either a filename or something that has a 'write' method, and
the available options are implementation dependent.

An implementer that wants to support an "encoding" option could implement
this as

    def write(self, out, encoding="us-ascii"):

even if he only documents the write(out, **options) form, but developers
using e.g. introspection-based "intellisense" tools or pydoc or help() will in-
variably end up calling this as

    tree.write(out, "utf-8")

which causes problems for reimplementors, and limits how the interface can
be modified in the future (once enough people do this, you cannot even go
back to a stricter "def write(self, out, **options)" approach without breaking
stuff).

I've suffered from enough "specification by reverse engineering" incidents
during my career to ignore things like this...

</F>





More information about the Python-Dev mailing list