I’ve been using Boost.Python to wrap a C++ library for use in Python for the past few months, and recently needed to have one compiled .so (or .pyd) file behave as a package instead of as a module. That is, I wanted the one file to behave as if it was actually a directory of Python files:
/application
__init__.py
submodule.py
I found a helpful post which uses PyImport_AddModule(“application.submodule”) to initialize a new Python module and boost::python::scope to add classes and method definitions to that module.
Unfortunately in my use “application” is not known at compile time — instead the C++ code is compiled into a static library which is reused for many different applications. However, the same method will work if we first use the __name__ attribute to get the application name.
#include <boost/python.hpp>
using namespace boost::python;
/**
* Methods and classes exposed by application.submodule.
*/
void import_application_submodule() {
def("method1", &method1);
// ...
}
/**
* Methods and classes exposed by application.
*/
void import_application() {
scope current;
std::string submoduleName(extract<const char*>(current.attr("__name__")));
submoduleName.append(".submodule");
// Create the submodule, and attach it to the current scope.
object submodule(borrowed(PyImport_AddModule(submoduleName.c_str())));
current.attr("submodule") = submodule;
{
// Switch the scope to the submodule, add methods and classes.
scope submoduleScope = submodule;
import_application_submodule();
}
}