Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Selecting pyqt version in individual test, as opposed to for the whole test suite. #577

Closed
ahobeost opened this issue Oct 24, 2024 · 3 comments

Comments

@ahobeost
Copy link

As part of a very large project, we would like to incrementally move from pyqt5 to pyqt6.
The solution for backwards compatibility allows this to work, just not for testing it seems).

The following two tests demonstrate what I would like to achieve and show a known issue (#437).
The issue here, is that qtbot produces a specific Qapplication (either version 5 or version 6).

class TestMessageBox:
    def testCreate(self, qtbot):
        print("I am before message box")

        from PyQt5 import QtWidgets as _qtw
        qtbot.addWidget(_qtw.QMessageBox())
        print("I am after message box")
        assert False

    def testCreatePyQt6(self, qtbot):
        print("I am before message box")
        from PyQt6 import QtWidgets as _qtw

        qtbot.addWidget(_qtw.QMessageBox())
        print("I am after message box")
        assert False

One of these (or both) will fail, depending on which api is set in the pytest.ini file:
qt_api=pyqt5

The other will fail with the following error code:
Process finished with exit code -1073740791 (0xC0000409)

It would be great if qtbot would provide a Qapplication tailored to the desired version, for example.
qt.bot.set_version('pyqt5')

And then the tests would be:

class TestMessageBox:
    def testCreate(self, qtbot):
        print("I am before message box")

        from PyQt5 import QtWidgets as _qtw
        qt.bot.set_version('pyqt5')

        qtbot.addWidget(_qtw.QMessageBox())
        print("I am after message box")
        assert False

    def testCreatePyQt6(self, qtbot):
        print("I am before message box")

        from PyQt6 import QtWidgets as _qtw
        
        qt.bot.set_version('pyqt5')
        qtbot.addWidget(_qtw.QMessageBox())
        print("I am after message box")
        assert False

The following workaround also exists, which is not compatible with qtbot:

def testCreatePyQt6(self, qtbot):
        print("I am before message box")

        from PyQt6 import QtWidgets as _qtw
        
        app = _qtw.QApplication([])
        qtbot.addWidget(_qtw.QMessageBox())
        print("I am after message box")
        assert False

Naive implementation:

class Qtbot:
    def set_version(self, api: str):
        from pytestqt.qt_compat import qt_api
        qt_api.set_qt_api(api)
@nicoddemus
Copy link
Member

Hi @ahobeost,

I don't think it is possible to provide different QApplication instances in the same process, it acts as a singleton, and errors out if you try to create a second QApplication.

In your case I suggest to mark the tests differently (say qt5 and qt6), and then execute them in separate pytest sessions:

pytest -m qt5 ...
pytest -m qt6 ...

This seems reasonable and safer than trying to use both PyQt versions in the same process.

@nicoddemus nicoddemus closed this as not planned Won't fix, can't repro, duplicate, stale Oct 24, 2024
@ahobeost
Copy link
Author

Hi @ahobeost,

I don't think it is possible to provide different QApplication instances in the same process, it acts as a singleton, and errors out if you try to create a second QApplication.

In your case I suggest to mark the tests differently (say qt5 and qt6), and then execute them in separate pytest sessions:

pytest -m qt5 ...
pytest -m qt6 ...

This seems reasonable and safer than trying to use both PyQt versions in the same process.

Thanks for the quick reply @nicoddemus.
My thinking went along the same line, in case this was a dead end.
Have a great day!

@nicoddemus
Copy link
Member

Btw an option is to, instead of marking them both, mark just one of them, for example only add qt6 marks to Qt6 specific tests, and then:

pytest -m "not qt6"
pytest -m qt6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants