Issue 20379: help(instance_of_builtin_class.method) does not display self (original) (raw)

Created on 2014-01-24 14:06 by larry, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (7)

msg209078 - (view)

Author: Larry Hastings (larry) * (Python committer)

Date: 2014-01-24 14:06

For an object O that are bound to something (either a class or an instance), help(O) traditionally shows the bound argument. For this code:

class C:
    def foo(self, a):  pass

c = C()

help(c.foo) would show the signature as "(self, a)", even though self has been bound.

My recent changes to Python's type system (#20189), to add inspect.Signature support for builtins, broke this. The previous behavior should be restored.

msg209108 - (view)

Author: Terry J. Reedy (terry.reedy) * (Python committer)

Date: 2014-01-24 19:33

What matters to other programs is what the inspect functions return, not what help() does or does not do to the returned string before displaying it. So I see the issue as the discrepancy in this.

class C: def foo(self, a): pass c = C()

import inspect print('garg - C.foo ', inspect.formatargspec(*inspect.getfullargspec(C.foo))) print('garg - c.foo', inspect.formatargspec(*inspect.getfullargspec(c.foo))) print('sig - C.foo ', str(inspect.signature(C.foo))) print('sig - c.foo', str(inspect.signature(c.foo)))

garg - C.foo (self, a) garg - c.foo (self, a) sig - C.foo (self, a) sig - c.foo (a)

Idle calltips attempt to remind the user what they must and might enter after '('. For this, the sig output correct and the garg output is buggy. Idle currently works around the garg bug by selectively deleting the first param name with if (isinstance(ob, (type, types.MethodType)) or isinstance(ob_call, types.MethodType)): argspec = _first_param.sub("", argspec)

If signatures for bound builtins are similarly buggy, by including 'self' when it should be omitted, calltips would need a means to detect when to omit. Perhaps

type([].append) <class 'builtin_function_or_method'> will work, but the name implies otherwise. In any case, I would prefer that inspect.signature give correct results instead of being made bug-compatible with .getfullargspec. In other words, it should include the 'delete self' code that is correct for the implementation. Then I could omit the yet-to-be-written expanded workaround.

I regard this help output as buggy.

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

It identifies foo as a bound method, but gives the wrong signature for a bound method. So in my view, your changes fix a bug rather than breaking correct behavior.

msg209119 - (view)

Author: Zachary Ware (zach.ware) * (Python committer)

Date: 2014-01-24 20:55

I don't think there's any danger of changing inspect.Signature's behavior here; it's doing the right thing. What we're concerned with here is just making sure that the output of 'help(some_kind_of_method)' is equivalent to the output of 'help(some_kind_of_method_in_C)', which should just mean changes to pydoc.

pydoc currently shows the 'self' parameter because before trying to find the signature, it replaces the object it is looking at with that object's func attribute (see Lib/pydoc.py:1315). To get rid of that behavior for Python-implemented methods is as simple as removing that line.

Is that the route we want to go, though? It makes sense and it does make Python and C methods (mostly) match so I'd be happy with it, but it does change the help output for every Python-implemented method.

There is still the issue that the help output for C-implemented methods don't say anything about whether they're bound or not, but that issue is just a sibling to this one.

msg209126 - (view)

Author: Larry Hastings (larry) * (Python committer)

Date: 2014-01-24 21:54

Huh. So inspect.getfullargspec is the code ignoring whether or not a function is bound.

Well, help(x) should be consistent, whether x is a bound builtin class instance or a bound Python class instance. Right now it isn't; it displays the "self" for the Python one but not for the builtin one.

msg209138 - (view)

Author: Terry J. Reedy (terry.reedy) * (Python committer)

Date: 2014-01-25 00:29

I fully agree that help(bound method) should be consistent. I just feel that it should be consistently correct ;-).

Help(ob) is intended for interactive use (Guido has said, but feel free to ask again), and indeed, is an optional interactive feature, and not a built-in. So I believe we are free to change the output to something better (as with Exception messages). For some things (classes), it prints out too much and Guido would like a bit less printed.

msg209589 - (view)

Author: Yury Selivanov (yselivanov) * (Python committer)

Date: 2014-01-28 21:32

FWIW, I solved the first arg consistency for inspect.getfullargspec in #17481. The latest patch always shows the first argument (self) for both python-defined and C-defined methods.

msg213715 - (view)

Author: Larry Hastings (larry) * (Python committer)

Date: 2014-03-16 05:17

Fixed in b2ee3fe195e2.

History

Date

User

Action

Args

2022-04-11 14:57:57

admin

set

github: 64578

2014-03-16 05:17:01

larry

set

status: open -> closed
resolution: fixed
messages: +

stage: needs patch -> resolved

2014-01-28 21:32:59

yselivanov

set

nosy: + yselivanov
messages: +

2014-01-25 04:54:36

zach.ware

set

messages: -

2014-01-25 04:54:33

zach.ware

set

messages: -

2014-01-25 04:54:31

zach.ware

set

messages: -

2014-01-25 04:24:36

larry

set

messages: +

2014-01-25 04:24:02

zach.ware

set

messages: +

2014-01-25 04🔞49

larry

set

messages: +

2014-01-25 04:06:07

larry

set

title: help(bound_builtin_class) does not display self -> help(instance_of_builtin_class.method) does not display self

2014-01-25 00:29:01

terry.reedy

set

messages: +

2014-01-24 21:54:08

larry

set

messages: +

2014-01-24 20:55:34

zach.ware

set

messages: +

2014-01-24 19:33:01

terry.reedy

set

nosy: + terry.reedy
messages: +

2014-01-24 14:06:42

larry

create