-
Notifications
You must be signed in to change notification settings - Fork 184
Description
I'm using Dask to parallelize computing. And my code is compiled with cython.
When computing, Dask actually asks cloudpickle to dump the compute method, but this operation fails.
The problem is that it looks like cloudpickle cannot dump methods of a class if this class has been compiled with cython. But such methods can be dumped using pickle.
How to reproduce:
Here is the code of the class below. I'd like to pickle the method my_method from an object of this class:
class MyClass:
def __init__(self, a):
self.a = a
def my_method(self, b):
return self.a + bThe following code works properly when importing from the python module:
import cloudpickle
from module import MyClass
my_obj = MyClass(a=10)
cloudpickle.dumps(my_obj.my_method)But this fails if the module is cythonized.
If the module is cythonized and MyClass is imported from there, call to cloudpickle.dumps(my_obj.my_method) generates the following error:
>>> cloudpickle.dumps(my_obj.my_method)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/marc.beillevaire/conda/envs/test_cythn/lib/python3.7/site-packages/cloudpickle/cloudpickle.py", line 961, in dumps
cp.dump(obj)
File "/home/marc.beillevaire/conda/envs/test_cythn/lib/python3.7/site-packages/cloudpickle/cloudpickle.py", line 267, in dump
return Pickler.dump(self, obj)
File "/home/marc.beillevaire/conda/envs/test_cythn/lib/python3.7/pickle.py", line 437, in dump
self.save(obj)
File "/home/marc.beillevaire/conda/envs/test_cythn/lib/python3.7/pickle.py", line 504, in save
f(self, obj) # Call unbound method with explicit self
File "/home/marc.beillevaire/conda/envs/test_cythn/lib/python3.7/site-packages/cloudpickle/cloudpickle.py", line 727, in save_instancemethod
self.save_reduce(types.MethodType, (obj.__func__, obj.__self__), obj=obj)
File "/home/marc.beillevaire/conda/envs/test_cythn/lib/python3.7/pickle.py", line 638, in save_reduce
save(args)
File "/home/marc.beillevaire/conda/envs/test_cythn/lib/python3.7/pickle.py", line 504, in save
f(self, obj) # Call unbound method with explicit self
File "/home/marc.beillevaire/conda/envs/test_cythn/lib/python3.7/pickle.py", line 771, in save_tuple
save(element)
File "/home/marc.beillevaire/conda/envs/test_cythn/lib/python3.7/pickle.py", line 535, in save
self.save_global(obj, rv)
File "/home/marc.beillevaire/conda/envs/test_cythn/lib/python3.7/site-packages/cloudpickle/cloudpickle.py", line 705, in save_global
return Pickler.save_global(self, obj, name=name)
File "/home/marc.beillevaire/conda/envs/test_cythn/lib/python3.7/pickle.py", line 957, in save_global
(obj, module_name, name)) from None
_pickle.PicklingError: Can't pickle <cyfunction MyClass.my_method at 0x7f78f662e608>: it's not found as module.my_method
Here is the simple setup.py file I'm using to generate the cythonized module:
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("src/module.py")
)then: python setup.py build_ext --inplace.
Note that using standard pickle works on both python & cythonized code, ie: import pickle; pickle.dumps(my_obj.my_func) works properly
Did I miss something?
I tried adding __getstate__/__setstate__ that return self.__dict__ but this does not solve the problem.
Does some of you have any clue about this? Thanks for the help :)