[C++-sig] Bug with custom convertor and stl container?
Will Lee
lee.will at gmail.com
Fri Jun 16 19:17:26 CEST 2006
It seems like there's a bug when I use a custom converter (as described in
the FAQ for the custom string) and a wrapped stl container. If I define a
custom converter and use that type in a std::vector or std::map, I'll get an
"TypeError: No Python class registered for C++" error for that converted
type.
For example, in the following case where I'm converting from type A to a
python integer, std::vector<A> and std::map<int, A> are not working
propertly. The testMap and testVec unit tests will both fail. This is
somewhat a showstopper so it would be great if you have any idea on how to
get around this.
Thanks!
ATest.cpp:
#include <boost/python.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <vector>
#include <map>
struct A
{
int value;
A() : value(0){};
A(int v) : value(v) {};
};
bool operator==(const A& v1, const A& v2)
{
return (v1.value == v2.value);
}
struct B
{
A a;
};
// Converter from A to python int
struct AToPython
{
static PyObject* convert(const A& s)
{
return boost::python::incref(boost::python::object((int)s.value).ptr());
}
};
// Conversion from python int to A
struct AFromPython
{
AFromPython()
{
boost::python::converter::registry::push_back(
&convertible,
&construct,
boost::python::type_id< A >());
}
static void* convertible(PyObject* obj_ptr)
{
if (!PyInt_Check(obj_ptr)) return 0;
return obj_ptr;
}
static void construct(
PyObject* obj_ptr,
boost::python::converter::rvalue_from_python_stage1_data* data)
{
void* storage = (
(boost::python::converter::rvalue_from_python_storage< A >*)
data)->storage.bytes;
new (storage) A((int)PyInt_AsLong(obj_ptr));
data->convertible = storage;
}
};
BOOST_PYTHON_MODULE(atest)
{
using namespace boost::python;
to_python_converter< A , AToPython >();
AFromPython();
class_<std::vector< A > >("AVec")
.def(vector_indexing_suite<std::vector<A>, false>())
;
class_< std::map<int, A> >("AMap")
.def(map_indexing_suite<std::map<int, A>, false >())
;
class_< B >("B")
.add_property("a", make_getter(&B::a,
return_value_policy<return_by_value>()),
make_setter(&B::a, return_value_policy<return_by_value>()))
;
}
ATest.py:
#!/usr/bin/env python
import unittest
import atest
class ATest(unittest.TestCase):
def testB(self):
b = atest.B()
self.assert_(b.a == 0)
b.a = 35
self.assert_(b.a == 35)
def testMap(self):
amap = atest.AMap()
amap[3] = 4
self.assert_(amap[3] == 4)
def testVec(self):
amap = atest.AVec()
amap.append(4)
self.assert_(amap[0] == 4)
if __name__ == "__main__":
unittest.main()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20060616/8bb3dcc0/attachment.htm>
More information about the Cplusplus-sig
mailing list