Search code examples
pythonpicklefunctools

Are partial functions "officially" picklable?


I need to create a bunch of partial functions that can be pickled. Empirically testing this, it seems to work fine:

import pickle
import functools

pickle.dumps(functools.partial(int, base=2))
# b'\x80\x03cfunctools\npartial\nq\x00cbuiltins\nint\nq\x01\x85q\x02Rq\x03(h\x01)}q\x04X\x04\x00\x00\x00baseq\x05K\x02sNtq\x06b.'

However, this is not stated explicitly in the documentation, and the given "roughly equivalent" function of functools.partial() is not picklable.

Can I assume that partial objects are picklable in any circumstances (no edge cases, independently of the C / Python implementation)?


Solution

  • The code snippet in the documentation simulating the partial() function is not picklable as it uses nested function. However, the official functools.partial() is implemented using a class which is pickable: cpython/functools.py#L234

    The official Python issue tracker contains several references for partial objects not beeing picklable, and this has been considered as a bug:

    Also, there are unit tests to check picklability of partial objects: cpython/test_functools.py#L244

    The changelog for Python 3.6 contains reference to the picklability of functools.partial objects:

    bpo-27137: the pure Python fallback implementation of functools.partial now matches the behaviour of its accelerated C counterpart for subclassing, pickling and text representation purposes.

    For these reasons, I think one can safely assume that partial picklability is not an implementation detail and can be relied upon.