[C++-sig] additional files for pickle support

David Abrahams david.abrahams at rcn.com
Sun Jul 21 14:57:56 CEST 2002


From: "Ralf W. Grosse-Kunstleve" <rwgk at yahoo.com>

> OK, done experimenting. David, now would be a good time to criticize the
new
> files.

Nice!

Question: Why not just have this function accept a tuple argument instead
of doing your own error checking?

    static
    void
    setstate(world& w, boost::python::object state)
    {
        using namespace boost::python;
        extract<tuple> state_proxy(state);
        if (!state_proxy.check() || len(state_proxy()) != 1) {
          PyErr_SetString(PyExc_ValueError,
            "Unexpected argument in call to __setstate__.");
          throw_error_already_set();
        }


> Three additional patches are attached for your reference. The only other
> changes are trivial additions to the Jamfiles.
>
> Locally I am currently working with
> #include <boost/python/detail/api_placeholder.hpp>
> This file implements len() and getattr(). I don't think you want this in
cvs.

I guess not in the long run, but as a temporary measure it's fine.

> So before I can check in the patches that complete the integration of the
> pickle support there need to be replacements for my len() and getattr().

I'm not sure what's happening with Dave H. at the moment, but it will be
easy enough to replace your versions when his are ready.

> P.S.: I noticed that class_::setattr() still deals with handle<> .
> Is this going to change?

I hope so. I'm going to try making class_<> into a class derived from
object, to see how that goes. Then it would be:

    .attr("foo") = ... ;

Hmm, you can't just dump setattr, because the above won't chain. We could
adopt a Phoenix-like construct:

    class_<X>("X")
    [
        attr("foo") = 33,
        def("bar", &bar),
        ...
    ];


But I'm still nervous about that; I think it would put a huge burden on
many compilers.

> Index: class.hpp
> ===================================================================
> RCS file: /cvsroot/boost/boost/boost/python/class.hpp,v
> retrieving revision 1.27
> diff -r1.27 class.hpp
> 27a28
> > # include <boost/python/object/pickle_support.hpp>
> 196a198,210
> >
> >     // Pickle support
> >     template <typename PickleSupport>
> >     self& pickle_support(PickleSupport)
> >     {
> >       detail::pickle_support_finalize<PickleSupport>::register_(
> >         *this,
> >         &PickleSupport::getinitargs,
> >         &PickleSupport::getstate,
> >         &PickleSupport::setstate,
> >         PickleSupport::getstate_manages_dict());
> >       return *this;
> >     }


I know you'll be impatient with me about this, but I would love to find a
better name than "pickle_support". Let's explore a little.

    .pickle_via(world_pickling())
    .def_pickle(world_pickle())

Hmm, I'm out of ideas :(

Well, here's another one, which I'm sure you'll really love <wink>: used a
named parameter interface like that used in Boost.Graph
http://www.boost.org/libs/graph/doc/bgl_named_params.html

class<X>("X")
    .def_pickle(getinitargs(&world_getinitargs)
                .getstate(&world_getstate)
                .setstate(&world_setstate))
    ...
    ;


> Index: object/class.hpp
> ===================================================================
> RCS file: /cvsroot/boost/boost/boost/python/object/class.hpp,v
> retrieving revision 1.22
> diff -r1.22 class.hpp
> 41a42
> >     void enable_pickle_support(bool getstate_manages_dict);
>
>
> Index: src/object/class.cpp
> ===================================================================
> RCS file: /cvsroot/boost/boost/libs/python/src/object/class.cpp,v
> retrieving revision 1.31
> diff -r1.31 class.cpp
> 8a9
> > #include <boost/python/object/pickle_support.hpp>
> 304a306,315
> >   }
> >
> >   void class_base::enable_pickle_support(bool getstate_manages_dict)
> >   {
> >       setattr("__reduce__", make_instance_reduce_function());
> >       handle<> one(PyInt_FromLong(1));
> >       setattr("__safe_for_unpickling__", one);
> >       if (getstate_manages_dict) {
> >         setattr("__getstate_manages_dict__", one);
> >       }

Looks fine to me. I guess I'd go with def_pickle() and pickle as
substitutes for pickle_support() and pickle_support_base. At least, those
are my current favorite ideas.

-Dave







More information about the Cplusplus-sig mailing list