[prev in list] [next in list] [prev in thread] [next in thread] 

List:       python-cpp-sig
Subject:    Re: [C++-sig] two pitfals when extending c++ classes from python
From:       Ralf Grosse-Kunstleve <rwgrosse-kunstleve () lbl ! gov>
Date:       2011-10-25 11:07:48
Message-ID: CAPbyqJF_FtY6gWEk4k0kNy++Mu1DZNs4B=7x2+xg-=_fxZEL7A () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Hi Holger,
chances that Dave, Joel, or me get to work on the tutorial are very small.
But if you send me updated files I'll check them in. Maybe simpler would be
to add to the FAQ.
Ralf

On Tue, Oct 25, 2011 at 3:50 AM, Holger Brandsmeier <brandsmeier@gmx.de>wro=
te:

> Dear list,
>
> The boost_python Tutorial describes nicely and very brief how to
> subclass a boost::python exported class in python.
>
> I stumbeled over two pitfalls, which I did not expect by reading the
> tutorial.
>
> 1) When you put a wrapper class around a pure virtual class, you have
> to remove the "no_init" argument, e.g. for the example in the tutorial
>  class_<BaseWrap, boost::noncopyable>("Base", no_init)
> is wrong, it should be
>  class_<BaseWrap, boost::noncopyable>("Base")
> This is also what is shown in the tutorial, but it is not mentioned,
> that adding 'no_init' makes your wrapper unusable.
>
> If you don't override __init__ in your python class or if you call the
> super constructor in your overriden __init__, then you actually get an
> error when "no_init" is present:
>  RuntimeError: This class cannot be instantiated from Python
> So, yes, you might argue that I should have been warned by this error.
> But unfortunately for me that error was misleading. Given this error I
> assumed that you didn't want me to call the super constructor in my
> __init__ if my super class is pure virtual (why not? pure virtual
> classes simply shouldn't have constructors). Then I spend a lot of
> time debugging, why I couldn't pass my class back to C++ any more
> until I found that the tutorial didn't have a "no_init" argument.
>
> 2) The method that I export as overridable in python takes on argument
> `node` of type  `const parfem::Node&`. The class Node is a virtual
> class. If I simply pass `node` to python then I obtain the misleading
> message
>  TypeError: No to_python (by-value) converter found for C++ type:
> parfem::Node
> This message actually doesn't mean that there is no such converter,
> there is certainly one present. This method probably has to do with
> the fact that Node is exported as "noncopyable" and "no_init".
> Admittedly the problem here is how to handle the lifetime of the
> object and after thinking about it I fully why boost::python has a
> problem here.  My solution was then to pass a smart pointer instance.
> I just wanted to point out that the error message was very misleading
> here for me.
>
> -Holger
>
>
> --
> Holger Brandsmeier, SAM, ETH Z=FCrich
> http://www.sam.math.ethz.ch/people/bholger
> _______________________________________________
> Cplusplus-sig mailing list
> Cplusplus-sig@python.org
> http://mail.python.org/mailman/listinfo/cplusplus-sig

[Attachment #5 (text/html)]

Hi Holger,<div>chances that Dave, Joel, or me get to work on the tutorial are very \
small. But if you send me updated files I&#39;ll check them in. Maybe simpler would \
be to add to the FAQ.</div><div>Ralf<br><br><div class="gmail_quote"> On Tue, Oct 25, \
2011 at 3:50 AM, Holger Brandsmeier <span dir="ltr">&lt;<a \
href="mailto:brandsmeier@gmx.de">brandsmeier@gmx.de</a>&gt;</span> \
wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px \
#ccc solid;padding-left:1ex;"> Dear list,<br>
<br>
The boost_python Tutorial describes nicely and very brief how to<br>
subclass a boost::python exported class in python.<br>
<br>
I stumbeled over two pitfalls, which I did not expect by reading the tutorial.<br>
<br>
1) When you put a wrapper class around a pure virtual class, you have<br>
to remove the &quot;no_init&quot; argument, e.g. for the example in the tutorial<br>
 class_&lt;BaseWrap, boost::noncopyable&gt;(&quot;Base&quot;, no_init)<br>
is wrong, it should be<br>
 class_&lt;BaseWrap, boost::noncopyable&gt;(&quot;Base&quot;)<br>
This is also what is shown in the tutorial, but it is not mentioned,<br>
that adding &#39;no_init&#39; makes your wrapper unusable.<br>
<br>
If you don&#39;t override __init__ in your python class or if you call the<br>
super constructor in your overriden __init__, then you actually get an<br>
error when &quot;no_init&quot; is present:<br>
 RuntimeError: This class cannot be instantiated from Python<br>
So, yes, you might argue that I should have been warned by this error.<br>
But unfortunately for me that error was misleading. Given this error I<br>
assumed that you didn&#39;t want me to call the super constructor in my<br>
__init__ if my super class is pure virtual (why not? pure virtual<br>
classes simply shouldn&#39;t have constructors). Then I spend a lot of<br>
time debugging, why I couldn&#39;t pass my class back to C++ any more<br>
until I found that the tutorial didn&#39;t have a &quot;no_init&quot; argument.<br>
<br>
2) The method that I export as overridable in python takes on argument<br>
`node` of type  `const parfem::Node&amp;`. The class Node is a virtual<br>
class. If I simply pass `node` to python then I obtain the misleading<br>
message<br>
 TypeError: No to_python (by-value) converter found for C++ type: parfem::Node<br>
This message actually doesn&#39;t mean that there is no such converter,<br>
there is certainly one present. This method probably has to do with<br>
the fact that Node is exported as &quot;noncopyable&quot; and \
&quot;no_init&quot;.<br> Admittedly the problem here is how to handle the lifetime of \
the<br> object and after thinking about it I fully why boost::python has a<br>
problem here.  My solution was then to pass a smart pointer instance.<br>
I just wanted to point out that the error message was very misleading<br>
here for me.<br>
<br>
-Holger<br>
<font color="#888888"><br>
<br>
--<br>
Holger Brandsmeier, SAM, ETH Zürich<br>
<a href="http://www.sam.math.ethz.ch/people/bholger" \
target="_blank">http://www.sam.math.ethz.ch/people/bholger</a><br> \
_______________________________________________<br> Cplusplus-sig mailing list<br>
<a href="mailto:Cplusplus-sig@python.org">Cplusplus-sig@python.org</a><br>
<a href="http://mail.python.org/mailman/listinfo/cplusplus-sig" \
target="_blank">http://mail.python.org/mailman/listinfo/cplusplus-sig</a></font></blockquote></div><br></div>




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

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic