[Python-Dev] PyMethodObject::im_class

Robin Dunn robin@alldunn.com
Mon, 19 Nov 2001 16:53:48 -0800


In wxPython the code I use for reflecting virtual C++ method calls to Python
methods checks first that the method is implemented in a derived class
otherwise it just calls the C++ base class version.  Here is a bit of the
code:

    PyObject* method;
    method = PyObject_GetAttrString(m_self, (char*)name);
    if (PyMethod_Check(method) &&
        ((PyMethod_GET_CLASS(method) == m_class) ||
         PyClass_IsSubclass(PyMethod_GET_CLASS(method), m_class))) {


This worked fine prior to Python 2.2 (the earliest I tried was 2.2b1) and
the PyMethod_GET_CLASS macro would give me the actual class that the method
was defined in.  Unfortunatly in 2.2 it appears that the class object
returned is now the class of m_self which in my test case is the derived
class which does not define the method.  This issue is further illustrated
by the following Python code:

class A:
    def spam(self):
        print "spam"
class B(A):
    pass

import sys
print sys.version
b = B()
print b.spam


Which, when run with Python 2.1.1 and Python 2.2b2 gives this output:

storm:robind> p21 /tmp/method.py
2.1.1 (#1, Aug 30 2001, 17:36:05)
[GCC 2.96 20000731 (Mandrake Linux 8.1 2.96-0.61mdk)]
<method A.spam of B instance at 0x80ed914>

storm:robind> p22 /tmp/method.py
2.2b2 (#1, Nov 19 2001, 13:36:25)
[GCC 2.96 20000731 (Mandrake Linux 8.1 2.96-0.62mdk)]
<bound method B.spam of <__main__.B instance at 0x814c044>>

Is there something different I can do in 2.2 to give me the class that the
method is actually defined in?  BTW, the comments in classobject.h still say
"The class that defined the method".

--
Robin Dunn
Software Craftsman
robin@AllDunn.com       Java give you jitters?
http://wxPython.org      Relax with wxPython!