How to Access Current File Path in Python C Extension
In Python, you can get the current file path with the __file__
attribute.
print(__file__)
How can I access this attribute from a Python C Extension? I tried the following code, but the attribute doesn’t exist.
if (PyObject_HasAttrString(module, "__file__")) {
PyObject *string = PyObject_GetAttrString(module, "__file__");
const char *path = PyUnicode_AsUTF8(string);
}
Solution 1:
It depends on when you want to access the __file__
attribute and exactly how you create the module.
In single-phase initialization (when you call PyModule_Create
within PyInit_yourmodulename
) __file__
is set after the PyInit_*
function is called. Therefore you can only access it after that point, when the module is fully imported.
In multi-phase initialization, where PyInit_yourmodulename
returns a PyModuleDef
object and then the Py_mod_create
slot of that PyModuleDef
is called, you can set the filename from the spec
passed to Py_mod_create
. The ModuleSpec
object has an attribute origin
. This corresponds to the file that the module was loaded from. Thus you can set the __file__
attribute of your module from spec.origin
.
If you're creating your modules outside of the PyInit_yourmodulename
system (for example, creating multiple modules from a single file) then you're out of luck and will have to work out what __file__
is yourself.