diff --git a/winpython/_vendor/qtpy/QtCore.py b/winpython/_vendor/qtpy/QtCore.py index c1d81e8f..289fcac2 100644 --- a/winpython/_vendor/qtpy/QtCore.py +++ b/winpython/_vendor/qtpy/QtCore.py @@ -24,6 +24,10 @@ del pyqtSignal, pyqtSlot, pyqtProperty, QT_VERSION_STR elif PYSIDE2: from PySide2.QtCore import * + try: # may be limited to PySide-5.11a1 only + from PySide2.QtGui import QStringListModel + except: + pass elif PYQT4: from PyQt4.QtCore import * # Those are things we inherited from Spyder that fix crazy crashes under @@ -58,6 +62,7 @@ class QStandardPaths(): HomeLocation = _QDesktopServices.HomeLocation DataLocation = _QDesktopServices.DataLocation CacheLocation = _QDesktopServices.CacheLocation + writableLocation = _QDesktopServices.storageLocation # Those are imported from `import *` del pyqtSignal, pyqtSlot, pyqtProperty, QT_VERSION_STR, qInstallMsgHandler @@ -88,6 +93,7 @@ class QStandardPaths(): HomeLocation = _QDesktopServices.HomeLocation DataLocation = _QDesktopServices.DataLocation CacheLocation = _QDesktopServices.CacheLocation + writableLocation = _QDesktopServices.storageLocation import PySide.QtCore __version__ = PySide.QtCore.__version__ diff --git a/winpython/_vendor/qtpy/QtGui.py b/winpython/_vendor/qtpy/QtGui.py index 3dfaff07..071be132 100644 --- a/winpython/_vendor/qtpy/QtGui.py +++ b/winpython/_vendor/qtpy/QtGui.py @@ -12,6 +12,7 @@ exposed here. Therefore, you need to treat/use this package as if it were the ``PyQt5.QtGui`` module. """ +import warnings from . import PYQT5, PYQT4, PYSIDE, PYSIDE2, PythonQtError @@ -75,10 +76,21 @@ from PyQt4.QtGui import QDesktopServices as _QDesktopServices class QDesktopServices(): - openUrl = _QDesktopServices.openUrl - setUrlHandler = _QDesktopServices.setUrlHandler - unsetUrlHandler = _QDesktopServices.unsetUrlHandler + openUrl = _QDesktopServices.openUrl + setUrlHandler = _QDesktopServices.setUrlHandler + unsetUrlHandler = _QDesktopServices.unsetUrlHandler + def __getattr__(self, name): + attr = getattr(_QDesktopServices, name) + + new_name = name + if name == 'storageLocation': + new_name = 'writableLocation' + warnings.warn(("Warning QDesktopServices.{} is deprecated in Qt5" + "we recommend you use QDesktopServices.{} instead").format(name, new_name), + DeprecationWarning) + return attr + QDesktopServices = QDesktopServices() elif PYSIDE: from PySide.QtGui import (QAbstractTextDocumentLayout, QActionEvent, QBitmap, @@ -126,8 +138,20 @@ class QDesktopServices(): from PySide.QtGui import QDesktopServices as _QDesktopServices class QDesktopServices(): - openUrl = _QDesktopServices.openUrl - setUrlHandler = _QDesktopServices.setUrlHandler - unsetUrlHandler = _QDesktopServices.unsetUrlHandler + openUrl = _QDesktopServices.openUrl + setUrlHandler = _QDesktopServices.setUrlHandler + unsetUrlHandler = _QDesktopServices.unsetUrlHandler + + def __getattr__(self, name): + attr = getattr(_QDesktopServices, name) + + new_name = name + if name == 'storageLocation': + new_name = 'writableLocation' + warnings.warn(("Warning QDesktopServices.{} is deprecated in Qt5" + "we recommend you use QDesktopServices.{} instead").format(name, new_name), + DeprecationWarning) + return attr + QDesktopServices = QDesktopServices() else: raise PythonQtError('No Qt bindings could be found') diff --git a/winpython/_vendor/qtpy/QtHelp.py b/winpython/_vendor/qtpy/QtHelp.py new file mode 100644 index 00000000..ca9d93dd --- /dev/null +++ b/winpython/_vendor/qtpy/QtHelp.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) + +"""QtHelp Wrapper.""" + +import warnings + +from . import PYQT5 +from . import PYQT4 +from . import PYSIDE +from . import PYSIDE2 + +if PYQT5: + from PyQt5.QtHelp import * +elif PYSIDE2: + from PySide2.QtHelp import * +elif PYQT4: + from PyQt4.QtHelp import * +elif PYSIDE: + from PySide.QtHelp import * diff --git a/winpython/_vendor/qtpy/QtMultimedia.py b/winpython/_vendor/qtpy/QtMultimedia.py index a20cc3bd..9015ece9 100644 --- a/winpython/_vendor/qtpy/QtMultimedia.py +++ b/winpython/_vendor/qtpy/QtMultimedia.py @@ -1,15 +1,14 @@ +import warnings + from . import PYQT5 from . import PYQT4 from . import PYSIDE from . import PYSIDE2 - if PYQT5: from PyQt5.QtMultimedia import * elif PYSIDE2: - # Current wheels don't have this module - # from PySide2.QtMultimedia import * - pass + from PySide2.QtMultimedia import * elif PYQT4: from PyQt4.QtMultimedia import * from PyQt4.QtGui import QSound diff --git a/winpython/_vendor/qtpy/QtSql.py b/winpython/_vendor/qtpy/QtSql.py new file mode 100644 index 00000000..98520bef --- /dev/null +++ b/winpython/_vendor/qtpy/QtSql.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtSql classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PYQT4, PYSIDE, PythonQtError + +if PYQT5: + from PyQt5.QtSql import * +elif PYSIDE2: + from PySide2.QtSql import * +elif PYQT4: + from PyQt4.QtSql import * +elif PYSIDE: + from PySide.QtSql import * +else: + raise PythonQtError('No Qt bindings could be found') + +del PYQT4, PYQT5, PYSIDE, PYSIDE2 diff --git a/winpython/_vendor/qtpy/__init__.py b/winpython/_vendor/qtpy/__init__.py index 1ade9a8c..54ad5486 100644 --- a/winpython/_vendor/qtpy/__init__.py +++ b/winpython/_vendor/qtpy/__init__.py @@ -10,12 +10,13 @@ **QtPy** is a shim over the various Python Qt bindings. It is used to write Qt binding indenpendent libraries or applications. -The shim will automatically select the first available API (PyQt5, PyQt4 and -finally PySide). +If one of the APIs has already been imported, then it will be used. -You can force the use of one specific bindings (e.g. if your application is -using one specific bindings and you need to use library that use QtPy) by -setting up the ``QT_API`` environment variable. +Otherwise, the shim will automatically select the first available API (PyQt5, +PySide2, PyQt4 and finally PySide); in that case, you can force the use of one +specific bindings (e.g. if your application is using one specific bindings and +you need to use library that use QtPy) by setting up the ``QT_API`` environment +variable. PyQt5 ===== @@ -62,10 +63,23 @@ """ import os +import sys +import warnings # Version of QtPy from ._version import __version__ + +class PythonQtError(Exception): + """Error raise if no bindings could be selected""" + pass + + +class PythonQtWarning(Warning): + """Warning if some features are not implemented in a binding.""" + pass + + # Qt API environment variable name QT_API = 'QT_API' @@ -86,7 +100,9 @@ # Setting a default value for QT_API os.environ.setdefault(QT_API, 'pyqt5') + API = os.environ[QT_API].lower() +initial_api = API assert API in (PYQT5_API + PYQT4_API + PYSIDE_API + PYSIDE2_API) is_old_pyqt = is_pyqt46 = False @@ -94,15 +110,20 @@ PYQT4 = PYSIDE = PYSIDE2 = False -class PythonQtError(Exception): - """Error raise if no bindings could be selected""" - pass +if 'PyQt5' in sys.modules: + API = 'pyqt5' +elif 'PySide2' in sys.modules: + API = 'pyside2' +elif 'PyQt4' in sys.modules: + API = 'pyqt4' +elif 'PySide' in sys.modules: + API = 'pyside' if API in PYQT5_API: try: - from PyQt5.Qt import PYQT_VERSION_STR as PYQT_VERSION # analysis:ignore - from PyQt5.Qt import QT_VERSION_STR as QT_VERSION # analysis:ignore + from PyQt5.QtCore import PYQT_VERSION_STR as PYQT_VERSION # analysis:ignore + from PyQt5.QtCore import QT_VERSION_STR as QT_VERSION # analysis:ignore PYSIDE_VERSION = None except ImportError: API = os.environ['QT_API'] = 'pyside2' @@ -129,7 +150,7 @@ class PythonQtError(Exception): sip.setapi('QTextStream', 2) sip.setapi('QTime', 2) sip.setapi('QUrl', 2) - except AttributeError: + except (AttributeError, ValueError): # PyQt < v4.6 pass from PyQt4.Qt import PYQT_VERSION_STR as PYQT_VERSION # analysis:ignore @@ -153,12 +174,18 @@ class PythonQtError(Exception): except ImportError: raise PythonQtError('No Qt bindings could be found') +# If a correct API name is passed to QT_API and it could not be found, +# switches to another and informs through the warning +if API != initial_api: + warnings.warn('Selected binding "{}" could not be found, ' + 'using "{}"'.format(initial_api, API), RuntimeWarning) + API_NAME = {'pyqt5': 'PyQt5', 'pyqt': 'PyQt4', 'pyqt4': 'PyQt4', 'pyside': 'PySide', 'pyside2':'PySide2'}[API] if PYQT4: - import sip - try: - API_NAME += (" (API v{0})".format(sip.getapi('QString'))) - except AttributeError: - pass + import sip + try: + API_NAME += (" (API v{0})".format(sip.getapi('QString'))) + except AttributeError: + pass diff --git a/winpython/_vendor/qtpy/_patch/qheaderview.py b/winpython/_vendor/qtpy/_patch/qheaderview.py index 99cd20a7..b6baddbb 100644 --- a/winpython/_vendor/qtpy/_patch/qheaderview.py +++ b/winpython/_vendor/qtpy/_patch/qheaderview.py @@ -4,6 +4,7 @@ # # Licensed under the terms of the MIT License # (see LICENSE.txt for details) +import warnings def introduce_renamed_methods_qheaderview(QHeaderView): @@ -15,8 +16,9 @@ def sectionsClickable(self): return _isClickable(self) QHeaderView.sectionsClickable = sectionsClickable def isClickable(self): - raise Exception('isClickable is only available in Qt4. Use ' - 'sectionsClickable instead.') + warnings.warn('isClickable is only available in Qt4. Use ' + 'sectionsClickable instead.', stacklevel=2) + return _isClickable(self) QHeaderView.isClickable = isClickable @@ -28,8 +30,9 @@ def sectionsMovable(self): return _isMovable(self) QHeaderView.sectionsMovable = sectionsMovable def isMovable(self): - raise Exception('isMovable is only available in Qt4. Use ' - 'sectionsMovable instead.') + warnings.warn('isMovable is only available in Qt4. Use ' + 'sectionsMovable instead.', stacklevel=2) + return _isMovable(self) QHeaderView.isMovable = isMovable @@ -41,8 +44,9 @@ def sectionResizeMode(self, logicalIndex): return _resizeMode(self, logicalIndex) QHeaderView.sectionResizeMode = sectionResizeMode def resizeMode(self, logicalIndex): - raise Exception('resizeMode is only available in Qt4. Use ' - 'sectionResizeMode instead.') + warnings.warn('resizeMode is only available in Qt4. Use ' + 'sectionResizeMode instead.', stacklevel=2) + return _resizeMode(self, logicalIndex) QHeaderView.resizeMode = resizeMode _setClickable = QHeaderView.setClickable @@ -53,8 +57,9 @@ def setSectionsClickable(self, clickable): return _setClickable(self, clickable) QHeaderView.setSectionsClickable = setSectionsClickable def setClickable(self, clickable): - raise Exception('setClickable is only available in Qt4. Use ' - 'setSectionsClickable instead.') + warnings.warn('setClickable is only available in Qt4. Use ' + 'setSectionsClickable instead.', stacklevel=2) + return _setClickable(self, clickable) QHeaderView.setClickable = setClickable @@ -66,8 +71,9 @@ def setSectionsMovable(self, movable): return _setMovable(self, movable) QHeaderView.setSectionsMovable = setSectionsMovable def setMovable(self, movable): - raise Exception('setMovable is only available in Qt4. Use ' - 'setSectionsMovable instead.') + warnings.warn('setMovable is only available in Qt4. Use ' + 'setSectionsMovable instead.', stacklevel=2) + return _setMovable(self, movable) QHeaderView.setMovable = setMovable @@ -80,8 +86,9 @@ def setSectionResizeMode(self, *args): _setResizeMode(self, *args) QHeaderView.setSectionResizeMode = setSectionResizeMode def setResizeMode(self, *args): - raise Exception('setResizeMode is only available in Qt4. Use ' - 'setSectionResizeMode instead.') + warnings.warn('setResizeMode is only available in Qt4. Use ' + 'setSectionResizeMode instead.', stacklevel=2) + _setResizeMode(self, *args) QHeaderView.setResizeMode = setResizeMode diff --git a/winpython/_vendor/qtpy/_version.py b/winpython/_vendor/qtpy/_version.py index 0465a17f..3e2a74ac 100644 --- a/winpython/_vendor/qtpy/_version.py +++ b/winpython/_vendor/qtpy/_version.py @@ -1,2 +1,2 @@ -version_info = (1, 3, 0) +version_info = (1, 4, 2) __version__ = '.'.join(map(str, version_info)) diff --git a/winpython/_vendor/qtpy/tests/test.ui b/winpython/_vendor/qtpy/tests/test.ui deleted file mode 100644 index 8f0a67c0..00000000 --- a/winpython/_vendor/qtpy/tests/test.ui +++ /dev/null @@ -1,35 +0,0 @@ - - - Form - - - - 0 - 0 - 400 - 300 - - - - Form - - - - - - - - Ceci n'est pas un bouton - - - - - - - - - - - - - diff --git a/winpython/_vendor/qtpy/tests/test_custom.ui b/winpython/_vendor/qtpy/tests/test_custom.ui deleted file mode 100644 index f74b5c72..00000000 --- a/winpython/_vendor/qtpy/tests/test_custom.ui +++ /dev/null @@ -1,42 +0,0 @@ - - - Form - - - - 0 - 0 - 400 - 300 - - - - Form - - - - - - - - Ceci n'est pas un bouton - - - - - - - - - - - - - _QComboBoxSubclass - QComboBox -
qcombobox_subclass
-
-
- - -
diff --git a/winpython/_vendor/qtpy/tests/test_patch_qheaderview.py b/winpython/_vendor/qtpy/tests/test_patch_qheaderview.py index 6c9e6ded..17037f34 100644 --- a/winpython/_vendor/qtpy/tests/test_patch_qheaderview.py +++ b/winpython/_vendor/qtpy/tests/test_patch_qheaderview.py @@ -82,17 +82,17 @@ class Model(QAbstractListModel): # test that the old methods in Qt4 raise exceptions if PYQT4 or PYSIDE: - with pytest.raises(Exception): + with pytest.warns(UserWarning): headerview.isClickable() - with pytest.raises(Exception): + with pytest.warns(UserWarning): headerview.isMovable() - with pytest.raises(Exception): + with pytest.warns(UserWarning): headerview.resizeMode(0) - with pytest.raises(Exception): + with pytest.warns(UserWarning): headerview.setClickable(True) - with pytest.raises(Exception): - headerview.setMovableClickable(True) - with pytest.raises(Exception): + with pytest.warns(UserWarning): + headerview.setMovable(True) + with pytest.warns(UserWarning): headerview.setResizeMode(0, QHeaderView.Interactive) diff --git a/winpython/_vendor/qtpy/tests/test_qdesktopservice_split.py b/winpython/_vendor/qtpy/tests/test_qdesktopservice_split.py index bf12927d..472f2df1 100644 --- a/winpython/_vendor/qtpy/tests/test_qdesktopservice_split.py +++ b/winpython/_vendor/qtpy/tests/test_qdesktopservice_split.py @@ -1,11 +1,12 @@ +"""Test QDesktopServices split in Qt5.""" + from __future__ import absolute_import import pytest -from qtpy import PYSIDE2 +import warnings +from qtpy import PYQT4, PYSIDE -"""Test QDesktopServices split in Qt5.""" -@pytest.mark.skipif(PYSIDE2, reason="It fails on PySide2") def test_qstandarpath(): """Test the qtpy.QStandardPaths namespace""" from qtpy.QtCore import QStandardPaths @@ -16,13 +17,25 @@ def test_qstandarpath(): with pytest.raises(AttributeError) as excinfo: QStandardPaths.setUrlHandler -@pytest.mark.skipif(PYSIDE2, reason="It fails on PySide2") + def test_qdesktopservice(): """Test the qtpy.QDesktopServices namespace""" from qtpy.QtGui import QDesktopServices assert QDesktopServices.setUrlHandler is not None - # Attributes from QStandardPaths shouldn't be in QDesktopServices - with pytest.raises(AttributeError) as excinfo: - QDesktopServices.StandardLocation \ No newline at end of file + +@pytest.mark.skipif(not (PYQT4 or PYSIDE), reason="Warning is only raised in old bindings") +def test_qdesktopservice_qt4_pyside(): + from qtpy.QtGui import QDesktopServices + # Attributes from QStandardPaths should raise a warning when imported + # from QDesktopServices + with warnings.catch_warnings(record=True) as w: + # Cause all warnings to always be triggered. + warnings.simplefilter("always") + # Try to import QtHelp. + QDesktopServices.StandardLocation + + assert len(w) == 1 + assert issubclass(w[-1].category, DeprecationWarning) + assert "deprecated" in str(w[-1].message) diff --git a/winpython/_vendor/qtpy/tests/test_qthelp.py b/winpython/_vendor/qtpy/tests/test_qthelp.py new file mode 100644 index 00000000..2b70ca75 --- /dev/null +++ b/winpython/_vendor/qtpy/tests/test_qthelp.py @@ -0,0 +1,22 @@ +"""Test for QtHelp namespace.""" + +from __future__ import absolute_import + +import pytest + + +def test_qthelp(): + """Test the qtpy.QtHelp namespace.""" + from qtpy import QtHelp + + assert QtHelp.QHelpContentItem is not None + assert QtHelp.QHelpContentModel is not None + assert QtHelp.QHelpContentWidget is not None + assert QtHelp.QHelpEngine is not None + assert QtHelp.QHelpEngineCore is not None + assert QtHelp.QHelpIndexModel is not None + assert QtHelp.QHelpIndexWidget is not None + assert QtHelp.QHelpSearchEngine is not None + assert QtHelp.QHelpSearchQuery is not None + assert QtHelp.QHelpSearchQueryWidget is not None + assert QtHelp.QHelpSearchResultWidget is not None diff --git a/winpython/_vendor/qtpy/tests/test_qtmultimedia.py b/winpython/_vendor/qtpy/tests/test_qtmultimedia.py index 5561e77b..02b415ff 100644 --- a/winpython/_vendor/qtpy/tests/test_qtmultimedia.py +++ b/winpython/_vendor/qtpy/tests/test_qtmultimedia.py @@ -1,12 +1,12 @@ from __future__ import absolute_import import pytest -from qtpy import PYSIDE2, QtMultimedia -@pytest.mark.skipif(PYSIDE2, reason="It fails on PySide2") def test_qtmultimedia(): """Test the qtpy.QtMultimedia namespace""" + from qtpy import QtMultimedia + assert QtMultimedia.QAbstractVideoBuffer is not None assert QtMultimedia.QAudio is not None assert QtMultimedia.QAudioDeviceInfo is not None diff --git a/winpython/_vendor/qtpy/tests/test_qtsql.py b/winpython/_vendor/qtpy/tests/test_qtsql.py new file mode 100644 index 00000000..1e7404ff --- /dev/null +++ b/winpython/_vendor/qtpy/tests/test_qtsql.py @@ -0,0 +1,24 @@ +from __future__ import absolute_import + +import pytest +from qtpy import QtSql + +def test_qtsql(): + """Test the qtpy.QtSql namespace""" + assert QtSql.QSqlDatabase is not None + assert QtSql.QSqlDriverCreatorBase is not None + assert QtSql.QSqlDriver is not None + assert QtSql.QSqlError is not None + assert QtSql.QSqlField is not None + assert QtSql.QSqlIndex is not None + assert QtSql.QSqlQuery is not None + assert QtSql.QSqlRecord is not None + assert QtSql.QSqlResult is not None + assert QtSql.QSqlQueryModel is not None + assert QtSql.QSqlRelationalDelegate is not None + assert QtSql.QSqlRelation is not None + assert QtSql.QSqlRelationalTableModel is not None + assert QtSql.QSqlTableModel is not None + + # Following modules are not (yet) part of any wrapper: + # QSqlDriverCreator, QSqlDriverPlugin diff --git a/winpython/_vendor/qtpy/tests/test_qtsvg.py b/winpython/_vendor/qtpy/tests/test_qtsvg.py index 51b743bb..74d8522e 100644 --- a/winpython/_vendor/qtpy/tests/test_qtsvg.py +++ b/winpython/_vendor/qtpy/tests/test_qtsvg.py @@ -1,9 +1,8 @@ from __future__ import absolute_import import pytest -from qtpy import PYSIDE2 -@pytest.mark.skipif(PYSIDE2, reason="It fails on PySide2") + def test_qtsvg(): """Test the qtpy.QtSvg namespace""" from qtpy import QtSvg @@ -11,4 +10,4 @@ def test_qtsvg(): assert QtSvg.QGraphicsSvgItem is not None assert QtSvg.QSvgGenerator is not None assert QtSvg.QSvgRenderer is not None - assert QtSvg.QSvgWidget is not None \ No newline at end of file + assert QtSvg.QSvgWidget is not None diff --git a/winpython/_vendor/vendor.txt b/winpython/_vendor/vendor.txt index 5407b13c..86bb5250 100644 --- a/winpython/_vendor/vendor.txt +++ b/winpython/_vendor/vendor.txt @@ -1 +1 @@ -qtpy==1.3.0 \ No newline at end of file +qtpy==1.4.2 \ No newline at end of file