Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1a6f9f2

Browse files
committed
Handle None entries in sys.modules.
sys.modules entries can be explicitly set to None to block imports, so the `name in sys.modules` check should rather be written `sys.modules.get(name)` (... is not None). While we're at it, disentangle a bit install_repl_displayhook to exit early if `not sys.modules.get("IPython") or not get_ipython()`, which avoids having to throw a local NotIPython exception just to `goto end`. (Also note that the import of `backend2gui` should not throw an ImportError, as that mapping has been around since <2011).
1 parent 69edfa2 commit 1a6f9f2

4 files changed

Lines changed: 44 additions & 51 deletions

File tree

lib/matplotlib/backends/qt_compat.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,16 @@
3535
_ETS = {"pyqt5": QT_API_PYQT5, "pyside2": QT_API_PYSIDE2,
3636
"pyqt": QT_API_PYQTv2, "pyside": QT_API_PYSIDE,
3737
None: None}
38-
# First, check if anything is already imported.
39-
if "PyQt5.QtCore" in sys.modules:
38+
# First, check if anything is already imported. Use ``sys.modules.get(name)``
39+
# rather than ``name in sys.modules`` as entries can also have been explicitly
40+
# set to None.
41+
if sys.modules.get("PyQt5.QtCore"):
4042
QT_API = QT_API_PYQT5
41-
elif "PySide2.QtCore" in sys.modules:
43+
elif sys.modules.get("PySide2.QtCore"):
4244
QT_API = QT_API_PYSIDE2
43-
elif "PyQt4.QtCore" in sys.modules:
45+
elif sys.modules.get("PyQt4.QtCore"):
4446
QT_API = QT_API_PYQTv2
45-
elif "PySide.QtCore" in sys.modules:
47+
elif sys.modules.get("PySide.QtCore"):
4648
QT_API = QT_API_PYSIDE
4749
# Otherwise, check the QT_API environment variable (from Enthought). This can
4850
# only override the binding, not the backend (in other words, we check that the

lib/matplotlib/cbook/__init__.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ def _get_running_interactive_framework():
5454
One of the following values: "qt5", "qt4", "gtk3", "wx", "tk",
5555
"macosx", "headless", ``None``.
5656
"""
57+
# Use ``sys.modules.get(name)`` rather than ``name in sys.modules`` as
58+
# entries can also have been explicitly set to None.
5759
QtWidgets = (sys.modules.get("PyQt5.QtWidgets")
5860
or sys.modules.get("PySide2.QtWidgets"))
5961
if QtWidgets and QtWidgets.QApplication.instance():
@@ -76,9 +78,9 @@ def _get_running_interactive_framework():
7678
if frame.f_code in codes:
7779
return "tk"
7880
frame = frame.f_back
79-
if 'matplotlib.backends._macosx' in sys.modules:
80-
if sys.modules["matplotlib.backends._macosx"].event_loop_is_running():
81-
return "macosx"
81+
macosx = sys.modules.get("matplotlib.backends._macosx")
82+
if macosx and macosx.event_loop_is_running():
83+
return "macosx"
8284
if not _c_internal_utils.display_is_valid():
8385
return "headless"
8486
return None

lib/matplotlib/pyplot.py

Lines changed: 30 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -119,52 +119,41 @@ def install_repl_displayhook():
119119
global _IP_REGISTERED
120120
global _INSTALL_FIG_OBSERVER
121121

122-
class _NotIPython(Exception):
123-
pass
124-
125-
# see if we have IPython hooks around, if use them
126-
127-
try:
128-
if 'IPython' in sys.modules:
129-
from IPython import get_ipython
130-
ip = get_ipython()
131-
if ip is None:
132-
raise _NotIPython()
133-
134-
if _IP_REGISTERED:
135-
return
136-
137-
def post_execute():
138-
if matplotlib.is_interactive():
139-
draw_all()
140-
141-
# IPython >= 2
142-
try:
143-
ip.events.register('post_execute', post_execute)
144-
except AttributeError:
145-
# IPython 1.x
146-
ip.register_post_execute(post_execute)
147-
148-
_IP_REGISTERED = post_execute
149-
_INSTALL_FIG_OBSERVER = False
122+
if _IP_REGISTERED:
123+
return
124+
# See if we have IPython hooks around, if so use them.
125+
# Use ``sys.modules.get(name)`` rather than ``name in sys.modules`` as
126+
# entries can also have been explicitly set to None.
127+
mod_ipython = sys.modules.get("IPython")
128+
if not mod_ipython:
129+
_INSTALL_FIG_OBSERVER = True
130+
return
131+
ip = mod_ipython.get_ipython()
132+
if not ip:
133+
_INSTALL_FIG_OBSERVER = True
134+
return
150135

151-
# trigger IPython's eventloop integration, if available
152-
from IPython.core.pylabtools import backend2gui
136+
def post_execute():
137+
if matplotlib.is_interactive():
138+
draw_all()
153139

154-
ipython_gui_name = backend2gui.get(get_backend())
155-
if ipython_gui_name:
156-
ip.enable_gui(ipython_gui_name)
157-
else:
158-
_INSTALL_FIG_OBSERVER = True
140+
try: # IPython >= 2
141+
ip.events.register("post_execute", post_execute)
142+
except AttributeError: # IPython 1.x
143+
ip.register_post_execute(post_execute)
144+
_IP_REGISTERED = post_execute
145+
_INSTALL_FIG_OBSERVER = False
159146

160-
# import failed or ipython is not running
161-
except (ImportError, _NotIPython):
162-
_INSTALL_FIG_OBSERVER = True
147+
from IPython.core.pylabtools import backend2gui
148+
# trigger IPython's eventloop integration, if available
149+
ipython_gui_name = backend2gui.get(get_backend())
150+
if ipython_gui_name:
151+
ip.enable_gui(ipython_gui_name)
163152

164153

165154
def uninstall_repl_displayhook():
166155
"""
167-
Uninstall the matplotlib display hook.
156+
Uninstall the Matplotlib display hook.
168157
169158
.. warning::
170159
@@ -174,8 +163,8 @@ def uninstall_repl_displayhook():
174163
.. warning::
175164
176165
If you are using vanilla python and have installed another
177-
display hook this will reset ``sys.displayhook`` to what ever
178-
function was there when matplotlib installed it's displayhook,
166+
display hook, this will reset ``sys.displayhook`` to what ever
167+
function was there when Matplotlib installed its displayhook,
179168
possibly discarding your changes.
180169
"""
181170
global _IP_REGISTERED

lib/matplotlib/testing/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def mpl_test_settings(request):
4848

4949
# special case Qt backend importing to avoid conflicts
5050
if backend.lower().startswith('qt4'):
51-
if any(k in sys.modules for k in ('PyQt5', 'PySide2')):
51+
if any(sys.modules.get(k) for k in ('PyQt5', 'PySide2')):
5252
pytest.skip('Qt5 binding already imported')
5353
try:
5454
import PyQt4
@@ -59,7 +59,7 @@ def mpl_test_settings(request):
5959
except ImportError:
6060
pytest.skip("Failed to import a Qt4 binding.")
6161
elif backend.lower().startswith('qt5'):
62-
if any(k in sys.modules for k in ('PyQt4', 'PySide')):
62+
if any(sys.modules.get(k) for k in ('PyQt4', 'PySide')):
6363
pytest.skip('Qt4 binding already imported')
6464
try:
6565
import PyQt5

0 commit comments

Comments
 (0)