Cannot pickle and unpickle vectorized functions.
See original GitHub issueProblem
I tried to pickle and unpickle an object that contains attributes of vectorized functions that were created with numpy.frompyfunc
. The pickle.loads
crashed with AttributeError: 'module' object has no attribute 'test (vectorized)'
How to reproduce
I tried to create the minimum example to reproduce the problem and here it is:
import numpy as np
def func(a):
return a*2
vec_func = np.frompyfunc(func, 1, 1)
pickle.loads(pickle.dumps(vec_func))
This crashes with the following error:
AttributeError Traceback (most recent call last)
<ipython-input-33-b5f3d96132c6> in <module>()
4
5 vec_func = np.frompyfunc(func, 1, 1)
----> 6 pickle.loads(pickle.dumps(vec_func))
/usr/lib/python2.7/pickle.pyc in loads(str)
1386 def loads(str):
1387 file = StringIO(str)
-> 1388 return Unpickler(file).load()
1389
1390 # Doctest
/usr/lib/python2.7/pickle.pyc in load(self)
862 while 1:
863 key = read(1)
--> 864 dispatch[key](self)
865 except _Stop, stopinst:
866 return stopinst.value
/usr/lib/python2.7/pickle.pyc in load_reduce(self)
1137 args = stack.pop()
1138 func = stack[-1]
-> 1139 value = func(*args)
1140 stack[-1] = value
1141 dispatch[REDUCE] = load_reduce
/home/sque/workspace/project/venv/local/lib/python2.7/site-packages/numpy/core/__init__.pyc in _ufunc_reconstruct(module, name)
69 # scipy.special.expit for instance.
70 mod = __import__(module, fromlist=[name])
---> 71 return getattr(mod, name)
72
73 def _ufunc_reduce(func):
AttributeError: 'module' object has no attribute 'func (vectorized)'
Possible fix
Probably it has to do with the __name__
that frompyfunc
sets in the new wrapper function.
Issue Analytics
- State:
- Created 7 years ago
- Reactions:2
- Comments:8 (4 by maintainers)
Top Results From Across the Web
Python multiprocessing PicklingError: Can't pickle <type ...
Here is a list of what can be pickled. In particular, functions are only picklable if they are defined at the top-level of...
Read more >pickle — Python object serialization — Python 3.11.1 ...
Source code: Lib/pickle.py The pickle module implements binary protocols for ... It has explicit support for bytes objects and cannot be unpickled by...
Read more >Do Not Use Python Pickle Unless You Know All These Points
Pickle constructs arbitrary Python objects by invoking arbitrary functions, that's why it is not secure. However, this enables it to serialise ...
Read more >numpy.load — NumPy v1.24 Manual
If allow_pickle=True , but the file cannot be loaded as a pickle. ... value supports the context manager protocol in a similar fashion...
Read more >Python's Pickle: Pickling Explained | Analytics Vidhya | - Medium
The pickle module implements binary protocols for serializing and ... XDR (which can't represent pointer sharing); however it means that non-Python programs ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Does it work to pickle functions vectorized with
np.vectorize
? Those use a different wrapper object…Well, I’ve also encountered this issue. My problem started with
np.vectorize
which I could not pickle after I’ve used it once. I’ve posted this issue on dill repository, and the great people there helped me to get more information -np.frompyfunc
whichnp.vectorize
uses when theotypes=[object]
.np.vectorize
uses lazy evaluation.ufunc
is the problem which is created with thenp.frompyfunc
, and numpy way to pickle it defined here - https://github.com/numpy/numpy/blob/112e63eae5e472a8f8405f68a313d904f7fb5bda/numpy/core/__init__.py#L128-L134 This holds only the function name, which is good to module defined function that are attached to the module using C Python API, like here - https://github.com/numpy/numpy/blob/dd5ab7b11520cf9cfa2129303c02ff30b2960d6f/numpy/core/src/multiarray/methods.c#L2832-L2840 I don’t have much knowledge in Python C API, so I don’t know if there is a way to do this attach ofufunc
dynamically to the current module which runsnp.frompyfunc
. Moreover if you’ll try to get module name of thenp.frompyfunc(my_func,1,1)
you’ll get None (also withinspect
).P.S. After all said, I’ve found a way to bypass this by creating a
VectorizeWrapper
which holds the args, kwargs internally and creates thenp.vectorize
itself like this -