cloudpipe/cloudpickle

Unable to pickle functions that are decorated with `functools.lru_cache()`

Open

#178 opened on Jun 20, 2018

View on GitHub
 (14 comments) (12 reactions) (0 assignees)Python (1,407 stars) (152 forks)batch import
bughelp wanted

Description

Observed behavior

The cloudpickle module is unable to pickle functions that are cached via the functools.lru_cache decorator function.

The following minimal example triggers the issue on Python 3.6.5 and cloudpickle version 0.5.3:

# minimal.py
from functools import lru_cache
import cloudpickle

@lru_cache()
def cached_func():
    pass

cloudpickle.dumps(cached_func)

Resulting in the following traceback:

$ python minimal.py
Traceback (most recent call last):
  File "minimal.py", line 8, in <module>
    cloudpickle.dumps(cached_func)
  File "/Users/csadorf/miniconda3/lib/python3.6/site-packages/cloudpickle/cloudpickle.py", line 895, in dumps
    cp.dump(obj)
  File "/Users/csadorf/miniconda3/lib/python3.6/site-packages/cloudpickle/cloudpickle.py", line 268, in dump
    return Pickler.dump(self, obj)
  File "/Users/csadorf/miniconda3/lib/python3.6/pickle.py", line 409, in dump
    self.save(obj)
  File "/Users/csadorf/miniconda3/lib/python3.6/pickle.py", line 507, in save
    self.save_global(obj, rv)
  File "/Users/csadorf/miniconda3/lib/python3.6/site-packages/cloudpickle/cloudpickle.py", line 642, in save_global
    return self.save_dynamic_class(obj)
  File "/Users/csadorf/miniconda3/lib/python3.6/site-packages/cloudpickle/cloudpickle.py", line 497, in save_dynamic_class
    self.save_reduce(tp, (obj.__name__, obj.__bases__, type_kwargs), obj=obj)
AttributeError: 'functools._lru_cache_wrapper' object has no attribute '__bases__'

Versions:

$ python -V
Python 3.6.5 :: Anaconda, Inc.
$ python -c "import cloudpickle; print(cloudpickle.__version__)"
0.5.3

Expected behavior

The cloudpickle module should handle cached functions by either pickling or ignoring the cache or at least should fail with a descriptive error message.

Contributor guide