[Python-Dev] Define metatype and a type that uses it

Amaury Forgeot d'Arc amauryfa at gmail.com
Wed Jul 8 17:35:21 CEST 2009


Hello,

2009/7/8 Erik Groeneveld <erik at cq2.nl>:
> I am working on an extension that allows one to open Java .jar files
> and use the objects defined in it (via CNI or JNI) in Python.  It
> works like a charm, but I am stuck with the definition of a metatype
> for the wrappers.  I have to do this in Python now, with a helper
> class.
>
> I did find examples of how to define metatypes, but I can't find
> anything on how to declare one type using this metatype.
>
> Could anyone point me to examples or documentation or help me fix my code below?
[...]

There are several changes to do in your code:
- Don't define a JObjectMeta struct, use JObjectType directly instead.
An instance of the metatype is the type itself!
- Don't set JObjectMetaType.tp_basicsize, let it inherit from the base
type (the correct value would be sizeof(PyHeapTypeObject), this is
important in order to create derived classes in python)
- Don't set JObjectMetaType.tp_new, let it inherit from the base type
(PyType_GenericNew just allocates memory; types are more complex...)
- JObjectType.tp_base = &JObjectMetaType" is wrong, it should be
"JObjectType.ob_type = &JObjectMetaType;", or better to be compatible
with python3: "Py_TYPE(JObjectType) = &JObjectMetaType;"

In summary, I made your example work with:
   JObjectMetaType.tp_name         = "metaclass.JObjectMeta";
   JObjectMetaType.tp_flags        = Py_TPFLAGS_DEFAULT;
   JObjectMetaType.tp_doc          = "JObjectMeta objects";
   JObjectMetaType.tp_init         = JObjectMeta_init;
   JObjectMetaType.tp_base         = &PyType_Type;
   JObjectMetaType.tp_getattro     = JObjectMeta_getattro;

   Py_TYPE(&JObjectType)       = &JObjectMetaType;
   JObjectType.tp_name         = "metaclass.JObject";
   JObjectType.tp_basicsize    = sizeof(JObject);
   JObjectType.tp_flags        = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
   JObjectType.tp_doc          = "JObject objects";
   JObjectType.tp_init         = JObject_init;


-- 
Amaury Forgeot d'Arc


More information about the Python-Dev mailing list