[Python-Dev] Quick poll: should help() show bound arguments?

Steven D'Aprano steve at pearwood.info
Sat Jan 25 05:36:49 CET 2014


On Fri, Jan 24, 2014 at 08:07:43PM -0800, Larry Hastings wrote:
> 
> (Quick, because apparently nobody reads the long ones!)
> 
> In Python 3.3:
> 
>     >>> class C:
>    ...    def foo(self, a):  pass
>    ...
>     >>> c = C()
>     >>> help(c.foo)
> 
> shows you the signature "foo(self, a)".

That matches the function declaration as defined right there in the 
class.


> As in, it claims it accepts two 
> parameters.  The function actually only accepts one parameter, because 
> "self" has already been bound.

No, that's wrong. The *function* C.foo accepts two parameters, self and 
a, exactly as declared. The *method* c.foo accepts only one.


> inspect.signature gets this right:
> 
>     >>> import inspect
>     >>> str(inspect.signature(c.foo))
>    '(a)'
> 
> but inspect.getfullargspec does not:
> 
>     >>> inspect.getfullargspec(c.foo)
>    FullArgSpec(args=['self', 'a'], varargs=None, varkw=None,
>    defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={})

That's arguable. Should inspect give the argument spec of the method 
object or the function object? I can see arguments for both. 
Backwards-compatibility argues against changing either, though.

help() is another story. Since help() is documentation aimed at the 
end-user, we can change it without worrying about backward 
compatibility. Ideally, help() ought to distingush between the two 
cases. I see that it already does, but not very well.

help(c.foo) in Python 3.3 gives:

    Help on method foo in module __main__:
 
    foo(self, a) method of __main__.C instance


while help(C.foo) gives:

    Help on function foo in module __main__:

    foo(self, a)



I think in the bound method case, it should drop the "self":

    Help on method foo in module __main__:

    foo(a) method of __main__.C instance


and in the function (previously: unbound method) case, it should show 
the "self" and the class:

    Help on function foo in module __main__:

    foo(self, a) method of class __main__.C

although I'm not sure how that second one is possible, now that unbound 
methods are gone and C.foo returns a plain function.

(Hmmm, perhaps getting rid of unbound methods was a mistake...)


> A) pydoc and help() should not show bound parameters in the signature, 
> like inspect.signature.
> B) pydoc and help() should show bound parameters in the signature, like 
> inspect.getfullargspec.


Provided they are described as *methods* rather than *functions*, bound 
methods should not show self. Likewise for classmethod and cls. That is, 
I'm voting +1 on A provided help() doesn't confuse methods and 
functions.


-- 
Steven


More information about the Python-Dev mailing list