Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't Ellipsis and NotImplemented be pickled?

Tags:

python

pickle

I was surprised to find that python (version 3.2.2) was refusing to pickle an object because its dict contained a reference to Ellipsis. Of the other built-in constants, pickle is happy working with False, True, and None, as explicitly stated in the pickle documentation, but also chokes on NotImplemented.

Python 3.2.2 (default, Sep  5 2011, 21:17:14) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> pickle.dumps(True)
b'\x80\x03\x88.'
>>> pickle.dumps(False)
b'\x80\x03\x89.'
>>> pickle.dumps(None)
b'\x80\x03N.'
>>> pickle.dumps(Ellipsis)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class 'ellipsis'>: attribute lookup builtins.ellipsis failed
>>> pickle.dumps(NotImplemented)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class 'NotImplementedType'>: attribute lookup builtins.NotImplementedType failed

For completeness, of the less useful built-in constants, __debug__ is just a bool, so causes no problems; copyright, license, and credits work (their type is site._Printer); quit and exit do not (their type is site.Quitter, which can't be found as it is defined inside a function).

Can anyone explain why this is - surely Ellipsis and NotImplemented haven't just been overlooked? The only relevant information I can find is this bug, which complains that NoneType (i.e., type(None)) is not picklable. One of the commenters mentions that type(Ellipsis) and type(NotImplemented) cannot be pickled, apparently without noticing that their instances cannot be either.

like image 473
James Avatar asked Jan 23 '12 14:01

James


1 Answers

There is absolutely no reason for python not to pickle things like Ellipsis and NotImplemented, and frankly not having them picklable contributes to the frailty of python as a parallel / asynchronous language. You can pickle these types of objects with dill, a replacement for pickle. Yes, I'm aware this is a mild rant, but I think a NotImplemented in your target code should not stop you from using multiprocessing or some other from of parallel python… or saving the state of your python session for use at a later time… or whatever.

Python 3.2.5 (default, May 19 2013, 14:25:55) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> dill.dumps(True)
b'\x80\x03\x88.'
>>> dill.dumps(False)
b'\x80\x03\x89.'
>>> dill.dumps(None)
b'\x80\x03N.'
>>> dill.dumps(Ellipsis)
b'\x80\x03cdill.dill\n_eval_repr\nq\x00X\x08\x00\x00\x00Ellipsisq\x01\x85q\x02Rq\x03.'
>>> dill.dumps(NotImplemented)
b'\x80\x03cdill.dill\n_eval_repr\nq\x00X\x0e\x00\x00\x00NotImplementedq\x01\x85q\x02Rq\x03.'

Get dill here: https://github.com/uqfoundation/dill

like image 83
Mike McKerns Avatar answered Oct 22 '22 11:10

Mike McKerns