What should I put in the tp_name field when defining a type in a Python extension?
I am developing an interface so that Python programs can call into an existing C++ library. If I understand correctly, such an interface (and the C++ library) should be imported as a module, say abc
. The types in the interface are defined as static variables on the C++ side of the interface, and registered with Python using the following sequence:
void PythonRegistrationData::RegisterType(PyObject* module, PyTypeObject* type)
{
if (type->ob_refcnt < 2)
{
if (type->tp_base != NULL)
RegisterType(module, type->tp_base);
Py_INCREF(type);
if (PyType_Ready(ty开发者_运维问答pe) != 0)
throw GPython::DummyError();
PyModule_AddObject(module, type->tp_name, as<PyObject>(type));
}
}
(The recursion is to ensure that base classes are registered before the derived class. The module has been created earlier.) According to the C-API docs, “For statically allocated type objects, the tp_name field should contain a dot.”; for this reason, I initialize tp_name
with "abc.MyType"
. When I do this, after loading the module, I get 'module' object has no attribute 'MyType'
when I try to use the type (e.g. x = abc.MyType()
, having done import abc
before). If I use just "MyType"
, it seems to work, but this seems to contradict both the official documentation and the examples in the tutorial.
So what is the exact meaning of the tp_name
field, and what should it really contain? And what is the effect of my not putting the module name in it?
By doing
PyModule_AddObject(module, type->tp_name, as<PyObject>(type));
you are adding the type to the module (which means setting an attribute) using "abc.MyType" as the attribute name. Which means you would need to access it using getattr(abc, 'abc.MyType')
if you wanted to access it on the abc
module (you can't access attributes with dots in the name directly.) You should set the tp_name
to the "qualified" name (with abc.
in front of it), you just shouldn't use the tp_name as the attribute name.
精彩评论