Class property using Python C-API
Similar to these Python solutions, you will have to create a classproperty
type in C and implement its tp_descr_get
function (which corresponds to __get__
in Python).
Then, if you want to use that in a C type, you would have to create an instance of your classproperty
type and insert it into dictionary of your type (tp_dict
slot of your type).
Follow up:
It would seem that it's impossible to set an attribute of a C type. The tp_setattro
function of the metaclass (PyType_Type
) raises a "can't set attributes of built-in/extension type" exception for all non-heap types (types with no Py_TPFLAGS_HEAPTYPE
flag). This flag is set for dynamic types. You could make your type dynamic but it might be more work then it's worth.
This means that the solution I gave initially allows you to create a property (as in: computed attribute) on a C type object with the limitation that it's read only. For setting you could use a class/static-method (METH_CLASS
/METH_STATIC
flag on a method in tp_methods
).
I'll try to convey the essence of what I've discovered about using class static properties.
My (edited) code is as follows:
// Prepare your type object, which you will no doubt complete
// by calling PyType_Ready, as here.
if (PyType_Ready(typeObj) < 0)
{
return;
}
Py_INCREF(typeObj);
PyModule_AddObject(module, typeName, (PyObject*) typeObj);
// Now we add static members directly to the type's tp_dict, but
// only *after* we've registered the type (above)
PyObject* dict = typeObj->tp_dict;
// You'll have your own wrapper / C values in the line below. This is just
// a pseudo-version of what I am (successfully) using.
PyObject* tmp = MyCreateWrapper(myStaticValueInC);
// Py_INCREF(tmp); // You may need this, depending on how line above works.
PyDict_SetItemString(dict, staticPropertyName, tmp);
Py_DECREF(tmp);
I believe all the essentials are here in terms of what order to construct your code in order to implement a class property.