diff --git a/IPython/external/qt_for_kernel.py b/IPython/external/qt_for_kernel.py index 61d2f15..1598068 100644 --- a/IPython/external/qt_for_kernel.py +++ b/IPython/external/qt_for_kernel.py @@ -37,7 +37,7 @@ import sys from IPython.utils.warn import warn from IPython.utils.version import check_version from IPython.external.qt_loaders import (load_qt, QT_API_PYSIDE, - QT_API_PYQT, QT_API_PYQTv1, + QT_API_PYQT, QT_API_PYQT_DEFAULT, loaded_api) #Constraints placed on an imported matplotlib @@ -50,7 +50,7 @@ def matplotlib_options(mpl): if mpqt.lower() == 'pyside': return [QT_API_PYSIDE] elif mpqt.lower() == 'pyqt4': - return [QT_API_PYQTv1] + return [QT_API_PYQT_DEFAULT] raise ImportError("unhandled value for backend.qt4 from matplotlib: %r" % mpqt) @@ -65,13 +65,13 @@ def get_options(): mpl = sys.modules.get('matplotlib', None) - if mpl is not None and check_version(mpl.__version__, '1.0.2'): + if mpl is not None and not check_version(mpl.__version__, '1.0.2'): #1.0.1 only supports PyQt4 v1 - return [QT_API_PYQTv1] + return [QT_API_PYQT_DEFAULT] if os.environ.get('QT_API', None) is None: #no ETS variable. Ask mpl, then use either - return matplotlib_options(mpl) or [QT_API_PYQTv1, QT_API_PYSIDE] + return matplotlib_options(mpl) or [QT_API_PYQT_DEFAULT, QT_API_PYSIDE] #ETS variable present. Will fallback to external.qt return None diff --git a/IPython/external/qt_loaders.py b/IPython/external/qt_loaders.py index 1100a31..4459273 100644 --- a/IPython/external/qt_loaders.py +++ b/IPython/external/qt_loaders.py @@ -16,6 +16,7 @@ from IPython.utils.version import check_version # Available APIs. QT_API_PYQT = 'pyqt' QT_API_PYQTv1 = 'pyqtv1' +QT_API_PYQT_DEFAULT = 'pyqtdefault' # don't set SIP explicitly QT_API_PYSIDE = 'pyside' @@ -23,7 +24,6 @@ class ImportDenier(object): """Import Hook that will guard against bad Qt imports once IPython commits to a specific binding """ - __forbidden = set() def __init__(self): self.__forbidden = None @@ -84,7 +84,7 @@ def has_binding(api): Parameters ---------- - api : str [ 'pyqtv1' | 'pyqt' | 'pyside'] + api : str [ 'pyqtv1' | 'pyqt' | 'pyside' | 'pyqtdefault'] Which module to check for Returns @@ -96,7 +96,8 @@ def has_binding(api): # check for complete presence before importing module_name = {QT_API_PYSIDE: 'PySide', QT_API_PYQT: 'PyQt4', - QT_API_PYQTv1: 'PyQt4'} + QT_API_PYQTv1: 'PyQt4', + QT_API_PYQT_DEFAULT: 'PyQt4'} module_name = module_name[api] import imp @@ -136,22 +137,36 @@ def qtapi_version(): def can_import(api): """Safely query whether an API is importable, without importing it""" + if not has_binding(api): + return False + current = loaded_api() - return has_binding(api) and current in [api, None] + if api == QT_API_PYQT_DEFAULT: + return current in [QT_API_PYQT, QT_API_PYQTv1, None] + else: + return current in [api, None] def import_pyqt4(version=2): """ Import PyQt4 + Parameters + ---------- + version : 1, 2, or None + Which QString/QVariant API to use. Set to None to use the system + default + ImportErrors rasied within this function are non-recoverable """ # The new-style string API (version=2) automatically # converts QStrings to Unicode Python strings. Also, automatically unpacks # QVariants to their underlying objects. import sip - sip.setapi('QString', version) - sip.setapi('QVariant', version) + + if version is not None: + sip.setapi('QString', version) + sip.setapi('QVariant', version) from PyQt4 import QtGui, QtCore, QtSvg @@ -163,6 +178,8 @@ def import_pyqt4(version=2): QtCore.Signal = QtCore.pyqtSignal QtCore.Slot = QtCore.pyqtSlot + # query for the API version (in case version == None) + version = sip.getapi('QString') api = QT_API_PYQTv1 if version == 1 else QT_API_PYQT return QtCore, QtGui, QtSvg, api @@ -205,21 +222,24 @@ def load_qt(api_options): """ loaders = {QT_API_PYSIDE: import_pyside, QT_API_PYQT: import_pyqt4, - QT_API_PYQTv1: partial(import_pyqt4, version=1) + QT_API_PYQTv1: partial(import_pyqt4, version=1), + QT_API_PYQT_DEFAULT: partial(import_pyqt4, version=None) } for api in api_options: if api not in loaders: raise RuntimeError( - "Invalid Qt API %r, valid values are: %r, %r, %r" % - (api, QT_API_PYSIDE, QT_API_PYQT, QT_API_PYQTv1)) + "Invalid Qt API %r, valid values are: %r, %r, %r, %r" % + (api, QT_API_PYSIDE, QT_API_PYQT, + QT_API_PYQTv1, QT_API_PYQT_DEFAULT)) if not can_import(api): continue #cannot safely recover from an ImportError during this result = loaders[api]() + api = result[-1] # changed if api = QT_API_PYQT_DEFAULT commit_api(api) return result else: