I've run into some problem i do not understand. Consider following example, which is a slightly modified pickle2.cpp from boost's libs/python/test/:

#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/extract.hpp>

namespace boost_python_test {

struct dummy // my addition
{
};
  // A friendly class.
  class world
  {
    public:
      world(const std::string& country) : secret_number(0) {
        this->country = country;
      }
      world(dummy) {}; // my addition
      std::string greet() const { return "Hello from " + country + "!"; }
      std::string get_country() const { return country; }
      void set_secret_number(int number) { secret_number = number; }
      int get_secret_number() const { return secret_number; }
    private:
      std::string country;
      int secret_number;
  };

  struct world_pickle_suite : boost::python::pickle_suite
  {
    static
    boost::python::tuple
    getinitargs(const world& w)
    {
        using namespace boost::python;
        return make_tuple(dummy()); // change to use dummy instead of string
    }

    static
    boost::python::tuple
    getstate(const world& w)
    {
        using namespace boost::python;
        return make_tuple(w.get_secret_number());
    }

    static
    void
    setstate(world& w, boost::python::tuple state)
    {
        using namespace boost::python;

                boost::python::object lenRes = state.attr("__len__")(); // old 
boost
        int const stateLen = boost::python::extract<int>(lenRes);
        if (stateLen != 1)
        {
          PyErr_SetObject(PyExc_ValueError,
                          ("expected 1-item tuple in call to __setstate__; got 
%s"
                           % state).ptr()
              );
          throw_error_already_set();
        }
        long number = extract<long>(state[0]);
        if (number != 42)
            w.set_secret_number(number);
    }
  };

}

BOOST_PYTHON_MODULE(pickle2_ext)
{
boost::python::class_< boost_python_test::dummy>( "dummy", 
boost::python::no_init );

    boost::python::class_<boost_python_test::world>(
        "world", boost::python::init<boost_python_test::dummy>())
        .def( boost::python::init< std::string const & >())
        .def("greet", &boost_python_test::world::greet)
        .def("get_secret_number", &boost_python_test::world::get_secret_number)
        .def("set_secret_number", &boost_python_test::world::set_secret_number)
        .def_pickle(boost_python_test::world_pickle_suite())
        ;
}

Code is compiled with gcc41, boost 1.33.1; compile options that might be 
relevant:
-pthread -fno-strict-aliasing -O0 -fno-inline -g0 -m64 -fPIC

then i use follwing test:
import pickle2_ext
import pickle

a = pickle2_ext.world("asd")
a.set_secret_number(54)
print a.get_secret_number()
pickle.dump(a, open('a.p', 'w'), pickle.HIGHEST_PROTOCOL)
r = pickle.load(open('a.p'))
print r.get_secret_number()

This test yields (python 2.4):
54
Traceback (most recent call last):
  File "test.py", line 7, in ?
    r = pickle.load(open('a.p'))
  File "/usr/lib64/python2.4/pickle.py", line 1390, in load
    return Unpickler(file).load()
  File "/usr/lib64/python2.4/pickle.py", line 872, in load
    dispatch[key](self)
  File "/usr/lib64/python2.4/pickle.py", line 1153, in load_reduce
    value = func(*args)
Boost.Python.ArgumentError: Python argument types in
    world.__init__(world, dummy)
did not match C++ signature:
    __init__(_object*, std::string)
    __init__(_object*, boost_python_test::dummy)

The original example, with std::string as a constructor parameter, works fine.
What do i miss?

regards,
Jakub Żytka
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to