[C++-sig] How to define a Python metaclass with Boost.Python?
Jim Bosch
talljimbo at gmail.com
Sat Feb 11 06:09:24 CET 2012
Sorry about the long delay...
On 02/08/2012 09:24 AM, Paul-Cristian Manta wrote:
> In my application I have a base Event class and both C++ and Python
> inherit from this base and define new types of events. Clients can
> subscribe a certain function to a certain type of event.
>
> >>> events = EventDispatcher()
> >>> sub = events.subscribe(KeyboardEvent, on_keyboard_event)
> >>> sub.cancel()
>
> When an event is posted to theEventDispatcher (from either C++ or
> Python), all functions that are subscribed to that event, /or to a base
> of that event/, are called.
>
> Because of how the system is supposed to work, I need a common way to
> determine type and parents of an event at runtime, regardless of whether
> the event class was defined in C++ or Python; I do this with a custom
> EventTypeInfo class.
>
> The metaclass that I would like to define in C++ would add a
> __cpp_event_typeinfo attribute to each event class defined in Python,
> which I can then grab when I need it.
>
> *A possible solution.* I though a good enough way of defining a
> metaclass in Boost.Python would be to the equivalent of this code below.
> Do you think there are any safety problem with doing something like
> this, some compatibly problem that could arise with the other
> Boost.Python classes?
>
> >>> class Meta:
> ... pass
> ...
> >>> Meta = type(Meta.__name__, (type,), dict(Meta.__dict__))
>
This is indeed a perfectly valid way to make a metaclass, and it should
definitely work to do the same thing in C++ using the C API and/or
Boost.Python.
The trouble is using that metaclass as the type of a
Boost.Python-wrapped C++ class...that's what I think is basically
impossible.
Of course, if you just want to inject some attributes into a wrapped
class, you can do that in Boost.Python without a metaclass. You'd write
a function that takes a boost::python::object and adds the attributes
you want to it. Calling that function with a boost::python::class_
object would then add the attribute, just like a metaclass would.
Jim
More information about the Cplusplus-sig
mailing list