New submission from Steven Barker:
The "repr" of bound method objects can be misleading in certain situations. The
repr is always is of the format:
<bound method x.y of <object>>
But "x" is often incorrect.
Here are some examples where the current code gets it wrong:
# inherited method
class Base(object):
def foo(self):
pass
class Derived(Base):
pass
print(Derived().foo)
# not too bad, prints "<bound method Derived.foo of <__main__.Derived
object at 0xXXXX>>"
# it probably should say "Base.foo" instead of "Derived.foo", but at least
they're two names for the same function
# however, an override and super() it gets very bad
class Derived2(Base):
def foo(self):
pass
print(super(Derived2, Derived2()).foo)
# totally wrong, prints "<bound method Dervied2.foo of __main__.derived2
object at 0xXXXX>>"
# but it actually *is* Base.foo bound to a Derived2 instance!
# bound class methods:
class Test(object):
@classmethod
def foo(cls):
pass
print(Test.foo)
# wrong, prints <bound method type.foo of <class '__main__.Test'>>
I suggest that rather than trying to assemble the "x.y" pair by from
"__self__.__class__" and "__func__.__name__", the BoundMethod should just use
the "__func__.__qualname__". In each of the cases above, the function's
location would be correctly located this way.
I came across this bug while investigating a confusing (to me) issue with
metaclasses and inheritance. The misleading "repr" output made it much harder
to figure out that my expectations were wrong. Here's a simplified example of
how it led me astray:
class A(object):
@classmethod
def foo(cls):
return "classmethod from A"
class BMeta(type):
def foo(cls):
return "instancemethod from BMeta"
class B(A, metaclass=BMeta):
pass
print(B.foo()) # surprisingly (to me) prints "classmethod from A"
print(B.foo) # incorrectly prints "<bound method BMeta.foo of <class
__main__.B>>"
It is presumably not a bug that inherited class methods take precedence over
instance methods from a metaclass (though it was surprising to me at the time).
The repr of the bound method though, suggested exactly the opposite. Given that
it gets many more common situations wrong as well, I think that the repr should
be fixed.
The relevant code appears to be in the method_repr function in
Objects/Classobject.c .
----------
components: Interpreter Core
messages: 217566
nosy: Steven.Barker
priority: normal
severity: normal
status: open
title: The repr of BoundMethod objects sometimes incorrectly identifies the
bound function
type: behavior
versions: Python 3.4
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue21389>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com