on Fri Apr 13 2012, John Reid <j.reid-AT-mail.cryst.bbk.ac.uk> wrote:

> Hi,
>
> If I want to define the same class (Inner) in 2 different scopes
> (Outer1 and Outer 2), I can do it like this:
>
> #include <boost/python.hpp>
>
> struct Outer1 {};
> struct Outer2 {};
> struct Inner {};
>
> BOOST_PYTHON_MODULE( _sandbox )
> {
>     namespace bp = ::boost::python;
>     {
>         bp::scope scope = bp::class_< Outer1 >( "Outer1" );
>         bp::class_< Inner >( "Inner" );
>     }
>
>     {
>         bp::scope scope = bp::class_< Outer2 >( "Outer2" );
>         bp::class_< Inner >( "Inner" );
>     }
> }
>
> Unfortunately when I import the _sandbox module I get the standard error:
>
> RuntimeWarning: to-Python converter for Inner already registered;
> second conversion method ignored.
>
> and in debug build the second Inner registration asserts.

You can't do this; don't even try.  Each C++ class has to have a unique
Python identity.  If you just want to refer to the same class by a
different name, you can of course:

BOOST_PYTHON_MODULE( _sandbox )
{
    namespace bp = ::boost::python;
    object inner;
    {
        bp::scope scope = bp::class_< Outer1 >( "Outer1" );
        inner = bp::class_< Inner >( "Inner" );
    }

    {
        object outer2 = bp::class_< Outer2 >( "Outer2" );
        outer2.attr("Inner") = inner;
    }
}

> Is there any way to test if Inner is already registered and if so just
> place it in the correct scope? Perhaps replacing the second scoped
> block with something like this:
>
>     {
>         bp::object class_Outer2 = bp::class_< Outer2 >( "Outer2" );
>         bp::type_info info = boost::python::type_id< Inner >();
>         const bp::converter::registration * reg =
> bp::converter::registry::query( info );
>         if( NULL == reg ) {
>             bp::class_< Inner >( "Inner" );
>         } else {
>             // Some magic here!
>         }
>     }
>
> Also I should say that the 2 scoped blocks of code aren't adjacent in
> my library so I don't really want to pass objects between them. I'm
> hoping for a solution that just extracts info from the boost.python
> registry.

BOOST_PYTHON_MODULE( _sandbox )
{
    namespace bp = ::boost::python;
    {
        bp::scope scope = bp::class_< Outer1 >( "Outer1" );
        bp::class_< Inner >( "Inner" );
    }

    {
        object outer2 = bp::class_< Outer2 >( "Outer2" );
        outer2.attr("Inner") = scope().attr("Outer1").attr("Inner");
    }
}

HTH-ly y'rs,

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to