How Can I Capture the Class Object for a Python Class Derived From My C API Metatype?
glchapman at earthlink.net
Thu Nov 15 16:36:54 CET 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
More information about the Python-list