How Can I Capture the Class Object for a Python Class Derived From My C API Metatype?

Greg Chapman glchapman at earthlink.net
Thu Nov 15 10:36:54 EST 2001


On 12 Nov 2001 06:08:52 -0800, stewart at sig.com (Rob Stewart) wrote:

>stewart at sig.com (Rob Stewart) wrote in message news:<3a5a7d54.0111091305.70bad186 at posting.google.com>...
>> I need to create a metatype, using the C API, that can save the class
>> objects for Python classes derived from it.  I need to be able to use
>> the class object to instantiate objects of that class under C (C++)
>> program control, and to discover the methods that have been defined to
>> override default behavior so C++ virtual function calls can be
>> forwarded to Python methods.

>As I understand the mechanism, T's tp_call slot function is invoked to
>instantiate a class object describing P.  If T is PyType_Type, then
>tp_call is defined to call the tp_new slot on the type of the new
>object, which ultimately should call tp_new on T (since the derived
>type's tp_new should call the base's tp_new.  At that point, T can
>save the PyObject * for the class object being created for later use
>by the C++ code.
>
>At that point, it should, I think, also be possible to capture the
>methods implemented or inherited by P.  For each method of an
>expected, predetermined name, I can capture the PyObject * for that
>method for subsequent invocation by the C++ code.  The notion here, is
>that if the method hasn't been overridden, then I can provide the
>default behavior in C++ rather than always forwarding to a method in
>the metatype.  This is merely a performance optimization.

First, take a look at the metatypes in Lib\test\test_descr.py to try to get a
general idea of what should happen.  I think what you need to do is create a
PyTypeObject for your metatype which has a base class (tp_base) of PyType_Type
(as well as an ob_type of PyType_Type).  PyType_Type is marked as
Py_TPFLAGS_BASETYPE so that should work.  Provide a tp_new handler which will
give you the chance to look at classes as they are created. The parameters to
tp_new (when creating types/classes) are the name of the new class, a tuple of
base classes, and a dictionary with the members (including methods) declared in
the to-be-created class. Looking at Misc\xxsubtype.c indicates that if all you
need is notification that a new class is being created, your metatype does not
need much besides tp_new, tp_flags, and tp_base -- it will inherit everything
else it needs from PyType_Type.  Finally, declare a base class that declares its
__metatype__ as your metatype, and inherit your classes from this base class;
when this base class and its descendants are created, your metatype's tp_new
will be called.

Again, a good idea is to look at test_descr.py, and then try to work out what
you want using a metatype written in Python to start with.  Once you've gotten
things working, you can convert your Python metatype to C.  I haven't tried
doing such a conversion, but it looks like it ought to be fairly
straightforward.

---
Greg Chapman




More information about the Python-list mailing list