Search code examples
pythonc++pybind11

Directory of pybind11 module


I am writing a python module, that is going to be a library, using pybind11.

At some point in my C++ code, I need to know the absolute path of my .so/.dll module (I need that to access to some files in a subdirectory inside the package containing my module). I tried to access to the __file__ attribute in this way:

namespace py = pybind11;

std::string path;

std::string getPath() {
   return path;
}

PYBIND11_MODULE(mymodule, m) {
    path = m.attr("__file__").cast<std::string>();
    //use path in some way to figure out the path the module...


    m.def("get_path", &getPath);
}

but I get the error

ImportError: AttributeError: module 'mymodule' has no attribute '__file__'

Is there any way to know the absolute path of a module written with pybind11?


Solution

  • If you're running solely from C++, this should work assuming your module is named example and can be found on the pythonpath.

    #include <pybind11/embed.h>
    
    namespace py = pybind11;
    
    
    void getModulePath()
    {
      py::scoped_interpreter guard{}; // start the interpreter and keep it alive
      py::object example = py::module::import("example");
      return example.attr("__file__").cast<std::string>();
    }
    

    If your application is running from inside python I think the following should work

    #include <pybind11/pybind11.h>
    
    namespace py = pybind11;
    
    
    void getModulePath()
    {
      py::gil_scoped_acquire acquire;
      py::object example = py::module::import("example");
      return example.attr("__file__").cast<std::string>();
    }
    

    This works because we are using the python interpreter to import the example module so the __file__ attribute will get set