diff --git a/lib/matplotlib/cbook/__init__.py b/lib/matplotlib/cbook/__init__.py index 37fd351de3ae..93a219e4a533 100644 --- a/lib/matplotlib/cbook/__init__.py +++ b/lib/matplotlib/cbook/__init__.py @@ -208,9 +208,11 @@ def __getstate__(self): for s, d in self.callbacks.items()}, # It is simpler to reconstruct this from callbacks in __setstate__. "_func_cid_map": None, + "_cid_gen": next(self._cid_gen) } def __setstate__(self, state): + cid_count = state.pop('_cid_gen') vars(self).update(state) self.callbacks = { s: {cid: _weak_or_strong_ref(func, self._remove_proxy) @@ -219,6 +221,7 @@ def __setstate__(self, state): self._func_cid_map = { s: {proxy: cid for cid, proxy in d.items()} for s, d in self.callbacks.items()} + self._cid_gen = itertools.count(cid_count) def connect(self, signal, func): """Register *func* to be called when signal *signal* is generated.""" diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index a24a0050d8f8..0de7a05dd53b 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -106,6 +106,17 @@ def current(self): """Return the active axes, or None if the stack is empty.""" return max(self._axes, key=self._axes.__getitem__, default=None) + def __getstate__(self): + return { + **vars(self), + "_counter": max(self._axes.values(), default=0) + } + + def __setstate__(self, state): + next_counter = state.pop('_counter') + vars(self).update(state) + self._counter = itertools.count(next_counter) + class SubplotParams: """ diff --git a/lib/matplotlib/tests/test_backend_tk.py b/lib/matplotlib/tests/test_backend_tk.py index cd2f5353fc9d..53c86de16fc2 100644 --- a/lib/matplotlib/tests/test_backend_tk.py +++ b/lib/matplotlib/tests/test_backend_tk.py @@ -39,8 +39,8 @@ def _isolated_tk_test(success_count, func=None): reason="$DISPLAY and $WAYLAND_DISPLAY are unset" ) @pytest.mark.xfail( # https://github.com/actions/setup-python/issues/649 - 'TF_BUILD' in os.environ and sys.platform == 'darwin' and - sys.version_info[:2] < (3, 11), + ('TF_BUILD' in os.environ or 'GITHUB_ACTION' in os.environ) and + sys.platform == 'darwin' and sys.version_info[:2] < (3, 11), reason='Tk version mismatch on Azure macOS CI' ) @functools.wraps(func) diff --git a/lib/matplotlib/tests/test_backends_interactive.py b/lib/matplotlib/tests/test_backends_interactive.py index f6fffad31544..0af052d50344 100644 --- a/lib/matplotlib/tests/test_backends_interactive.py +++ b/lib/matplotlib/tests/test_backends_interactive.py @@ -63,8 +63,11 @@ def _get_testable_interactive_backends(): elif env["MPLBACKEND"].startswith('wx') and sys.platform == 'darwin': # ignore on OSX because that's currently broken (github #16849) marks.append(pytest.mark.xfail(reason='github #16849')) - elif (env['MPLBACKEND'] == 'tkagg' and 'TF_BUILD' in os.environ and - sys.platform == 'darwin' and sys.version_info[:2] < (3, 11)): + elif (env['MPLBACKEND'] == 'tkagg' and + ('TF_BUILD' in os.environ or 'GITHUB_ACTION' in os.environ) and + sys.platform == 'darwin' and + sys.version_info[:2] < (3, 11) + ): marks.append( # https://github.com/actions/setup-python/issues/649 pytest.mark.xfail(reason='Tk version mismatch on Azure macOS CI')) envs.append( @@ -271,7 +274,8 @@ def _test_thread_impl(): reason='PyPy does not support Tkinter threading: ' 'https://foss.heptapod.net/pypy/pypy/-/issues/1929', strict=True)) - elif (backend == 'tkagg' and 'TF_BUILD' in os.environ and + elif (backend == 'tkagg' and + ('TF_BUILD' in os.environ or 'GITHUB_ACTION' in os.environ) and sys.platform == 'darwin' and sys.version_info[:2] < (3, 11)): param.marks.append( # https://github.com/actions/setup-python/issues/649 pytest.mark.xfail('Tk version mismatch on Azure macOS CI')) @@ -552,8 +556,11 @@ def _test_number_of_draws_script(): elif backend == "wx": param.marks.append( pytest.mark.skip("wx does not support blitting")) - elif (backend == 'tkagg' and 'TF_BUILD' in os.environ and - sys.platform == 'darwin' and sys.version_info[:2] < (3, 11)): + elif (backend == 'tkagg' and + ('TF_BUILD' in os.environ or 'GITHUB_ACTION' in os.environ) and + sys.platform == 'darwin' and + sys.version_info[:2] < (3, 11) + ): param.marks.append( # https://github.com/actions/setup-python/issues/649 pytest.mark.xfail('Tk version mismatch on Azure macOS CI') ) diff --git a/lib/matplotlib/tests/test_cbook.py b/lib/matplotlib/tests/test_cbook.py index bed05695ca75..3a70358e2530 100644 --- a/lib/matplotlib/tests/test_cbook.py +++ b/lib/matplotlib/tests/test_cbook.py @@ -207,6 +207,13 @@ def is_not_empty(self): assert self.callbacks._func_cid_map != {} assert self.callbacks.callbacks != {} + def test_cid_restore(self): + cb = cbook.CallbackRegistry() + cb.connect('a', lambda: None) + cb2 = pickle.loads(pickle.dumps(cb)) + cid = cb2.connect('c', lambda: None) + assert cid == 1 + @pytest.mark.parametrize('pickle', [True, False]) def test_callback_complete(self, pickle): # ensure we start with an empty registry