[Python-Dev] PEP 3102: Keyword-only arguments (original) (raw)

Jean-Paul Calderone exarkun at divmod.com
Fri May 5 16:01:23 CEST 2006


On Fri, 5 May 2006 08:20:02 -0500, Michael Urman <murman at gmail.com> wrote:

On 5/5/06, Terry Reedy <tjreedy at udel.edu> wrote:

At present, Python allows this as a choice. Not always - take a look from another perspective: def makeperson(**kwds): name = kwds.pop('name', None) age = kwds.pop('age', None) phone = kwds.pop('phone', None) location = kwds.pop('location', None) ... This already requires the caller to use keywords, but results in horrid introspection based documentation. You know it takes some keywords, but you have no clue what keywords they are. It's as bad as calling help() on many of the C functions in the python stdlib. So what allowing named keyword-only arguments does for us is allows us to document this case. That is an absolute win.

Here you go:

import inspect

@decorator
def keyword(f):
    def g(*a, **kw):
        if a:
            raise TypeError("Arguments must be passed by keyword")
        args = []
        expectedArgs = inspect.getargspec(f)[0]
        defaults = inspect.getargspec(f)[-1]
        for i, a in enumerate(expectedArgs):
            if a in kw:
                args.append(kw[a])
            elif i >= len(expectedArgs) - len(defaults):
                args.append(defaults[i - len(expectedArgs)])
            else:
                raise TypeError("Missing argument for " + a)
        return f(*args)
    return g

@keyword
def foo(a, b, c=10, d=20, e=30):
    return a, b, c, d, e

try:
    foo()
except TypeError:
    pass
else:
    assert False, "Should have raised TypeError"


try:
    foo(1)
except TypeError:
    pass
else:
    assert False, "Should have raised TypeError"


try:
    foo(a=1)
except TypeError:
    pass
else:
    assert False, "Should have raised TypeError"


assert foo(a=1, b=2) == (1, 2, 10, 20, 30)
assert foo(a=1, b=2, c=3) == (1, 2, 3, 20, 30)
assert foo(a=1, b=2, d=4) == (1, 2, 10, 4, 30)
assert foo(a=1, b=2, c=3, d=4, e=5) == (1, 2, 3, 4, 5)
print 'Success!'


More information about the Python-Dev mailing list