[C++-sig] boost::python::object and stl::map warning

Cedric Shock cedric at shockfamily.net
Wed Oct 15 23:33:44 CEST 2003


To whomever can provide some assistance:

The following simple code (included below) attempts to implement a 
std::map of boost::python::object.

I have defined a map of the objects as:
std::map<boost::python::object, boost::python::object> data;

Given boost::python::objects oi and ov, the following works:
data[oi] = ov;

However, the follwing statements all produce a warning (explained below):
ov = data[oi];
data.count(oi);
data[oi].ptr();

So assignment to the map is warning free, however, attempting to read 
from the map raises this warning.

It compiles with g++ 3.2.2, and will work as expected in python. 
However, for each of those offending statements it produces a warning like:

(data.count(oi)):
warning: cannot pass objects of non-POD type `struct 
std::_Rb_tree_iterator<std::pair<const boost::python::api::object, 
boost::python::api::object>, const std::pair<const 
boost::python::api::object, boost::python::api::object>&, const 
std::pair<const boost::python::api::object, 
boost::python::api::object>*>' through `...'; call will abort at runtime

(data[oi].ptr()):
warning: cannot pass objects of non-POD type `struct 
std::_Rb_tree_iterator<std::pair<const boost::python::api::object, 
boost::python::api::object>, std::pair<const boost::python::api::object, 
boost::python::api::object>&, std::pair<const 
boost::python::api::object, boost::python::api::object>*>' through 
`...'; call will abort at runtime


This warning usually indicates that something bad has been done with a 
variable argument function like passing a non-POD type to printf. But it 
should not be an issue here. std::map is routinely used to deal with 
non-POD objects, why can't it handle the boost::python::object?

Thank you in advance for your help,

Cedric A. Shock



#############################################################
#include <map>
#include <boost/python.hpp>

// Interface for map
class PyObjectMap {
	public:
	int contains(PyObject* index);
	PyObject* getitem(PyObject* index);
	void setitem(PyObject* index, PyObject* value);

	private:
	std::map<boost::python::object, boost::python::object> data;
};


// Implelementation of map:
int PyObjectMap::contains(PyObject* index) {
	// Convert PyObject* to an object:
	boost::python::object o(boost::python::borrowed(index));
	// Return whether it is in the map:
	return data.count(o);
}

PyObject* PyObjectMap::getitem(PyObject* index) {
	// Convert PyObject* to an object:
	boost::python::object o(boost::python::borrowed(index));

	if (data.count(o)) {
		// Get the pointer:
		PyObject* ptr;
		ptr = data[o].ptr();
		// We are returning it.
		// That means there's one more reference out there:
		boost::python::incref(ptr);
		//return ptr;
		return ptr;
	} else {
		// Raise an exception: IndexError
		// Not implemented yet
		return 0;
	}

}

void PyObjectMap::setitem(PyObject* index, PyObject* value) {
	// Convert PyObject* to objects:
	boost::python::object oi(boost::python::borrowed(index));
	boost::python::object ov(boost::python::borrowed(value));
	// Store the value
	data[oi] = ov;
}

using namespace boost::python;

BOOST_PYTHON_MODULE(map)
{
	class_<PyObjectMap>("map")
		.def("getitem", &PyObjectMap::getitem)
		.def("__getitem__", &PyObjectMap::getitem)
		.def("setitem", &PyObjectMap::setitem)
		.def("__setitem__", &PyObjectMap::setitem)
		.def("contains", &PyObjectMap::contains)
		.def("__contains__", &PyObjectMap::contains)
	;
}
####################################################





More information about the Cplusplus-sig mailing list