Boost.Python Submodules

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();
  }
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s