Details
-
Bug
-
Resolution: Duplicate
-
Not Evaluated
-
None
-
6.5.1
-
None
-
Ubuntu 23.04
Description
After updating PySide6 from 6.5.0 to 6.5.1 using pip, some of my unit tests failed when running in a row. They work fine if executed one by one, i.e., with a new Python interpreter instance for each test, but not when run by the same instance.
A minimal "working" example:
#!/usr/bin/env python3 import unittest from PySide6 import QtCore from PySide6.QtWidgets import ( QApplication, QPushButton, ) PRINT_OBJ = True class TheButton(QPushButton): def __init__(self, text: str) -> None: super().__init__(text=text, parent=None) self.clicked_count = 0 def clicked_me() -> None: if PRINT_OBJ: print(self, 'clicked') self.clicked_count += 1 self.clicked.connect(clicked_me) class TestQt65(unittest.TestCase): def setUp(self) -> None: self._q_app = QApplication.instance() or QApplication() print('Qt version:', QtCore.qVersion()) def test_1(self) -> None: dut = TheButton('test_1') if PRINT_OBJ: print('\ntest_1 obj:', dut) dut.click() self.assertEqual(dut.clicked_count, 1) def test_2(self) -> None: dut = TheButton('test_2') if PRINT_OBJ: print('\ntest_2 obj:', dut) dut.click() self.assertEqual(dut.clicked_count, 1)
Note that the slot for TheButton.clicked is an inner function of its {}init{}, not a separate instance method.
Qt 6.5.0
Running the tests individually: PASS
$ python3 -m unittest tests.uitests.test_qt65.TestQt65.test_1 qt.dbus.integration: Could not connect "org.freedesktop.IBus" to globalEngineChanged(QString) Qt version: 6.5.0 test_1 obj: <tests.uitests.test_qt65.TheButton(0x5557355a09b0) at 0x7fc959057a40> <tests.uitests.test_qt65.TheButton(0x5557355a09b0) at 0x7fc959057a40> clicked . ---------------------------------------------------------------------- Ran 1 test in 0.094s OK ltsoftware$ python3 -m unittest tests.uitests.test_qt65.TestQt65.test_2 qt.dbus.integration: Could not connect "org.freedesktop.IBus" to globalEngineChanged(QString) Qt version: 6.5.0 test_2 obj: <tests.uitests.test_qt65.TheButton(0x55c312feda50) at 0x7f97d4057a40> <tests.uitests.test_qt65.TheButton(0x55c312feda50) at 0x7f97d4057a40> clicked . ---------------------------------------------------------------------- Ran 1 test in 0.136s OK
Running both tests at once: PASS
$ python3 -m unittest tests.uitests.test_qt65.TestQt65 qt.dbus.integration: Could not connect "org.freedesktop.IBus" to globalEngineChanged(QString) Qt version: 6.5.0 test_1 obj: <tests.uitests.test_qt65.TheButton(0x557a80fbc870) at 0x7f40aba5fb80> <tests.uitests.test_qt65.TheButton(0x557a80fbc870) at 0x7f40aba5fb80> clicked .Qt version: 6.5.0 test_2 obj: <tests.uitests.test_qt65.TheButton(0x557a80fbc790) at 0x7f40aba5f800> <tests.uitests.test_qt65.TheButton(0x557a80fbc790) at 0x7f40aba5f800> clicked . ---------------------------------------------------------------------- Ran 2 tests in 0.102s OK
Qt 6.5.1
Running the tests individually: PASS
$ python3 -m unittest tests.uitests.test_qt65.TestQt65.test_1 Qt version: 6.5.1 test_1 obj: <tests.uitests.test_qt65.TheButton(0x5652fa86eff0) at 0x7f342e374980> <tests.uitests.test_qt65.TheButton(0x5652fa86eff0) at 0x7f342e374980> clicked . ---------------------------------------------------------------------- Ran 1 test in 0.142s OK ltsoftware$ python3 -m unittest tests.uitests.test_qt65.TestQt65.test_2 Qt version: 6.5.1 test_2 obj: <tests.uitests.test_qt65.TheButton(0x5612e17d6220) at 0x7fd0ce898940> <tests.uitests.test_qt65.TheButton(0x5612e17d6220) at 0x7fd0ce898940> clicked . ---------------------------------------------------------------------- Ran 1 test in 0.134s OK
Running both tests at once: {}FAIL{}
$ python3 -m unittest tests.uitests.test_qt65.TestQt65 Qt version: 6.5.1 test_1 obj: <tests.uitests.test_qt65.TheButton(0x55d8d007cb80) at 0x7f57c6698a80> <tests.uitests.test_qt65.TheButton(0x55d8d007cb80) at 0x7f57c6698a80> clicked .Qt version: 6.5.1 test_2 obj: <tests.uitests.test_qt65.TheButton(0x55d8d007caa0) at 0x7f57c6698700> <tests.uitests.test_qt65.TheButton(0x55d8d007cb80) at 0x7f57c6698a80> clicked F ====================================================================== FAIL: test_2 (tests.uitests.test_qt65.TestQt65.test_2) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/phip/phipsfiles/developing/electronics/altatec/lasertrimmer/ltsoftware/tests/uitests/test_qt65.py", line 44, in test_2 self.assertEqual(dut.clicked_count, 1) AssertionError: 0 != 1 ---------------------------------------------------------------------- Ran 2 tests in 0.097s FAILED (failures=1)
The problem is apparently that in the second test, the clicked slot still fires, but for the object created in the first test and not the one in the second test.
Apparent cause/fix
It appears that the handling of the QApplication changed between versions and it is now required to fully clean it up after the test using QApplication.shutdown(). If I add the call to tearDown(), the problem is gone:
def tearDown(self) -> None: self._q_app.shutdown()
Output:
$ python3 -m unittest tests.uitests.test_qt65.TestQt65 Qt version: 6.5.1 test_1 obj: <tests.uitests.test_qt65.TheButton(0x55df351904d0) at 0x7fe580a9cb00> <tests.uitests.test_qt65.TheButton(0x55df351904d0) at 0x7fe580a9cb00> clicked .Qt version: 6.5.1 test_2 obj: <tests.uitests.test_qt65.TheButton(0x55df34e1b9b0) at 0x7fe5859f8900> <tests.uitests.test_qt65.TheButton(0x55df34e1b9b0) at 0x7fe5859f8900> clicked . ---------------------------------------------------------------------- Ran 2 tests in 0.164s OK
It may be that the shutdown() should have been there ever since and it worked more by coincidence up to 6.5.0. However, to me this seems to be rather serious for just a minor version bump and might affect other parts of the software as well.
Attachments
Issue Links
- duplicates
-
PYSIDE-2346 Connecting signal to inner function reuses first instance of inner function
- Closed