Skip to content

Commit 0bb047d

Browse files
committed
Introducing PYTEST_QT_API configuration variable
Also simplified the code that decided which API to use
1 parent f523fe6 commit 0bb047d

File tree

6 files changed

+80
-70
lines changed

6 files changed

+80
-70
lines changed

.travis.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ virtualenv:
1010
matrix:
1111
allow_failures:
1212
# unfortunately couldn't find a reliable way to test pyqt5 on travis yet
13-
- env: PYTEST_VERSION=2.7.0 PYTEST_QT_FORCE_PYQT=5
13+
- env: PYTEST_VERSION=2.7.0 PYTEST_QT_API=pyqt5
1414

1515
env:
16-
- PYTEST_VERSION=2.6.4 PYTEST_QT_FORCE_PYQT=4
17-
- PYTEST_VERSION=2.6.4 PYTEST_QT_FORCE_PYQT=false
18-
- PYTEST_VERSION=2.7.0 PYTEST_QT_FORCE_PYQT=4
19-
- PYTEST_VERSION=2.7.0 PYTEST_QT_FORCE_PYQT=false
20-
- PYTEST_VERSION=2.7.0 PYTEST_QT_FORCE_PYQT=5
16+
- PYTEST_VERSION=2.6.4 PYTEST_QT_API=pyqt4
17+
- PYTEST_VERSION=2.6.4 PYTEST_QT_API=pyside
18+
- PYTEST_VERSION=2.7.0 PYTEST_QT_API=pyqt4
19+
- PYTEST_VERSION=2.7.0 PYTEST_QT_API=pyside
20+
- PYTEST_VERSION=2.7.0 PYTEST_QT_API=pyqt5
2121

2222
install:
2323
- sudo add-apt-repository --yes ppa:ubuntu-sdk-team/ppa

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ this order:
6464
- ``PyQt4``
6565
- ``PyQt5``
6666

67-
To force a particular version of PyQt_, set the environment variable
68-
``PYTEST_QT_FORCE_PYQT=4`` or ``PYTEST_QT_FORCE_PYQT=5``.
67+
To force a particular API, set the environment variable ``PYTEST_QT_API`` to
68+
``pyside``, ``pyqt4`` or ``pyqt5``.
6969

7070
Documentation
7171
=============

docs/index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ this order:
3434
- ``PyQt4``
3535
- ``PyQt5``
3636

37-
To force a particular version of ``PyQt``, set the environment variable
38-
``PYTEST_QT_FORCE_PYQT=4`` or ``PYTEST_QT_FORCE_PYQT=5``.
37+
To force a particular API, set the environment variable ``PYTEST_QT_API`` to
38+
``pyside``, ``pyqt4`` or ``pyqt5``.
3939

4040
Installation
4141
============

install-qt.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ def run(cmd):
1212
sys.exit('command %s failed with status %s' % (cmd, r))
1313

1414
py3k = sys.version_info[0] == 3
15-
if os.environ['PYTEST_QT_FORCE_PYQT'] != "false":
16-
pyqt_ver = os.environ['PYTEST_QT_FORCE_PYQT']
17-
assert pyqt_ver in ('4', '5'), 'unexpected pyqt_version: %s' % pyqt_ver
15+
if os.environ['PYTEST_QT_API'] in ('pyqt4', 'pyqt5'):
16+
pyqt_ver = os.environ['PYTEST_QT_API'][-1]
1817
if py3k:
1918
run('sudo apt-get install -qq python3-pyqt%s' % pyqt_ver)
2019
else:

pytestqt/plugin.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import pytest
88

9-
from pytestqt.qt_compat import QtCore, QtTest, QApplication
9+
from pytestqt.qt_compat import QtCore, QtTest, QApplication, QT_API
1010

1111

