[issue19956] inspect.getsource(obj.foo) fails when foo is an injected method constructed from another method

Terry J. Reedy report at bugs.python.org
Mon May 18 00:30:33 EDT 2020


Terry J. Reedy <tjreedy at udel.edu> added the comment:

Here is minimal reproducing code.

import types
import inspect

class A:
    def say(self): print("A.say")
a = A()

class B: pass    
b = B()
b.say = types.MethodType(a.say, b)

Let us examine MethodType first.  Calling 'b.say()' asks the previously neglected question: Is b.say a proper, sane callable?  I claim not. With 3.9.0a6, the call fails with "TypeError: say() takes 1 positional argument but 2 were given".  b.say() calls a.say(b), which calls A.say(a, b).  If A.say took another parameter, such as 'name', 'b.say()' might work, but only by accident.

Here is another buggy use of MethodType, 
b.A = types.MethodType(A, b)
b.A()
# TypeError: A() takes no arguments
Again, given 'def __init__(self, something)', b.A() might work, but only by accident.

types.MethodType is an example of "[This module] defines names for some object types that are used by the standard Python interpreter, but not exposed as builtins like int or str are."  The names are mainly intended to be used for isinstance checks and rarely, if at all, for object creation.

The MethodType entry lack a signature and only says "The type of methods of user-defined class instances."  Its docstring, "method(function, instance)\n\nCreate a bound instance method object." does have a signature.  However, 'function' must be a function compatible with being passed 'instance' as the first argument.  This is false for both A and a.say; both result in buggy 'callables'.

MethodType checks that its first argument, assigned to the .__func__ attribute, is callable (has a '.__call__' attribute) but apparently does not check further.

As for getsource.  For b.A and b.say, it raises "TypeError: module, class, method, function, traceback, frame, or code object was expected, got {type}", where type is 'type' and 'method' respectively.  For both, the message is slightly confusing in that the function got something on the list (type=class).  For both, getsource could be patched to work with the buggy inputs.  I the latter is a bad idea.  Built-in functions usually fail with buggy inputs.  We should either improve the error message for methods or just close this.

----------
nosy: +serhiy.storchaka

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue19956>
_______________________________________


More information about the Python-bugs-list mailing list