[C++-sig] [Boost.Python v3] Conversions and Registries

Dave Abrahams dave at boostpro.com
Wed Oct 5 13:21:48 CEST 2011


on Tue Sep 20 2011, "Niall Douglas" <s_sourceforge-AT-nedprod.com> wrote:

> On 19 Sep 2011 at 17:03, Jim Bosch wrote:
>
>> I'd like to see support for static, template-based conversions.  These 
>> would be defined by [partial-]specializing a traits class, and I tend to 
>> think they should only be invoked after attempting all registry-based 
>> conversions. 
>
> Surely not! You'd want to let template specialisaton be the first 
> point of call so the compiler can compile in obvious conversions, 
> *then* and only then do you go to a runtime registry.

I don't understand why you guys would want compile-time converters at
all, really.  Frankly, I think they should all be eliminated.  They 
complicate the model Boost.Python needs to support and cause confusion
when the built-in ones mask runtime conversions.

> This also lets one override the runtime registry when needed in the 
> local compiland. I'm not against having another set of template 
> specialisations do something should the first set of specialisations 
> fail, and/or the runtime registry lookup fails.

There are better ways to deal with conversion specialization, IMO.  The
runtime registry should be scoped, and it should be possible to find the
"nearest eligible converter" based on the python module hierarchy.

>> Users would have to include the same headers in groups of 
>> interdependent modules to avoid specializing the same traits class 
>> multiple times in different ways; I can't think of a way to protect them 
>> from this, but template-based specializations are a sufficiently 
>> advanced featured that I'm comfortable leaving it up to users to avoid 
>> this problem.
>
> Just make sure what you do works with precompiled headers :)

Another problem that you avoid by not supporting compile-time
selection of converters.

>> 3) Considering that we will have a "best-match" overloading system, what 
>> should take precedence, an inexact match in a module-specific registry, 
>> or an exact match in a global registry?  (Clearly this is a moot point 
>> for to-Python conversion).

Nearer scopes should mask more distant scopes.  This is unfortunately
necessary, or you get unpredictable results depending on the context in
which you're running (all the other modules in the system).

> Imagine the following. Program A loads DLL B and DLL C. DLL B is 
> dependent on DLL D which uses BPL. DLL C is dependent on DLL E which 
> uses BPL.

Jeez, I'm going to have to graph this

      A
     / \
    B   C
    |   |
    D   E
    \  /
     BPL

> DLL D tells BPL that class foo is implicitly convertible with an 
> integer.
>
> DLL E tells BPL that class foo is actually a thin wrapper for 
> std::string.
>
> Right now with present BPL, we have to load two copies of BPL, one 
> for DLL D and one for DLL E. They maintain separate type registries, 
> so all is good.

That's not correct.  Boost.Python was designed to deal with scenarios
like this and be run as a single instance in such a system, with a
single registry.

> But what if DLL B returns a python function to Program A, which then 
> installs it as a callback with DLL C?

OMG, could you make this more convoluted, please?

> In the normal case, BPL code in DLL E will call into BPL code DLL D 
> and all is well.
>
> But what if the function in DLL D throws an exception?
>
> This gets converted into a C++ exception by throwing 
> boost::error_already_set.
>
> Now the C++ runtime must figure where to send the exception. But what 
> is the C++ runtime supposed to do with such an exception type? It 
> isn't allowed to see the copy of BPL living in DLL E, so it will fire 
> the exception type into DLL D where it doesn't belong. At this point, 
> the program will almost certainly segfault.

Sorry, you completely lost me here.

> As I mentioned earlier, this is a very semantically similar problem 
> to supporting multiple python interpreters anyway with each calling 
> into one another. 

How exactly is one python interpreter supposed to "call into" another
one?  Are you suggesting they have their own threads and one blocks to
wait for the other, or is it something completely different.

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


More information about the Cplusplus-sig mailing list