pytest-qt
pytest-qt copied to clipboard
Import error when running tests
When running any pytest I receive the following error
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR> File "/test/.venv/lib/python3.9/site-packages/_pytest/main.py", line 264, in wrap_session
INTERNALERROR> config._do_configure()
INTERNALERROR> File "/test/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py", line 992, in _do_configure
INTERNALERROR> self.hook.pytest_configure.call_historic(kwargs=dict(config=self))
INTERNALERROR> File "/test/.venv/lib/python3.9/site-packages/pluggy/_hooks.py", line 277, in call_historic
INTERNALERROR> res = self._hookexec(self.name, self.get_hookimpls(), kwargs, False)
INTERNALERROR> File "/test/.venv/lib/python3.9/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR> File "/test/.venv/lib/python3.9/site-packages/pluggy/_callers.py", line 60, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> File "/test/.venv/lib/python3.9/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "/test/.venv/lib/python3.9/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "/test/.venv/lib/python3.9/site-packages/pytestqt/plugin.py", line 203, in pytest_configure
INTERNALERROR> qt_api.set_qt_api(config.getini("qt_api"))
INTERNALERROR> File "/test/.venv/lib/python3.9/site-packages/pytestqt/qt_compat.py", line 75, in set_qt_api
INTERNALERROR> self.pytest_qt_api = self._get_qt_api_from_env() or api or self._guess_qt_api()
INTERNALERROR> File "/test/.venv/lib/python3.9/site-packages/pytestqt/qt_compat.py", line 64, in _guess_qt_api
INTERNALERROR> if _can_import("PySide6.QtCore"):
INTERNALERROR> File "/test/.venv/lib/python3.9/site-packages/pytestqt/qt_compat.py", line 56, in _can_import
INTERNALERROR> _import(name)
INTERNALERROR> File "/test/.venv/lib/python3.9/site-packages/pytestqt/qt_compat.py", line 23, in _import
INTERNALERROR> return __import__(name)
INTERNALERROR> File "/test/.venv/lib/python3.9/site-packages/shiboken2/files.dir/shibokensupport/__feature__.py", line 145, in _import
INTERNALERROR> return original_import(name, *args, **kwargs)
INTERNALERROR> File "/test/.venv/lib/python3.9/site-packages/IPython/external/qt_loaders.py", line 65, in find_spec
INTERNALERROR> raise ImportError(
INTERNALERROR> ImportError:
INTERNALERROR> Importing PySide6 disabled by IPython, which has
INTERNALERROR> already imported an Incompatible QT Binding: pyside2
I suspect it has something to do with the Ipython package that is being used as well. Here is the full list of installed dependencies
[tool.poetry.dependencies]
python = ">=3.9,<3.10"
importlib-metadata = "^4.11.2"
ipython = "^8.1.1"
matplotlib = "^3.5.1"
mypy = "^0.931"
mypy-extensions = "^0.4.3"
Pygments = "^2.11.2"
qiskit = "^0.34.2"
pylatexenc = "^2.10"
qtconsole = "^5.2.2"
Rx = "^3.2.0"
typed-ast = "^1.5.2"
typing-extensions = "^4.1.1"
zipp = "^3.7.0"
marshmallow = "^3.14.1"
marshmallow-enum = "^1.5.1"
marshmallow-dataclass = "^8.5.3"
yapf = "^0.32.0"
pre-commit = "^2.17.0"
pytest-qt = "^4.0.2"
pytest = "^7.0.1"
appdirs = "^1.4.4"
PySide2 = "^5.15.2"
That error is coming from IPython, not pytest-qt. It looks like you will need to make sure that you configure the same Qt API for IPython (docs) and pytest-qt (docs).
I did configure the env variable QT_API for IPython QT_API=pyside
. However, at this stage https://github.com/pytest-dev/pytest-qt/blob/master/src/pytestqt/qt_compat.py#L64, pytest-qt is trying to import any possible qt library, which in this case will throw a nasty error from IPython since that one is not allowing any other imports than the ones defined. Currently only ModuleNotFoundError
is handled, but wouldn't it be possible to cater for others as well since there's a lot that might go wrong here?
def _can_import(name):
try:
_import(name)
return True
except ModuleNotFoundError as e:
self._import_errors[name] = str(e)
return False
As an alternative and very simple solution may I propose to just change the order in which the imports are being tried, to something like
if _can_import("PySide2.QtCore"):
return "pyside2"
elif _can_import("PyQt6.QtCore"):
return "pyqt6"
elif _can_import("PyQt5.QtCore"):
return "pyqt5"
elif _can_import("PySide6.QtCore"):
return "pyside6"
Hmm, right, apologies for closing this issue so quickly - reopening it for now.
@svartkanin One workaround is to use PYTEST_QT_API=pyside2
.
@eyllanesc got it right: this will prevent pytest-qt from trying to guess which API to use (the _guess_api
function).