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>());


}


_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to