From 0015c7801e08309729960f48821174dc72a6d4b3 Mon Sep 17 00:00:00 2001 From: Zachary Pincus Date: Fri, 25 Sep 2015 11:10:10 -0500 Subject: [PATCH] Clarify Qt import logic --- IPython/external/qt_for_kernel.py | 50 +++++++++++++++++-------------- IPython/external/qt_loaders.py | 8 ++--- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/IPython/external/qt_for_kernel.py b/IPython/external/qt_for_kernel.py index 3a50575e85c..4b377d2dd34 100644 --- a/IPython/external/qt_for_kernel.py +++ b/IPython/external/qt_for_kernel.py @@ -13,18 +13,13 @@ Next, ask QT_API env variable if QT_API not set: - ask matplotlib via rcParams['backend.qt4'] - if it said PyQt: - use PyQt4 @v1 - elif it said PySide: - use PySide + ask matplotlib what it's using. If Qt4Agg or Qt5Agg, then use the + version matplotlib is configured with else: (matplotlib said nothing) # this is the default path - nobody told us anything - try: - PyQt @v1 - except: - fallback on PySide + try in this order: + PyQt default version, PySide else: use what QT_API says @@ -45,22 +40,30 @@ QT_API_PYQT_DEFAULT) #Constraints placed on an imported matplotlib -# TODO: Make sure this logic is still in sync with matplotlib's requirements. -# In particular, matplotlib can also now support a qt5 backend, and so this will -# break if matplotlib is imported and running happily with qt5, because -# it only queries for the preferred qt4 option. def matplotlib_options(mpl): if mpl is None: return - mpqt = mpl.rcParams.get('backend.qt4', None) - if mpqt is None: - return None - if mpqt.lower() == 'pyside': - return [QT_API_PYSIDE] - elif mpqt.lower() == 'pyqt4': - return [QT_API_PYQT_DEFAULT] - raise ImportError("unhandled value for backend.qt4 from matplotlib: %r" % - mpqt) + backend = mpl.rcParams.get('backend', None) + if backend == 'Qt4Agg': + mpqt = mpl.rcParams.get('backend.qt4', None) + if mpqt is None: + return None + if mpqt.lower() == 'pyside': + return [QT_API_PYSIDE] + elif mpqt.lower() == 'pyqt4': + return [QT_API_PYQT_DEFAULT] + elif mpqt.lower() == 'pyqtv2': + return [QT_API_PYQT] + raise ImportError("unhandled value for backend.qt4 from matplotlib: %r" % + mpqt) + elif backend == 'Qt5Agg': + mpqt = mpl.rcParams.get('backend.qt5', None) + if mpqt is None: + return None + if mpqt.lower() == 'pyqt5': + return [QT_API_PYQT5] + raise ImportError("unhandled value for backend.qt5 from matplotlib: %r" % + mpqt) def get_options(): """Return a list of acceptable QT APIs, in decreasing order of @@ -79,7 +82,8 @@ def get_options(): qt_api = os.environ.get('QT_API', None) if qt_api is None: - #no ETS variable. Ask mpl, then use either + #no ETS variable. Ask mpl, then use default fallback path + # TODO: should Qt5 be on the fallback path if there is no Qt4 API? return matplotlib_options(mpl) or [QT_API_PYQT_DEFAULT, QT_API_PYSIDE] elif qt_api not in _qt_apis: raise RuntimeError("Invalid Qt API %r, valid values are: %r" % diff --git a/IPython/external/qt_loaders.py b/IPython/external/qt_loaders.py index 34c7be8b207..a5cb3e97c0b 100644 --- a/IPython/external/qt_loaders.py +++ b/IPython/external/qt_loaders.py @@ -15,10 +15,10 @@ from IPython.utils.version import check_version # Available APIs. -QT_API_PYQT = 'pyqt' +QT_API_PYQT = 'pyqt' # Force version 2 QT_API_PYQT5 = 'pyqt5' -QT_API_PYQTv1 = 'pyqtv1' -QT_API_PYQT_DEFAULT = 'pyqtdefault' # don't set SIP explicitly +QT_API_PYQTv1 = 'pyqtv1' # Force version 2 +QT_API_PYQT_DEFAULT = 'pyqtdefault' # use system default for version 1 vs. 2 QT_API_PYSIDE = 'pyside' @@ -73,7 +73,7 @@ def loaded_api(): Returns ------- - None, 'pyside', 'pyqt', or 'pyqtv1' + None, 'pyside', 'pyqt', 'pyqt5', or 'pyqtv1' """ if 'PyQt4.QtCore' in sys.modules: if qtapi_version() == 2: