1

In the Boost Python documentation for "Header ", it is described how to expose the subclass of a class.

However, I could not find any documentation on how to do this for multiple classes. See the code below, modelled on the code in the documentation. If I want to write code like

w = nested.Z.W()
z.g()

etc. it does not work, since apparently once the scope has been defined to be X, it does not return to the global scope. So, for example Z now lives in the scope of X. How can I make it return to the global scope? The documentation says

Constructing a scope object with an argument changes the associated global Python object to the one held by the argument, until the lifetime of the scope object ends, at which time the associated global Python object reverts to what it was before the scope object was constructed.

More generally, this is problematic, since what happens to the objects I may define in the module following the construction of this scope object?Will they all end up in the scope of X?

One way to resolve this would be a mechanism to restore global scope. Does anyone know how to do this? Any other way of resolving this would also be fine.

#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/scope.hpp>
using namespace boost::python;

struct X
{
  void f() {}
  struct Y { int g() { return 42; } };
};

struct Z
{
  void f() {}
  struct W { int g() { return 91; } };
};

BOOST_PYTHON_MODULE(nested)
{
  // add some constants to the current (module) scope
  scope().attr("yes") = 1;
  scope().attr("no") = 0;

  // Change the current scope
  scope outer
    = class_<X>("X")
    .def("f", &X::f)
    ;

  // Define a class Y in the current scope, X
   class_<X::Y>("Y")
     .def("g", &X::Y::g)
     ;

  // Change the current scope 
  // (this does not work as one would hope - W ends up inside Z, but Z is now in X.)
  scope outer2
    = class_<Z>("Z")
    .def("f", &Z::f)
    ;

  // Define a class Y in the current scope, X
   class_<Z::W>("W")
     .def("g", &Z::W::g)
     ;
}
Kara
  • 6,115
  • 16
  • 50
  • 57
Faheem Mitha
  • 6,096
  • 7
  • 48
  • 83

1 Answers1

1

Entering and exiting scope is simply handled by the lifetime of the scope object (...another way to say that is: a scope ends when the corresponding scope object is destructed). In the example, if you enclose the "outer" scope within braces, "outer2" will be (back) in the module scope.

BOOST_PYTHON_MODULE(nested)
{
  // add some constants to the current (module) scope
  scope().attr("yes") = 1;
  scope().attr("no") = 0;

  // Change the current scope
  { // -- limit C++ scope of outer
    scope outer
      = class_<X>("X")
      .def("f", &X::f)
      ;

     // Define a class Y in the current scope, X
     class_<X::Y>("Y")
       .def("g", &X::Y::g)
       ;

  } // -- finish scope "outer" --

  // Start new scope
  scope outer2
    = class_<Z>("Z")
    .def("f", &Z::f)
    ;

  // Define a class Y in the current scope, X
   class_<Z::W>("W")
     .def("g", &Z::W::g)
     ;
}

There is a similar answer here: boost::python nested namespace

Community
  • 1
  • 1
OnurC
  • 91
  • 1
  • 2