On 07/02/10 15:42, Jakub Zytka wrote:

Ok, on newer boost (1.43) error message pointed the actual problem:
even for such simple dummy class some pickling support must be provided, eg.

struct dummy_pickle_suite : boost::python::pickle_suite
{
static
    boost::python::tuple
    getinitargs(const dummy& w)
    {
        return boost::python::tuple();
    }

    static
    boost::python::tuple
    getstate(const dummy& w)
    {
        using namespace boost::python;
        return boost::python::tuple();
    }

    static
    void
    setstate(dummy&, boost::python::tuple)
    {
    }
};

I was mislead by this ArgumentError...

regards,
Jakub Żytka

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

_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to