Commit 2e84def5 authored by Robert Bradshaw's avatar Robert Bradshaw

Prohibit default pickling of classes with non-Python-convertable members.

parent 437fcbe8
...@@ -1568,12 +1568,31 @@ if VALUE is not None: ...@@ -1568,12 +1568,31 @@ if VALUE is not None:
return node return node
def _inject_pickle_methods(self, node): def _inject_pickle_methods(self, node):
env = self.current_env()
all_members = [] all_members = []
cls = node.entry.type cls = node.entry.type
while cls is not None: while cls is not None:
all_members.extend(cls.scope.var_entries) all_members.extend(cls.scope.var_entries)
cls = cls.base_type cls = cls.base_type
all_members.sort(key=lambda e: e.name) all_members.sort(key=lambda e: e.name)
non_py = [
e for e in all_members
if not e.type.is_pyobject and (not e.type.create_from_py_utility_code(env)
or not e.type.create_to_py_utility_code(env))]
if non_py:
msg = "%s cannot be converted to a Python object" % ','.join("self.%s" % e.name for e in non_py)
pickle_func = TreeFragment(u"""
def __reduce__(self):
raise TypeError("%s")
""" % msg,
level='c_class', pipeline=[NormalizeTree(None)]).substitute({})
pickle_func.analyse_declarations(node.scope)
self.visit(pickle_func)
node.body.stats.append(pickle_func)
else:
all_members_names = [e.name for e in all_members] all_members_names = [e.name for e in all_members]
unpickle_func_name = '__pyx_unpickle_%s' % node.class_name unpickle_func_name = '__pyx_unpickle_%s' % node.class_name
......
...@@ -96,3 +96,14 @@ cdef class DefaultReduceSubclass(DefaultReduce): ...@@ -96,3 +96,14 @@ cdef class DefaultReduceSubclass(DefaultReduce):
def __repr__(self): def __repr__(self):
return "DefaultReduceSubclass(i=%s, s=%r, x=%s)" % (self.i, self.s, self.x) return "DefaultReduceSubclass(i=%s, s=%r, x=%s)" % (self.i, self.s, self.x)
cdef class NoReduceDueToIntPtr(object):
"""
>>> import pickle
>>> pickle.dumps(NoReduceDueToIntPtr())
Traceback (most recent call last):
...
TypeError: self.int_ptr cannot be converted to a Python object
"""
cdef int* int_ptr
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment