[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

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.


#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
        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 >*)

    new (storage) A((int)PyInt_AsLong(obj_ptr));
    data->convertible = storage;

  using namespace boost::python;
  to_python_converter< A , AToPython >();

  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,
        make_setter(&B::a, return_value_policy<return_by_value>()))

#!/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()
        self.assert_(amap[0] == 4)

if __name__ == "__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