Search code examples
pythonpython-c-api

How to get installed python package folder path?


How to get installed python package folder path in Python C API?

Suppose I want to open a file data.txt from the Python C-API module.pyd that resides as follows:

package
   |--module.pyd
   |--data
   |    |-data.txt

How do I get the path name of data.txt?



Solution

  • The procedure is similar to that for pure Python as explained in:

    as you can still look up __file__ on a C extension object.

    >>> import wrapt._wrappers
    >>> wrapt._wrappers.__file__
    '/Users/graham/Python/wrapt-py36/lib/python3.6/site-packages/wrapt/_wrappers.cpython-36m-darwin.so'
    

    In C code, you just need to work through the steps using the C API.

    PyObject *module = NULL;
    PyObject *file = NULL;
    
    module = PyImport_ImportModule('package.module');
    
    if (module) {
        PyObject *dict = NULL;
    
        dict = PyModule_GetDict(module);
    
        file = PyDict_GetItemString(dict, "__file__");
    
        if (file) {
            ...
        }
    
        Py_XDECREF(file);
    }
    
    Py_XDECREF(module);
    

    You then need to drop the last segment of the path to get the directory and construct the path to the other file. I don't show code for that, as depends on whether want to do it yourself in C code, or muck around with trying to call the os.path functions from Python.

    Also, it is often better to wrap your C extension within a thin Python package wrapper. That way these sorts of things which are easier to do in Python code can be done there as a function. Your C API code can then call your pure Python function if it really needs to. In other words, can save yourself a lot of work by only putting the stuff that needs to be in C code in the extension and do other work in the Python wrapper.