[pypy-commit] pypy cpyext-pickle: minimal fixes to enable pickling a PyCFunction object
mattip
pypy.commits at gmail.com
Wed May 25 14:36:34 EDT 2016
Author: Matti Picus <matti.picus at gmail.com>
Branch: cpyext-pickle
Changeset: r84689:024c98fad224
Date: 2016-05-25 21:35 +0300
http://bitbucket.org/pypy/pypy/changeset/024c98fad224/
Log: minimal fixes to enable pickling a PyCFunction object
diff --git a/lib-python/2.7/pickle.py b/lib-python/2.7/pickle.py
--- a/lib-python/2.7/pickle.py
+++ b/lib-python/2.7/pickle.py
@@ -285,7 +285,10 @@
if f:
f(self, obj) # Call unbound method with explicit self
return
-
+ elif 'builtin' in str(t):
+ # specifically cpyext builtin types
+ self.save_global(obj)
+ return
# Check copy_reg.dispatch_table
reduce = dispatch_table.get(t)
if reduce:
diff --git a/pypy/module/cpyext/methodobject.py b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -44,8 +44,8 @@
dealloc=cfunction_dealloc)
def cfunction_attach(space, py_obj, w_obj):
+ assert isinstance(w_obj, W_PyCFunctionObject)
py_func = rffi.cast(PyCFunctionObject, py_obj)
- assert isinstance(w_obj, W_PyCFunctionObject)
py_func.c_m_ml = w_obj.ml
py_func.c_m_self = make_ref(space, w_obj.w_self)
py_func.c_m_module = make_ref(space, w_obj.w_module)
diff --git a/pypy/module/cpyext/test/test_arraymodule.py b/pypy/module/cpyext/test/test_arraymodule.py
--- a/pypy/module/cpyext/test/test_arraymodule.py
+++ b/pypy/module/cpyext/test/test_arraymodule.py
@@ -73,5 +73,6 @@
module = self.import_module(name='array')
arr = module.array('i', [1,2,3,4])
s = pickle.dumps(arr)
+ assert s == "carray\n_reconstruct\np0\n(S'i'\np1\n(lp2\nI1\naI2\naI3\naI4\natp3\nRp4\n."
rra = pickle.loads(s) # rra is arr backwards
assert arr.tolist() == rra.tolist()
diff --git a/pypy/objspace/std/objectobject.py b/pypy/objspace/std/objectobject.py
--- a/pypy/objspace/std/objectobject.py
+++ b/pypy/objspace/std/objectobject.py
@@ -182,7 +182,13 @@
if w_reduce is not None:
w_cls = space.getattr(w_obj, space.wrap('__class__'))
w_cls_reduce_meth = space.getattr(w_cls, w_st_reduce)
- w_cls_reduce = space.getattr(w_cls_reduce_meth, space.wrap('im_func'))
+ try:
+ w_cls_reduce = space.getattr(w_cls_reduce_meth, space.wrap('im_func'))
+ except OperationError as e:
+ # i.e. PyCFunction from cpyext
+ if not e.match(space, space.w_AttributeError):
+ raise
+ w_cls_reduce = space.w_None
w_objtype = space.w_object
w_obj_dict = space.getattr(w_objtype, space.wrap('__dict__'))
w_obj_reduce = space.getitem(w_obj_dict, w_st_reduce)
More information about the pypy-commit
mailing list