Skip to content

Commit

Permalink
Merge pull request #340 from larsoner/environ
Browse files Browse the repository at this point in the history
PR: Fix bug with environ handling
  • Loading branch information
dalthviz authored Apr 28, 2022
2 parents aed5492 + 2a98aad commit 25d402e
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 13 deletions.
32 changes: 22 additions & 10 deletions qtpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ class PythonQtWarning(Warning):
"""Warning if some features are not implemented in a binding."""


class PythonQtValueError(ValueError):
"""Error raised if an invalid QT_API is specified."""


# Qt API environment variable name
QT_API = 'QT_API'

Expand All @@ -98,14 +102,14 @@ class PythonQtWarning(Warning):
# Detecting if a binding was specified by the user
binding_specified = QT_API in os.environ

# Setting a default value for QT_API
os.environ.setdefault(QT_API, 'pyqt5')

API_NAMES = {'pyqt5': 'PyQt5', 'pyqt6': 'PyQt6',
'pyside2':'PySide2', 'pyside6': 'PySide6'}
API = os.environ[QT_API].lower()
'pyside2': 'PySide2', 'pyside6': 'PySide6'}
API = os.environ.get(QT_API, 'pyqt5').lower()
initial_api = API
assert API in API_NAMES
if API not in API_NAMES:
raise PythonQtValueError(
f'Specified QT_API={repr(QT_API.lower())} is not in valid options: '
f'{API_NAMES}')

is_old_pyqt = is_pyqt46 = False
QT5 = PYQT5 = True
Expand Down Expand Up @@ -150,7 +154,9 @@ class PythonQtWarning(Warning):

del macos_version
except ImportError:
API = os.environ['QT_API'] = 'pyqt6'
API = 'pyqt6'
else:
os.environ[QT_API] = API

if API in PYQT6_API:
try:
Expand All @@ -161,7 +167,9 @@ class PythonQtWarning(Warning):
QT6 = PYQT6 = True

except ImportError:
API = os.environ['QT_API'] = 'pyside2'
API = 'pyside2'
else:
os.environ[QT_API] = API


if API in PYSIDE2_API:
Expand All @@ -183,7 +191,9 @@ class PythonQtWarning(Warning):

del macos_version
except ImportError:
API = os.environ['QT_API'] = 'pyside6'
API = 'pyside6'
else:
os.environ[QT_API] = API

if API in PYSIDE6_API:
try:
Expand All @@ -194,7 +204,9 @@ class PythonQtWarning(Warning):
QT6 = PYSIDE6 = True

except ImportError:
API = os.environ['QT_API'] = 'pyqt5'
API = 'pyqt5'
else:
os.environ[QT_API] = API


# If a correct API name is passed to QT_API and it could not be found,
Expand Down
5 changes: 3 additions & 2 deletions qtpy/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ def pytest_report_header(config):
versions += 'PyQt6: '

try:
from PyQt6 import Qt
versions += f"PyQt: {Qt.PYQT_VERSION_STR} - Qt: {Qt.QT_VERSION_STR}"
from PyQt6 import QtCore
versions += \
f"PyQt: {QtCore.PYQT_VERSION_STR} - Qt: {QtCore.QT_VERSION_STR}"
except ImportError:
versions += 'not installed'
except AttributeError:
Expand Down
47 changes: 46 additions & 1 deletion qtpy/tests/test_main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import os
import sys
import subprocess

import pytest

from qtpy import QtCore, QtGui, QtWidgets, API_NAMES, PythonQtValueError

from qtpy import QtCore, QtGui, QtWidgets
try:
# removed in qt 6.0
from qtpy import QtWebEngineWidgets
Expand All @@ -16,6 +21,7 @@ def assert_pyside2():
assert QtGui.QPainter is PySide2.QtGui.QPainter
assert QtWidgets.QWidget is PySide2.QtWidgets.QWidget
assert QtWebEngineWidgets.QWebEnginePage is PySide2.QtWebEngineWidgets.QWebEnginePage
assert os.environ['QT_API'] == 'pyside2'

def assert_pyside6():
"""
Expand All @@ -27,6 +33,7 @@ def assert_pyside6():
assert QtWidgets.QWidget is PySide6.QtWidgets.QWidget
# Only valid for qt>=6.2
# assert QtWebEngineWidgets.QWebEnginePage is PySide6.QtWebEngineCore.QWebEnginePage
assert os.environ['QT_API'] == 'pyside6'

def assert_pyqt5():
"""
Expand All @@ -40,6 +47,7 @@ def assert_pyqt5():
assert QtWebEngineWidgets.QWebEnginePage is PyQt5.QtWebEngineWidgets.QWebEnginePage
else:
assert QtWebEngineWidgets.QWebEnginePage is PyQt5.QtWebKitWidgets.QWebPage
assert os.environ['QT_API'] == 'pyqt5'

def assert_pyqt6():
"""
Expand All @@ -49,6 +57,7 @@ def assert_pyqt6():
assert QtCore.QEvent is PyQt6.QtCore.QEvent
assert QtGui.QPainter is PyQt6.QtGui.QPainter
assert QtWidgets.QWidget is PyQt6.QtWidgets.QWidget
assert os.environ['QT_API'] == 'pyqt6'


def test_qt_api():
Expand Down Expand Up @@ -83,3 +92,39 @@ def test_qt_api():
assert_pyqt6()
else:
assert_pyqt5()


@pytest.mark.parametrize('api', API_NAMES.values())
def test_qt_api_environ(api):
"""
If no QT_API is specified but some Qt is imported, ensure QT_API is set properly.
"""
mod = f'{api}.QtCore'
pytest.importorskip(mod, reason=f'Requires {api}')
# clean env
env = os.environ.copy()
for key in ('QT_API', 'USE_QT_API'):
if key in env:
del env[key]
cmd = f"""
import {mod}
from qtpy import API
import os
print(API)
print(os.environ['QT_API'])
"""
output = subprocess.check_output([sys.executable, '-c', cmd], env=env)
got_api, env_qt_api = output.strip().decode('utf-8').splitlines()
assert got_api == api.lower()
assert env_qt_api == api.lower()
# Also ensure we raise a nice error
env['QT_API'] = 'bad'
cmd = """
try:
import qtpy
except ValueError as exc:
assert 'Specified QT_API' in str(exc), str(exc)
else:
raise AssertionError('QtPy imported despite bad QT_API')
"""
subprocess.check_call([sys.executable, '-Oc', cmd], env=env)

0 comments on commit 25d402e

Please sign in to comment.