1212
def _inject_qtest_methods(cls):
@@ -203,10 +203,10 @@ def waitForWindowShown(self, widget):
203203
.. note:: In Qt5, the actual method called is qWaitForWindowExposed,
204204
but this name is kept for backward compatibility
205205
"""
206-
if hasattr(QtTest.QTest, 'qWaitForWindowShown'):
206+
if hasattr(QtTest.QTest, 'qWaitForWindowShown'): # pragma: no cover
207207
# PyQt4 and PySide
208208
QtTest.QTest.qWaitForWindowShown(widget)
209-
else:
209+
else: # pragma: no cover
210210
# PyQt5
211211
QtTest.QTest.qWaitForWindowExposed(widget)
212212

@@ -418,4 +418,8 @@ def pytest_configure(config):
418418
config.addinivalue_line(
419419
'markers',
420420
"qt_no_exception_capture: Disables pytest-qt's automatic exception "
421-
'capture for just one test item.')
421+
'capture for just one test item.')
422+
423+
424+
def pytest_report_header():
425+
return ['qt-api: %s' % QT_API]

pytestqt/qt_compat.py

Lines changed: 60 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -11,72 +11,78 @@
1111
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
1212

1313
if not on_rtd: # pragma: no cover
14-
try:
15-
from PySide import QtCore
16-
USING_PYSIDE = True
17-
except ImportError:
18-
USING_PYSIDE = False
19-
20-
FORCE_PYQT = os.environ.get('PYTEST_QT_FORCE_PYQT', 'false') != 'false'
21-
PYQT_VER = None
22-
if not USING_PYSIDE or FORCE_PYQT:
14+
15+
def _try_import(name):
2316
try:
24-
import sip
17+
__import__(name)
18+
return True
2519
except ImportError:
26-
msg = 'pytest-qt requires either PyQt4 or PySide to be installed'
27-
raise ImportError(msg)
20+
return False
2821

29-
if 'PYTEST_QT_FORCE_PYQT' in os.environ:
30-
PYQT_VER = os.environ.get('PYTEST_QT_FORCE_PYQT', '4')
31-
# backward compatibility
32-
if PYQT_VER == 'true':
33-
PYQT_VER = '4'
34-
if PYQT_VER not in ('4', '5'):
35-
msg = 'Unsupported PyQt version in $PYTEST_QT_FORCE_PYQT: %s'
36-
raise RuntimeError(msg % PYQT_VER)
22+
def _guess_qt_api():
23+
if _try_import('PySide'):
24+
return 'pyside'
25+
elif _try_import('PyQt4'):
26+
return 'pyqt4'
27+
elif _try_import('PyQt5'):
28+
return 'pyqt5'
3729
else:
38-
# give preference for PyQt4 for backward compatibility
39-
try:
40-
import PyQt4
41-
PYQT_VER = '4'
42-
except ImportError:
43-
import PyQt5
44-
PYQT_VER = '5'
45-
46-
USING_PYSIDE = False
47-
48-
if USING_PYSIDE:
49-
def _import_module(module_name):
50-
pyside = __import__('PySide', globals(), locals(), [module_name], 0)
51-
return getattr(pyside, module_name)
52-
53-
Signal = QtCore.Signal
54-
Slot = QtCore.Slot
55-
Property = QtCore.Property
30+
msg = 'pytest-qt requires either PySide, PyQt4 or PyQt5 to be installed'
31+
raise ImportError(msg)
32+
33+
# backward compatibility support: PYTEST_QT_FORCE_PYQT
34+
if os.environ.get('PYTEST_QT_FORCE_PYQT', 'false') == 'true':
35+
QT_API = 'pyqt4'
5636
else:
57-
def _import_module(module_name):
58-
pyside = __import__('PyQt%s' % PYQT_VER,
59-
globals(), locals(), [module_name], 0)
60-
return getattr(pyside, module_name)
37+
QT_API = os.environ.get('PYTEST_QT_API')
38+
if QT_API is not None:
39+
QT_API = QT_API.lower()
40+
if QT_API not in ('pyside', 'pyqt4', 'pyqt5'):
41+
msg = 'Invalid value for $PYTEST_QT_API: %s'
42+
raise RuntimeError(msg % QT_API)
43+
else:
44+
QT_API = _guess_qt_api()
6145

62-
QtCore = _import_module('QtCore')
63-
Signal = QtCore.pyqtSignal
64-
Slot = QtCore.pyqtSlot
65-
Property = QtCore.pyqtProperty
66-
67-
46+
# backward compatibility
47+
USING_PYSIDE = QT_API == 'pyside'
48+
49+
def _import_module(module_name):
50+
m = __import__(_root_module, globals(), locals(), [module_name], 0)
51+
return getattr(m, module_name)
52+
53+
_root_modules = {
54+
'pyside': 'PySide',
55+
'pyqt4': 'PyQt4',
56+
'pyqt5': 'PyQt5',
57+
}
58+
_root_module = _root_modules[QT_API]
59+
60+
QtCore = _import_module('QtCore')
6861
QtGui = _import_module('QtGui')
6962
QtTest = _import_module('QtTest')
7063
Qt = QtCore.Qt
7164
QEvent = QtCore.QEvent
72-
if not USING_PYSIDE and PYQT_VER == '5':
73-
_QtWidgets = _import_module('QtWidgets')
74-
QApplication = _QtWidgets.QApplication
75-
QWidget = _QtWidgets.QWidget
76-
else:
65+
66+
if QT_API == 'pyside':
67+
Signal = QtCore.Signal
68+
Slot = QtCore.Slot
69+
Property = QtCore.Property
7770
QApplication = QtGui.QApplication
7871
QWidget = QtGui.QWidget
7972

73+
elif QT_API in ('pyqt4', 'pyqt5'):
74+
Signal = QtCore.pyqtSignal
75+
Slot = QtCore.pyqtSlot
76+
Property = QtCore.pyqtProperty
77+
78+
if QT_API == 'pyqt5':
79+
_QtWidgets = _import_module('QtWidgets')
80+
QApplication = _QtWidgets.QApplication
81+
QWidget = _QtWidgets.QWidget
82+
else:
83+
QApplication = QtGui.QApplication
84+
QWidget = QtGui.QWidget
85+
8086
else: # pragma: no cover
8187
USING_PYSIDE = True
8288

@@ -104,3 +110,4 @@ def __getattr__(cls, name):
104110
QEvent = Mock()
105111
QApplication = Mock()
106112
QWidget = Mock()
113+
QT_API = '<none>'

0 commit comments

Comments
 (0)