-
Notifications
You must be signed in to change notification settings - Fork 183
Description
Abstract
The following code snipped fails with cloudpickle but works with stock pickle if pydantic is cythonized (either via a platform-specific wheel or by having cython installed when calling setup.py):
# bug.py
import cloudpickle
import pydantic
import pickle
class Bar(pydantic.BaseModel):
a: int
pickle.loads(pickle.dumps(Bar(a=1))) # This works well
cloudpickle.loads(cloudpickle.dumps(Bar(a=1))) # This fails with the error belowWhen using the file via main:
$ python bug.py
The error message is:
_pickle.PicklingError: Can't pickle <cyfunction int_validator at 0x7fc6808f1040>: attribute lookup lambda12 on pydantic.validators failed
Note that the issue does NOT appear when a non-cythonized pydantic version is used.
Also note that the issue does NOT appear when the file is not __main__, for example:
$ python -c "import bug"
Environment
- Linux x64
- Python 3.8.6
- cloudpickle 1.6.0
- pydantic 1.7.3 w/ cython enabled
Technical Background
In contrast to pickle, cloudpickle pickles the actual class when it resides in __main__, see the following note in the README:
Among other things,
cloudpicklesupports pickling for lambda functions
along with functions and classes defined interactively in the
__main__module (for instance in a script, a shell or a Jupyter notebook).
I THINK that might be the reason why this happens. What's somewhat weird is that the object in question is pydantic.validators.int_validator which CAN actually be pickled:
from pydantic.validators import int_validator
import cloudpickle
import pickle
# both work:
pickle.dumps(int_validator)
cloudpickle.dumps(int_validator)