[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