Python 2.6: Determining if a method is inherited

F

Fuzzyman

Hello all,

I may well be being dumb (it has happened before), but I'm struggling
to fix some code breakage with Python 2.6.

I have some code that looks for the '__lt__' method on a class:

if hasattr(clr, '__lt__'):

However - in Python 2.6 object has grown a default implementation of
'__lt__', so this test always returns True.
False

So how do I tell if the X.__lt__ is inherited from object? I can look
in the '__dict__' of the class - but that doesn't tell me if X
inherits '__lt__' from a base class other than object. (Looking inside
the method wrapper repr with a regex is not an acceptable answer...)

Some things I have tried:

['__call__', '__class__', '__cmp__', '__delattr__', '__doc__',
'__format__', '__getattribute__', '__hash__', '__init__', '__name__',
'__new__', '__objclass__', '__reduce__', '__reduce_ex__', '__repr__',
'__self__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__']Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'method-wrapper' object has no attribute '__func__'

Michael Foord
 
V

Valentino Volonghi aka Dialtone

Fuzzyman said:
So how do I tell if the X.__lt__ is inherited from object? I can look

I don't have python 2.6 installed so I can't try but what I think could
work is:
.... def hello(self):
.... pass
.... .... def hello(self):
.... pass
.... .... pass
.... False

Which to me also makes sense. If it's inherited I expect it to be the
very same function object of one of the bases (which you can get with
inspect.getmro(Clazz)). On the other end if you override it it's not the
same function object so it won't return True when applied to 'is'.

HTH
 
A

Aaron \Castironpi\ Brady

Fuzzyman said:
Hello all,

I may well be being dumb (it has happened before), but I'm struggling
to fix some code breakage with Python 2.6.

I have some code that looks for the '__lt__' method on a class:

if hasattr(clr, '__lt__'):

However - in Python 2.6 object has grown a default implementation of
'__lt__', so this test always returns True.

False

So how do I tell if the X.__lt__ is inherited from object? I can look
in the '__dict__' of the class - but that doesn't tell me if X
inherits '__lt__' from a base class other than object. (Looking inside
the method wrapper repr with a regex is not an acceptable answer...)

They're of different types. I'm not sure how much you could use that,
or how reliable it is.
.... pass
........ def __lt__( self, other ):
.... pass
....
 
F

Fuzzyman

I don't have python 2.6 installed so I can't try but what I think could
work is:


...     def hello(self):
...         pass
...>>> class Bla(Foo):

...     def hello(self):
...         pass
...>>> class Baz(Foo):

...     pass
...>>> Baz.hello.im_func

<function hello at 0x2b1630>>>> Bla.hello.im_func

<function hello at 0x2b1670>>>> Foo.hello.im_func



False


Nope:

Python 2.6 (trunk:66714:66715M, Oct 1 2008, 18:36:04)
[GCC 4.0.1 (Apple Computer, Inc. build 5370)] on darwin
Type "help", "copyright", "credits" or "license" for more information.Traceback (most recent call last):

What I went with in the end:

import sys as _sys

if _sys.version_info[0] == 3:
def _has_method(cls, name):
for B in cls.__mro__:
if B is object:
continue
if name in B.__dict__:
return True
return False
else:
def _has_method(cls, name):
for B in cls.mro():
if B is object:
continue
if name in B.__dict__:
return True
return False

See this page for why I needed it:

http://www.voidspace.org.uk/python/weblog/arch_d7_2008_10_04.shtml#e1018

Michael
 
T

Terry Reedy

Fuzzyman said:
Hello all,

I may well be being dumb (it has happened before), but I'm struggling
to fix some code breakage with Python 2.6.

I have some code that looks for the '__lt__' method on a class:

if hasattr(clr, '__lt__'):

However - in Python 2.6 object has grown a default implementation of
'__lt__', so this test always returns True.

False

In 3.0, the test returns true because function attributes only get
wrapped when bound. In the meanwhile, " 'object' in repr(X.__lt__)"
should do it for you.

tjr
 
F

Fuzzyman

In 3.0, the test returns true because function attributes only get
wrapped when bound. In the meanwhile, " 'object' in repr(X.__lt__)"
should do it for you.


So long as its never used on a class with 'object' in the name.
Doesn't sound like a particularly *good* solution to me. :)

Michael
 
F

Fuzzyman

This session should give you some hints how to archive your goal :)
Have fun!

... def __lt__(self):
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'method-wrapper' object has no attribute 'im_func'

However - I need to detect whether a method is inherited from
*object*. All those differences you have shown behave identically if
the class inherits from 'int'.

I am trying to detect explicit implementation of comparison methods -
so there is a big difference between inheriting from int and
inheriting from object (meaningful comparison methods existing on one
and not the other).

What I went for in the end:

import sys as _sys

if _sys.version_info[0] == 3:
def _has_method(cls, name):
for B in cls.__mro__:
if B is object:
continue
if name in B.__dict__:
return True
return False
else:
def _has_method(cls, name):
for B in cls.mro():
if B is object:
continue
if name in B.__dict__:
return True
return False

See this page for why I needed it:

http://www.voidspace.org.uk/python/weblog/arch_d7_2008_10_04.shtml#e1018

Michael
 
T

Terry Reedy

So long as its never used on a class with 'object' in the name.
Doesn't sound like a particularly *good* solution to me. :)

From what you posted, 'type object at' should work.
 
T

Terry Reedy

Fuzzyman said:
It's still a hack...

I am sorry if I offended you by pointing out to you a quick and dirty
solution that would solve your problem immediately.
 
F

Fuzzyman

I am sorry if I offended you by pointing out to you a quick and dirty
solution that would solve your problem immediately.

Your smiley parsing is obviously broken.

Michael
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top