Skip to content

Commit fe3abed

Browse files
author
Ralf W. Grosse-Kunstleve
committed
much more informative pickle error messages if pickling is not enabled
[SVN r34004]
1 parent 3fdfb30 commit fe3abed

4 files changed

Lines changed: 31 additions & 1 deletion

File tree

src/object/class.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,10 @@ namespace objects
530530
if (scope().ptr() != Py_None)
531531
scope().attr(name) = result;
532532

533+
// For pickle. Will lead to informative error messages if pickling
534+
// is not enabled.
535+
result.attr("__reduce__") = object(make_instance_reduce_function());
536+
533537
return result;
534538
}
535539
}
@@ -627,7 +631,6 @@ namespace objects
627631

628632
void class_base::enable_pickling_(bool getstate_manages_dict)
629633
{
630-
setattr("__reduce__", object(make_instance_reduce_function()));
631634
setattr("__safe_for_unpickling__", object(true));
632635

633636
if (getstate_manages_dict)

src/object/pickle_support.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <boost/python/tuple.hpp>
99
#include <boost/python/list.hpp>
1010
#include <boost/python/dict.hpp>
11+
#include <boost/python/str.hpp>
1112

1213
namespace boost { namespace python {
1314

@@ -19,6 +20,22 @@ namespace {
1920
object instance_class(instance_obj.attr("__class__"));
2021
result.append(instance_class);
2122
object none;
23+
if (!getattr(instance_obj, "__safe_for_unpickling__", none))
24+
{
25+
str type_name(getattr(instance_class, "__name__"));
26+
str module_name(getattr(instance_class, "__module__", ""));
27+
if (module_name)
28+
module_name += ".";
29+
30+
PyErr_SetObject(
31+
PyExc_RuntimeError,
32+
( "Pickling of \"%s\" instances is not enabled"
33+
" (http://www.boost.org/libs/python/doc/v2/pickle.html)"
34+
% (module_name+type_name)).ptr()
35+
);
36+
37+
throw_error_already_set();
38+
}
2239
object getinitargs = getattr(instance_obj, "__getinitargs__", none);
2340
tuple initargs;
2441
if (getinitargs.ptr() != none.ptr()) {

test/pickle1.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ namespace {
4545
}
4646
};
4747

48+
// To support test of "pickling not enabled" error message.
49+
struct noop {};
4850
}
4951

5052
BOOST_PYTHON_MODULE(pickle1_ext)
@@ -54,4 +56,7 @@ BOOST_PYTHON_MODULE(pickle1_ext)
5456
.def("greet", &world::greet)
5557
.def_pickle(world_pickle_suite())
5658
;
59+
60+
// To support test of "pickling not enabled" error message.
61+
class_<noop>("noop");
5762
}

test/pickle1.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
Hello from California!
1919
>>> print wl.greet()
2020
Hello from California!
21+
22+
>>> noop = pickle1_ext.noop()
23+
>>> try: pickle.dumps(noop)
24+
... except RuntimeError, e: print str(e)[:55]
25+
Pickling of "pickle1_ext.noop" instances is not enabled
2126
'''
2227

2328
def run(args = None):

0 commit comments

Comments
 (0)