diff options
Diffstat (limited to 'libs/python/src/object/pickle_support.cpp')
-rw-r--r-- | libs/python/src/object/pickle_support.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/libs/python/src/object/pickle_support.cpp b/libs/python/src/object/pickle_support.cpp new file mode 100644 index 000000000..428c07b6c --- /dev/null +++ b/libs/python/src/object/pickle_support.cpp @@ -0,0 +1,78 @@ +// (C) Copyright R.W. Grosse-Kunstleve 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/python/make_function.hpp> +#include <boost/python/object/class.hpp> +#include <boost/python/tuple.hpp> +#include <boost/python/list.hpp> +#include <boost/python/dict.hpp> +#include <boost/python/str.hpp> + +namespace boost { namespace python { + +namespace { + + tuple instance_reduce(object instance_obj) + { + list result; + object instance_class(instance_obj.attr("__class__")); + result.append(instance_class); + object none; + if (!getattr(instance_obj, "__safe_for_unpickling__", none)) + { + str type_name(getattr(instance_class, "__name__")); + str module_name(getattr(instance_class, "__module__", object(""))); + if (module_name) + module_name += "."; + + PyErr_SetObject( + PyExc_RuntimeError, + ( "Pickling of \"%s\" instances is not enabled" + " (http://www.boost.org/libs/python/doc/v2/pickle.html)" + % (module_name+type_name)).ptr() + ); + + throw_error_already_set(); + } + object getinitargs = getattr(instance_obj, "__getinitargs__", none); + tuple initargs; + if (!getinitargs.is_none()) { + initargs = tuple(getinitargs()); + } + result.append(initargs); + object getstate = getattr(instance_obj, "__getstate__", none); + object instance_dict = getattr(instance_obj, "__dict__", none); + long len_instance_dict = 0; + if (!instance_dict.is_none()) { + len_instance_dict = len(instance_dict); + } + if (!getstate.is_none()) { + if (len_instance_dict > 0) { + object getstate_manages_dict = getattr( + instance_obj, "__getstate_manages_dict__", none); + if (getstate_manages_dict.is_none()) { + PyErr_SetString(PyExc_RuntimeError, + "Incomplete pickle support" + " (__getstate_manages_dict__ not set)"); + throw_error_already_set(); + } + } + result.append(getstate()); + } + else if (len_instance_dict > 0) { + result.append(instance_dict); + } + return tuple(result); + } + +} // namespace + +object const& make_instance_reduce_function() +{ + static object result(&instance_reduce); + return result; +} + +}} // namespace boost::python |