From f0671ca066c779c1211285e670bca6c744ede784 Mon Sep 17 00:00:00 2001 From: Daniele Nicolodi Date: Sat, 18 Mar 2023 17:50:27 +0100 Subject: [PATCH] BUG: fix IPython's %pylab mode detection There is no pyplot module in the system registry, as the module is imported as matplotlib.pyplot. This code tries to detect when matplotlib.pyplot.show() is invoked in a script run via the %run IPython's magic while in interactive mode as enabled by the %pylab or %matplotlib IPyhton's magic commands. In these modes, matplotlib.pyplot.show() should not block. Failing do detect these modes, a simple test.py script as this import matplotlib.pyplot as plt plt.figure() plt.show() run in IPython as follows %matplotlib %run test.py is not expected to block on matplotlib.pyplot.show(). Without this patch it does. Additionally, the redraw implemented by IPython at the end of %run caused an empty figure to be displayed when the script terminates. Fixing the module lookup in sys.modules fixes the issue. Fixes: 86f26a0227ca640210c670286f0c65dbd5a1de8d. Fixes: #25485. --- lib/matplotlib/backend_bases.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 2c54ecd087a2..a5118c51cfba 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -2930,8 +2930,8 @@ def pyplot_show(cls, *, block=None): # Hack: Are we in IPython's %pylab mode? In pylab mode, IPython # (>= 0.10) tacks a _needmain attribute onto pyplot.show (always # set to False). - ipython_pylab = hasattr( - getattr(sys.modules.get("pyplot"), "show", None), "_needmain") + pyplot_show = getattr(sys.modules.get("matplotlib.pyplot"), "show", None) + ipython_pylab = hasattr(pyplot_show, "_needmain") block = not ipython_pylab and not is_interactive() if block: cls.start_main_loop() @@ -3645,8 +3645,8 @@ def show(cls, *, block=None): # Hack: Are we in IPython's %pylab mode? In pylab mode, IPython # (>= 0.10) tacks a _needmain attribute onto pyplot.show (always # set to False). - ipython_pylab = hasattr( - getattr(sys.modules.get("pyplot"), "show", None), "_needmain") + pyplot_show = getattr(sys.modules.get("matplotlib.pyplot"), "show", None) + ipython_pylab = hasattr(pyplot_show, "_needmain") block = not ipython_pylab and not is_interactive() if block: cls.mainloop()