[C++-sig] Inconsistency with Boost.Python code

Stefan Seefeld seefeld at sympatico.ca
Thu Oct 9 20:11:52 CEST 2008


Robert wrote:
>
> Will this code below work?
>
>     boost::python::dict GetNamespace( char const* mod )
>     {
>         using namespace boost::python;
>         dict moduleNamespace( extract<dict>( import( mod ).attr( 
> "__dict__" ) ) );
>         return moduleNamespace;
>     }
>
>
> My main concern is the returned value of "import()" going out of scope 
> and being destroyed since there are no outstanding references to it, 
> causing the dict object returned to reference an invalid object. Would 
> this be a possibility?

No. moduleNamespace holds a (counted) reference to the module object, so 
it won't be destroyed (unloaded) while someone still holds references to 
objects within it.

>
> After running the code above I find that it does not work, and I get 
> the following output from python:
>
> TypeError: No to_python (by-value) converter found for C++ type: 
> struct boost::python::extract<class boost::python::dict>

That's probably caused by the above code being a little too compact. 
extract<dict> is actually a distinct type, which provides a conversion 
operator for 'dict'.  (This two-phase conversion is useful as you may 
not yet know whether the conversion would succeed, so the extract<> type 
gives you an opportunity to check that, before actually invoking it.)

In most circumstances this conversion operator is invoked implicitly by 
the compiler, but sometimes it isn't.
A slight change in the syntax should do the trick, such as

dict moduleNamespace = extract<dict>( import( mod ).attr( "__dict__" ) 
); // caution: untested !

or applying the call operator on the temporary extract<> object:

dict moduleNamespace(extract<dict>(import(mod).attr("__dict__")(); // 
caution: untested !


HTH,
       Stefan


-- 

      ...ich hab' noch einen Koffer in Berlin...




More information about the Cplusplus-sig mailing list