[C++-sig] map_indexing_suite does not find to-python convertors
Wichert Akkerman
wichert at wiggy.net
Thu Sep 22 15:43:52 CEST 2011
I am struggling to expose a map to python code. What I am doing is
pretty simple: I have a map from an enum type to Glib::ustring, with a
convertors registered to convert Python str and unicode instances to an
ustring, and ustring to Python unicode. I've put the relevant code below.
What I am running into is that the conversion from python to C++ types
is failing with a "No Python class registered for C++ class
Glib::ustring" error. This looks very similar to the FAQ entry "Why is
my automatic to-python conversion not being found?"
(http://www.boost.org/doc/libs/1_47_0/libs/python/doc/v2/faq.html#topythonconversionfailed
), and the workaround suggested there indeed works fine for class
properties. I can't seem to find a similar trick for map values though.
Is there a trick to get this working?
Wichert.
enum aspect_type { ... };
typedef std::map<aspect_type, Glib::ustring> aspect_map;
struct ustring_to_python {
static PyObject* convert(Glib::ustring const& s) {
PyObject* unicode;
unicode=PyUnicode_DecodeUTF8(s.data(), static_cast<Py_ssize_t>(s.size()), "ignore");
Py_INCREF(unicode);
return unicode;
}
};
struct ustring_from_python {
ustring_from_python() {
converter::registry::push_back(&convertible,&construct, type_id<Glib::ustring>());
}
static void* convertible(PyObject *obj) {
if (PyUnicode_Check(obj) || PyString_Check(obj))
return obj;
return 0;
}
static void construct(PyObject* obj, converter::rvalue_from_python_stage1_data *data) {
PyObject *str = 0;
char* value;
if (PyUnicode_Check(obj)) {
str = PyUnicode_AsUTF8String(obj);
if (str==0)
throw_error_already_set();
}
value = PyString_AsString(obj);
if (value==0) {
Py_XDECREF(str);
throw_error_already_set();
}
void* storage = ((converter::rvalue_from_python_storage<Glib::ustring>*)data)->storage.bytes;
new (storage) Glib::ustring(value);
data->convertible = storage;
Py_XDECREF(obj);
}
};
BOOST_PYTHON_MODULE(mymodule) {
to_python_converter<Glib::ustring, ustring_to_python>();
ustring_from_python();
class_<Article::aspect_map>("AspectMap")
.def(map_indexing_suite<aspect_map, true>());
}
More information about the Cplusplus-sig
mailing list