[Python-3000] PEP3102 Keyword-Only Arguments (original) (raw)

Steven Bethard steven.bethard at gmail.com
Mon Aug 14 22:34:54 CEST 2006


On 8/14/06, Guido van Rossum <guido at python.org> wrote:

On 8/14/06, Steven Bethard <steven.bethard at gmail.com> wrote: > On 8/14/06, Guido van Rossum <guido at python.org> wrote: > > I believe the PEP doesn't address the opposite use case: positional > > arguments that should not be specified as keyword arguments. For > > example, I might want to write > > > > def foo(a, b): ... > > > > but I don't want callers to be able to call it as foo(b=1, a=2) or > > even foo(a=2, b=1). > > Another use case is when you want to accept the arguments of another > callable, but you have your own positional arguments:: > > >>> class Wrapper(object): > ... def init(self, func): > ... self.func = func > ... def call(self, *args, **kwargs): > ... print 'calling wrapped function' > ... return self.func(*args, **kwargs) > ... > >>> @Wrapper > ... def func(self, other): > ... return self, other > ... > >>> func(other=1, self=2) > Traceback (most recent call last): > File "", line 1, in ? > TypeError: call() got multiple values for keyword argument 'self' > > It would be really nice in the example above to mark self in > _call_ as a positional only argument.

But this is a rather unusual use case isn't it? It's due to the bound methods machinery. Do you have other use cases?

Well, for example, unitest.TestCase.failUnlessRaises works this way. Here's the method signature::

def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):

Which means that if you write::

self.failUnlessRaises(TypeError, my_func, callableObj=foo)

you'll get an error since there's a name clash between the callableObj taken by failUnlessRaises and the one taken by the my_func object.

OTOH, I haven't run into this error because I don't use camelCase names. Perhaps the right answer is to always use camelCase on any arguments that you don't want to worry about conflicts, and then any PEP 8 compliant code will never have problems. ;-)

> > Perhaps we can use ** without following identifier to signal this? > > It's not entirely analogous to * without following identifier, but at > > least somewhat similar. > > I'm certainly not opposed to going this way, but I don't think it > would solve the problem above since you still need to take keyword > arguments.

Can you elaborate?

Well, taking the failUnlessRaises signature above, if you wanted to specify that self, excClass and callableObj were positional only arguments, I believe you'd have to write::

def failUnlessRaises(self, excClass, callableObj, *args, **):

I believe that means that you can't use failUnlessRaises to call a method that expects keyword arguments, e.g.::

self.assertRaises(OptionError, parser.add_option, type='foo')

STeVe

I'm not in-sane. Indeed, I am so far out of sane that you appear a tiny blip on the distant coast of sanity. --- Bucky Katt, Get Fuzzy



More information about the Python-3000 mailing list