Supplying a Python base class when wrapping a C++ class...
I'd like to wrap a C++ class and have the generated python wrapper class derive from a Python class. I know I can use bases<> to have my wrapped class derive from the class objects associated with the C++ types I specify in bases<>, but in this instance, I want to derive my wrapper class from a Python class that was not generated by boost.python. From looking at the code, it seems like it would be some work to add this capability. (Is anyone working on something like this?) As a workaround, does anyone know a way that I could perhaps hack this in after the Python class is created? That is, can I change the Python base classes of a Python class at runtime? Thanks, Alex
Alex Mohr wrote:
I'd like to wrap a C++ class and have the generated python wrapper class derive from a Python class.
I know I can use bases<> to have my wrapped class derive from the class objects associated with the C++ types I specify in bases<>, but in this instance, I want to derive my wrapper class from a Python class that was not generated by boost.python.
From looking at the code, it seems like it would be some work to add this capability. (Is anyone working on something like this?)
As a workaround, does anyone know a way that I could perhaps hack this in after the Python class is created? That is, can I change the Python base classes of a Python class at runtime?
I believe this depends on what you are trying to accomplish. You can certainly derive a new python class from both, the python wrapper for your C++ class, as well as some other python class. I don't think it's possible to make the generated wrapper itself be derived from a particular python base class (other than 'object'). This is because all wrappers have a common metaclass, provided by boost.python, and python puts some constraints on the relationship between metaclasses of derived types. But multiple inheritance should be able to help. Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin...
I believe this depends on what you are trying to accomplish. You can certainly derive a new python class from both, the python wrapper for your C++ class, as well as some other python class.
Sure, but then can I replace the registration that boost.python has for the type that I wrapped with my new class? To be a bit more concrete: class_<Foo, bases<Bar> >(...); // Build a new python class that derives from the python class for Foo // that boost.python generated AND derives from another Python class. // Now I need to replace boost.python's notion of the python class // associated with Foo to be the multiply-derived python class I just // made.
I don't think it's possible to make the generated wrapper itself be derived from a particular python base class (other than 'object'). This is because all wrappers have a common metaclass, provided by boost.python, and python puts some constraints on the relationship between metaclasses of derived types.
Well, but you do make it derive from bases other than 'object' by supplying bases<X, Y, Z> -- boost.python looks up python classes associated with X, Y, and Z, and derives the new python wrapper class from those python bases. The problem is that I can only specify bases with compile-time type template parameters -- I can't pass arbitrary python classes. Thanks for the info, Alex
Alex Mohr wrote:
I believe this depends on what you are trying to accomplish. You can certainly derive a new python class from both, the python wrapper for your C++ class, as well as some other python class.
Sure, but then can I replace the registration that boost.python has for the type that I wrapped with my new class? To be a bit more concrete:
class_<Foo, bases<Bar> >(...);
// Build a new python class that derives from the python class for Foo // that boost.python generated AND derives from another Python class.
OK.
// Now I need to replace boost.python's notion of the python class // associated with Foo to be the multiply-derived python class I just // made.
Why ?
I don't think it's possible to make the generated wrapper itself be derived from a particular python base class (other than 'object'). This is because all wrappers have a common metaclass, provided by boost.python, and python puts some constraints on the relationship between metaclasses of derived types.
Well, but you do make it derive from bases other than 'object' by supplying bases<X, Y, Z> -- boost.python looks up python classes associated with X, Y, and Z, and derives the new python wrapper class from those python bases.
Sure. But all these bases get exposed to python the same way, using the very same metaclass.
The problem is that I can only specify bases with compile-time type template parameters -- I can't pass arbitrary python classes.
Indeed. I was talking about multiple inheritance within python, not by means of bases<...>. Sorry if that wasn't clear. Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin...
class_<Foo, bases<Bar> >(...);
// Build a new python class that derives from the python class for Foo // that boost.python generated AND derives from another Python class.
OK.
// Now I need to replace boost.python's notion of the python class // associated with Foo to be the multiply-derived python class I just // made.
Why ?
So that when boost.python converts a Foo to-python it generates a wrapper that derives from the extra class that I want it to. Also, so when someone invokes Foo's constructor in python, they get an object that has the bases I desire. I mean, I really want the wrapper for Foo to derive from this other Python class.
Indeed. I was talking about multiple inheritance within python, not by means of bases<...>. Sorry if that wasn't clear.
Sure, but in some sense it's the same thing -- when I say class_<Foo>, boost.python just uses the python C api to build a wrapper class (which derives from the wrapper classes for the types I specified in bases<>). I just want to provide an extra base class. Alex
Alex Mohr <amohr@pixar.com> writes:
I'd like to wrap a C++ class and have the generated python wrapper class derive from a Python class.
I know I can use bases<> to have my wrapped class derive from the class objects associated with the C++ types I specify in bases<>, but in this instance, I want to derive my wrapper class from a Python class that was not generated by boost.python.
From looking at the code, it seems like it would be some work to add this capability. (Is anyone working on something like this?)
That feature has been on my mental TODO list for a long time. Last time I looked, it was implementable.
As a workaround, does anyone know a way that I could perhaps hack this in after the Python class is created? That is, can I change the Python base classes of a Python class at runtime?
I'm not sure about that. -- Dave Abrahams Boost Consulting www.boost-consulting.com
Has anyone figured out how to do this? Alex Mohr-2 wrote:
I'd like to wrap a C++ class and have the generated python wrapper class derive from a Python class.
I know I can use bases<> to have my wrapped class derive from the class objects associated with the C++ types I specify in bases<>, but in this instance, I want to derive my wrapper class from a Python class that was not generated by boost.python.
From looking at the code, it seems like it would be some work to add this capability. (Is anyone working on something like this?)
As a workaround, does anyone know a way that I could perhaps hack this in after the Python class is created? That is, can I change the Python base classes of a Python class at runtime?
Thanks,
Alex _______________________________________________ C++-sig mailing list C++-sig@python.org http://mail.python.org/mailman/listinfo/c++-sig
-- View this message in context: http://www.nabble.com/-C%2B%2B-sig--Supplying-a-Python-base-class-when-wrapp... Sent from the Python - c++-sig mailing list archive at Nabble.com.
On 4/19/07, Rocketman@JSC <snemeth@houston.rr.com> wrote:
Has anyone figured out how to do this?
I recently spent some time on this issue. I was supposed to expose library defined exceptions and make them play well with "try-except" functionality. I found that it is not possible to create Python class which derives from Boost.Python exposed class and Exception. I've got TypeError: "Error when calling the metaclass bases multiple bases have instance lay-out conflict". So I doubt this issue could be solved on C++ level too. Fortunately I found pretty simple( for my case ) work around: http://language-binding.net/pyplusplus/troubleshooting_guide/exceptions/exce... . The page also contains full source code and unit tests. Let me know if this helped you. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/
participants (5)
-
Alex Mohr -
David Abrahams -
Rocketman@JSC -
Roman Yakovenko -
Stefan Seefeld