I have a follow up for another question. That question is about how to access constants added to a C extension module for Python.
To paraphrase that question and answer, if you added constants RED
and BLUE
to your module in the initialization function like this:
PyMODINIT_FUNC
PyInit_mymodule(void)
{
PyObject* module = PyModule_Create(&Module);
// ...
PyModule_AddStringConstant(module, "BLUE", "blue");
PyModule_AddStringConstant(module, "RED", "red");
return module;
}
then you can access them, e.g. to return them from a function, like this (bearing in mind that you must increment reference counts if necessary):
// Get module dict. This is a borrowed reference.
PyObject* module_dict = PyModule_GetDict(module);
// Get BLUE constant. This is a borrowed reference.
PyObject* BLUE = PyDict_GetItemString(module_dict, "BLUE");
// Get RED constant. This is a borrowed reference.
PyObject* RED = PyDict_GetItemString(module_dict, "RED");
That works great if you have a pointer to the module object, which was the case in the linked question.
My question is, how do you do this if you don't have a pointer to the module object? For example, if the current function is an object's method, the self
pointer you have is for that object, not the module (and I haven't been able to find a way to get the module from the object):
static PyObject * Foo_get_color(FooObject *self) {
// How do I get the module object here?
PyObject *module_dict = PyModule_GetDict(/* ??? */);
PyObject *color = NULL;
if (self->color == RED) {
color = PyDict_GetItemString(module_dict, "RED");
Py_INCREF(color);
} else if (self->color == BLUE) {
color = PyDict_GetItemString(module_dict, "BLUE");
Py_INCREF(color);
}
return color;
}
If you have a module definition (struct PyModuleDef
) you can just call PyState_FindModule
. I am asuming your struct is named Module
as in your example, so it will look like this:
PyObject * your_function() {
PyObject *module = PyState_FindModule(&Module);
PyObject* module_dict = PyModule_GetDict(module);
...
}
The FindModule documentation says that you need to add the module to the interpreter state as follows:
PyMODINIT_FUNC
PyInit_mymodule(void)
{
PyObject* module = PyModule_Create(&Module);
PyState_AddModule(module, &Module);
...