diff --git a/lib/matplotlib/cbook/__init__.py b/lib/matplotlib/cbook/__init__.py index b8acc03b5269..74a5082c7065 100644 --- a/lib/matplotlib/cbook/__init__.py +++ b/lib/matplotlib/cbook/__init__.py @@ -291,13 +291,18 @@ def __init__(self): self._cid = 0 self._func_cid_map = {} + # In general, callbacks may not be pickled; thus, we simply recreate an + # empty dictionary at unpickling. In order to ensure that `__setstate__` + # (which just defers to `__init__`) is called, `__getstate__` must + # return a truthy value (for pickle protocol>=3, i.e. Py3, the + # *actual* behavior is that `__setstate__` will be called as long as + # `__getstate__` does not return `None`, but this is undocumented -- see + # http://bugs.python.org/issue12290). + def __getstate__(self): - # We cannot currently pickle the callables in the registry, so - # return an empty dictionary. - return {} + return True def __setstate__(self, state): - # re-initialise an empty callback registry self.__init__() def connect(self, s, func): diff --git a/lib/matplotlib/tests/test_cbook.py b/lib/matplotlib/tests/test_cbook.py index 47ff048d349a..d0aff6e3e6ab 100644 --- a/lib/matplotlib/tests/test_cbook.py +++ b/lib/matplotlib/tests/test_cbook.py @@ -1,6 +1,7 @@ from __future__ import (absolute_import, division, print_function, unicode_literals) import itertools +import pickle from weakref import ref import warnings @@ -283,6 +284,10 @@ def test_callback_complete(self): def dummy(self): pass + def test_pickling(self): + assert hasattr(pickle.loads(pickle.dumps(cbook.CallbackRegistry())), + "callbacks") + def test_sanitize_sequence(): d = {'a': 1, 'b': 2, 'c': 3}