From 3fd58ed3e7138af9baad92470419b50384abb4b4 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Tue, 17 May 2022 16:53:04 -0400 Subject: [PATCH 1/2] FIX: enable install_repl_displayhook when switching backends closes #23042 In #22005 we change `pyplot` so that at import time we do not force a switch of the backend and install the repl displayhook. However, this meant that in some cases (primarily through `ipython --pylab`) to end up with a session where `install_repl_displayhook` had never been called. Co-authored-by: Elliott Sales de Andrade --- lib/matplotlib/pyplot.py | 10 ++++------ lib/matplotlib/tests/test_pyplot.py | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 2aedcb5f362a..e5efe37a52cd 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -206,12 +206,6 @@ def _get_backend_mod(): # will (re)import pyplot and then call switch_backend if we need to # resolve the auto sentinel) switch_backend(dict.__getitem__(rcParams, "backend")) - # Just to be safe. Interactive mode can be turned on without calling - # `plt.ion()` so register it again here. This is safe because multiple - # calls to `install_repl_displayhook` are no-ops and the registered - # function respects `mpl.is_interactive()` to determine if it should - # trigger a draw. - install_repl_displayhook() return _backend_mod @@ -302,6 +296,10 @@ class backend_mod(matplotlib.backend_bases._Backend): # See https://github.com/matplotlib/matplotlib/issues/6092 matplotlib.backends.backend = newbackend + # make sure the repl display hook is installed in case we become + # interactive + install_repl_displayhook() + def _warn_if_gui_out_of_main_thread(): if (_get_required_interactive_framework(_get_backend_mod()) diff --git a/lib/matplotlib/tests/test_pyplot.py b/lib/matplotlib/tests/test_pyplot.py index 0dcc0c765afb..64a465284241 100644 --- a/lib/matplotlib/tests/test_pyplot.py +++ b/lib/matplotlib/tests/test_pyplot.py @@ -1,5 +1,6 @@ import difflib import numpy as np +import os import subprocess import sys from pathlib import Path @@ -367,3 +368,26 @@ def test_set_current_axes_on_subfigure(): assert plt.gca() != ax plt.sca(ax) assert plt.gca() == ax + + +def test_pylab_integration(): + pytest.importorskip("IPython") + subprocess.run( + [ + sys.executable, + "-m", + "IPython", + "--pylab", + "-c", + ";".join(( + "import matplotlib.pyplot as plt", + "assert plt._REPL_DISPLAYHOOK == plt._ReplDisplayHook.IPYTHON", + )), + ], + env={**os.environ, "SOURCE_DATE_EPOCH": "0"}, + timeout=5, + check=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True, + ) From 80ebea5df57aa693cf8606eb8afc64e9a9417a93 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Thu, 19 May 2022 17:59:59 -0400 Subject: [PATCH 2/2] CI: try unreasonably long timeout --- lib/matplotlib/tests/test_pyplot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/tests/test_pyplot.py b/lib/matplotlib/tests/test_pyplot.py index 64a465284241..6f9ddd5ccf21 100644 --- a/lib/matplotlib/tests/test_pyplot.py +++ b/lib/matplotlib/tests/test_pyplot.py @@ -385,7 +385,7 @@ def test_pylab_integration(): )), ], env={**os.environ, "SOURCE_DATE_EPOCH": "0"}, - timeout=5, + timeout=60, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,