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

Roman Yakovenko roman.yakovenko at gmail.com
Thu Mar 25 22:20:18 CET 2010


On Thu, Mar 25, 2010 at 10:23 PM, Christopher Bruns
<cmbruns at stanford.edu> wrote:
> Thanks Roman for your swift and thoughtful advice.  Your feedback on
> this list is one of many admirable features of Py++.

Thank you!

> I believe that the issue here goes a bit deeper than the classes' sort
> order (see below)

You are right.

> It seems that because Foo2 is an inner class of Foo1, it is always
> registered in the same block as Foo1.  There is no way for Foo3 to get
> registered in between.  Perhaps py++ does not yet have a way to
> separate the declaration of an outer class from the declaration of its
> inner classes.

You are right once again. When I developed the package I thought about
inner classes as some helper classes( small and "final" ).

> Further, because I prefer to use the one-file-per
> class wrapping feature of py++, there would need to be a separate file
> for Foo2, which is ordinarily declared in the file Foo1.pypp.cpp, for
> this case to work in  "split_module" mode.

Is this an option to "drop" base classes:

        mb.class_( 'Foo1' ).bases[0].access_type =
declarations.ACCESS_TYPES.PRIVATE
        mb.class_( 'Foo3' ).bases[0].access_type =
declarations.ACCESS_TYPES.PRIVATE

This will work, but I can't enumerate the things that will not be
exported ( bad memory :-) ).

If not, then there is one more option, but you definitely not going to
like it - to manipulate code creators tree.
It works:    http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1832&view=rev

The following code:
struct foo1_t{ struct foo2_t; };
struct foo3_t : public foo1_t{};
struct foo1_t::foo2_t : public foo3_t{};

was exposed using code_creators tree manipulation:

        mb.build_code_creator( self.EXTENSION_NAME )

        foo3 = mb.code_creator.body.creators[0]

        del mb.code_creator.body.creators[0]

        mb.code_creator.body.creators[0].adopt_creator( foo3, 0)


and the generated code is:


BOOST_PYTHON_MODULE(inner_base_class){
    { //::foo1_t
        typedef bp::class_< foo1_t > foo1_t_exposer_t;
        foo1_t_exposer_t foo1_t_exposer = foo1_t_exposer_t( "foo1_t",
"documentation" );
        bp::scope foo1_t_scope( foo1_t_exposer );
        bp::class_< foo3_t, bp::bases< foo1_t > >( "foo3_t", "documentation" );
        bp::class_< foo1_t::foo2_t, bp::bases< foo3_t > >( "foo2_t",
"documentation" );
    }
}

There is another problem with that code: class foo3_t is exposed under
class foo1_t. You can fix this using a simple Python code:

foo3_t = <your module>.foo1_t.foo3_t

The only other solution is "patching" the generated code.

HTH

-- 
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/


More information about the Cplusplus-sig mailing list