Because there is in general no way to deduce that a value of arbitrary type T
is an enumeration constant, the Boost Python Library cannot automatically
convert enum values to and from Python. To handle this case, you need to decide
how you want the enum to show up in Python (since Python doesn't have
enums). Once you have done that, you can write some simple
from_python()
and to_python()
functions.
If you are satisfied with a Python int as a way to represent your enum
values, we provide a shorthand for these functions. You just need to cause
boost::python::enum_as_int_converters<EnumType>
to be
instantiated, where
EnumType
is your enumerated type. There are two convenient ways to do this:
Some buggy C++ implementations require a class to be instantiated in the same namespace in which it is defined. In that case, the simple incantation above becomes:template class boost::python::enum_as_int_converters<my_enum>;
... } // close my_namespace // drop into namespace python and explicitly instantiate namespace boost { namespace python { template class enum_as_int_converters<my_enum_type>; }} // namespace boost::python namespace my_namespace { // re-open my_namespace ...
// instantiate as base class in any namespace struct EnumTypeConverters : boost::python::enum_as_int_converters<EnumType> { };
Either of the above is equivalent to the following declarations:
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround MyEnumType from_python(PyObject* x, boost::python::type<MyEnumType>) { return static_cast<MyEnum>( from_python(x, boost::python::type<long>())); } MyEnumType from_python(PyObject* x, boost::python::type<const MyEnumType&>) { return static_cast<MyEnum>( from_python(x, boost::python::type<long>())); } PyObject* to_python(MyEnumType x) { return to_python(static_cast<long>(x)); } BOOST_PYTHON_END_CONVERSION_NAMESPACE
This technique defines the conversions of
MyEnumType
in terms of the conversions for the built-in
long
type.
You may also want to add a bunch of lines like this to your module
initialization. These bind the corresponding enum values to the appropriate
names so they can be used from Python:
You can also add these to an extension class definition, if your enum happens to be local to a class and you want the analogous interface in Python:mymodule.add(boost::python::to_python(enum_value_1), "enum_value_1"); mymodule.add(boost::python::to_python(enum_value_2), "enum_value_2"); ...
my_class_builder.add(boost::python::to_python(enum_value_1), "enum_value_1"); my_class_builder.add(boost::python::to_python(enum_value_2), "enum_value_2"); ...
Next: Pointers and Smart Pointers Previous: Building an Extension Module Up: Top
© Copyright David Abrahams 2000. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided ``as is'' without express or implied warranty, and with no claim as to its suitability for any purpose.
Updated: Mar 6, 2001