[C++-sig] [Py++] Registration order corner case

Christopher Bruns cmbruns at stanford.edu
Thu Mar 25 19:34:14 CET 2010


Py++ has produced for me over 97,000 lines of beautiful boost.python
wrapping code on my project, using less than 2500 lines of python.
But I am still experiencing some minor troubles that prevent me from
completing my project.

Suppose I wish to wrap the following:

//###### foo.h ###########
struct Foo1 { struct Foo2; };
struct Foo3 : public Foo1 {};
struct Foo1::Foo2 : public Foo3 {};

then, pyplusplus generates code like this:

//###### foo_module.cpp #######
#include "boost/python.hpp"
#include "foo.h"
namespace bp = boost::python;
BOOST_PYTHON_MODULE(_foo){
    bp::class_< Foo3, bp::bases< Foo1 > >( "Foo3" );
    { //::Foo1
        typedef bp::class_< Foo1 > Foo1_exposer_t;
        Foo1_exposer_t Foo1_exposer = Foo1_exposer_t( "Foo1" );
        bp::scope Foo1_scope( Foo1_exposer );
        bp::class_< Foo1::Foo2, bp::bases< Foo3 > >( "Foo2" );
    }
}

When I try to use this module, "from _foo import *", I get a RuntimeError:
"RuntimeError: extension class wrapper for base class struct Foo1 has
not been created yet"

If I then move the registration of "Foo3" to below the Foo1 block in
the py++ generated code, I get a new RunTimeError:

BOOST_PYTHON_MODULE(_foo){
    { //::Foo1
        typedef bp::class_< Foo1 > Foo1_exposer_t;
        Foo1_exposer_t Foo1_exposer = Foo1_exposer_t( "Foo1" );
        bp::scope Foo1_scope( Foo1_exposer );
        bp::class_< Foo1::Foo2, bp::bases< Foo3 > >( "Foo2" );
    }
    bp::class_< Foo3, bp::bases< Foo1 > >( "Foo3" );
}

"RuntimeError: extension class wrapper for base class struct Foo3 has
not been created yet

The only way to avoid the registration order problem is to register
these classes to boost.python in exactly the order Foo1, Foo3, Foo2
(just like the definitions in C++).

#include "boost/python.hpp"
#include "foo.h"
namespace bp = boost::python;
BOOST_PYTHON_MODULE(_foo){
    typedef bp::class_< Foo1 > Foo1_exposer_t;
    Foo1_exposer_t Foo1_exposer = Foo1_exposer_t( "Foo1" );

    bp::class_< Foo3, bp::bases< Foo1 > >( "Foo3" );

    bp::scope Foo1_scope( Foo1_exposer );
    bp::class_< Foo1::Foo2, bp::bases< Foo3 > >( "Foo2" );
}

Is there a way to coax pyplusplus to produce this registration order?


More information about the Cplusplus-sig mailing list