Commit 2002ddfb authored by Robert Bradshaw's avatar Robert Bradshaw

Handle Python subclasses of Cdef classes.

parent d33f4844
......@@ -1603,10 +1603,17 @@ if VALUE is not None:
unpickle_func_name = '__pyx_unpickle_%s' % node.class_name
unpickle_func = TreeFragment(u"""
def %(unpickle_func_name)s(%(args)s):
def %(unpickle_func_name)s(__pyx_type, __pyx_state, %(args)s):
cdef %(class_name)s result
result = %(class_name)s.__new__(%(class_name)s)
result = %(class_name)s.__new__(__pyx_type)
%(assignments)s
if hasattr(result, '__setstate__'):
result.__setstate__(__pyx_state)
elif hasattr(result, '__dict__'):
result.__dict__.update(__pyx_state)
elif __pyx_state is not None:
from pickle import PickleError
raise PickleError("Unexpected state: %%s" %% __pyx_state)
return result
""" % {
'unpickle_func_name': unpickle_func_name,
......@@ -1620,7 +1627,13 @@ if VALUE is not None:
pickle_func = TreeFragment(u"""
def __reduce__(self):
return %s, (%s)
if hasattr(self, '__getstate__'):
state = self.__getstate__()
elif hasattr(self, '__dict__'):
state = self.__dict__
else:
state = None
return %s, (type(self), state, %s)
""" % (unpickle_func_name, ', '.join('self.%s' % v for v in all_members_names)),
level='c_class', pipeline=[NormalizeTree(None)]).substitute({})
pickle_func.analyse_declarations(node.scope)
......
......@@ -68,8 +68,8 @@ cdef class DefaultReduce(object):
DefaultReduce(i=11, s='abc')
"""
cdef int i
cdef str s
cdef readonly int i
cdef readonly str s
def __init__(self, i=0, s=None):
self.i = i
......@@ -98,6 +98,22 @@ cdef class DefaultReduceSubclass(DefaultReduce):
return "DefaultReduceSubclass(i=%s, s=%r, x=%s)" % (self.i, self.s, self.x)
class DefaultReducePySubclass(DefaultReduce):
"""
>>> a = DefaultReducePySubclass(i=11, s='abc', x=1.5); a
DefaultReducePySubclass(i=11, s='abc', x=1.5)
>>> import pickle
>>> pickle.loads(pickle.dumps(a))
DefaultReducePySubclass(i=11, s='abc', x=1.5)
"""
def __init__(self, **kwargs):
self.x = kwargs.pop('x', 0)
super(DefaultReducePySubclass, self).__init__(**kwargs)
def __repr__(self):
return "DefaultReducePySubclass(i=%s, s=%r, x=%s)" % (self.i, self.s, self.x)
cdef class NoReduceDueToIntPtr(object):
"""
>>> import pickle
......
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