[C++-sig] [Boost.Python] Patch to add post-initialization hooks for value_holder

Aaron Wishnick awishnick at izotope.com
Wed Feb 13 21:22:34 CET 2013


Hello,

We are using Boost.Python to embed a Python interpreter. We have some
existing classes whose ownership semantics don't play very nicely with
being instantiated from Python, which we really want to do. It's
unfortunately not possible for us to improve this, due to a large existing
codebase; we don't want to harm our existing projects in the process of
adding Python support.

However, what we can do, is tell these instances when they have been
instantiated from within Python, and then everything will work great. We
were able to use no_init and make_constructor to use a custom constructor
that would construct the object, and then call an extra function. However,
we wanted to make this happen globally for all classes that inherit from a
base class that we have, since requiring people to remember to do this
every time a new class is exposed is likely to lead to bugs.

I was able to accomplish this by having value_holder call a function after
constructing its held object. The function,
boost_python_value_holder_post_init(), is called with a pointer to the
newly constructed object, without namespace qualification (to enable ADL),
and the default implementation takes a bool as its parameter, in order to
be the worst possible candidate in overload resolution.

This allows us to implement void
boost_python_value_holder_post_init(BaseClass*) within the same namespace
that BaseClass is defined in, and then our version of the function will get
called any time that a subclass of BaseClass is constructed from within
Boost.Python.

I'm attaching my patch below. I would really appreciate any feedback as to
whether this general concept is something Boost.Python would consider
merging in, and if so, if there's anything I can do  in terms of how my
patch is implemented in order to make it more suitable.

I'd also be happy (and interested!) to discuss any alternate ways to
accomplish what I want. To reiterate, it's really important to us that we
be able to do this for all subclasses of a certain class, automatically,
and this was the only apparent mechanism to me.

The patch follows below. Thanks for your time!

Best regards,
Aaron Wishnick

--- a/boost/python/object/value_holder.hpp
+++ b/boost/python/object/value_holder.hpp
@@ -33,6 +33,17 @@

 namespace boost { namespace python { namespace objects {

+// After a value_holder initializes its held object, this
+// function will be called with a pointer to the held object.
+// Note that it will be called with ADL, so you should define
+// it in the same namespace as that of the object you want to
+// have this called on. This function takes a bool as a catchall
+// because pointer to bool conversion is the "worst" standard
+// conversion, and any other custom overload written by a client
+// should be called instead.
+inline void boost_python_value_holder_post_init(bool) {
+}
+
 #  if BOOST_WORKAROUND(__GNUC__, == 2)
 #   define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n)
(typename unforward<A##n>::type)objects::do_unforward(a##n,0)
 #  else
@@ -137,6 +148,7 @@ void* value_holder_back_reference<Value,Held>::holds(
             BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil)
             )
     {
+         boost_python_value_holder_post_init(&m_held);
         python::detail::initialize_wrapper(self,
boost::addressof(this->m_held));
     }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20130213/d4768a0a/attachment.html>


More information about the Cplusplus-sig mailing list