aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2022-01-26 19:03:41 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-02-03 17:18:10 +0000
commit1daed708ee14d56717c374cca9c780e5d32acb0f (patch)
tree87a675e6b4bd19d79f9658a27f9f572d462d84dc
parentdf8b9a68a98ac6045981e1d106acf31baea3668b (diff)
PyPySide: Fix locker handling which enables Mandelbrot
Not only the QPainter, but also the QMutexLocker were not correctly modelled after PEP 343 in the examples. Since that is now fixed, we consider the PyPy project not as ready, but good enough to publish it. It also turned out that people have the expectation to use QSignalBlocker in the "as" form: with QSignalBlocker(self.double_spin_box) as blocker: self.double_spin_box.setValue(2.5) https://stackoverflow.com/questions/60384734/how-to-use-qsignalblocker-in-python But that blocker would be None. As a side effect, QMutexLocker, QReadLocker, QWriteLocker and QSignalBlocker were augmented with a default __enter__ implementation that returns the locker instance. [ChangeLog][PySide6] The Mandelbrot example needed context managers for QPainter and QMutexLocker to work in PyPy. Task-number: PYSIDE-535 Change-Id: I2a62ca645a4fddcafbf11869f14a538141f32c39 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> (cherry picked from commit bc11e3c074bdba1ae0fcaa0c10e3b32f781be9fd) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--examples/corelib/threads/mandelbrot.py26
-rw-r--r--examples/network/blockingfortuneclient/blockingfortuneclient.py14
-rw-r--r--sources/pyside6/PySide6/QtCore/typesystem_core_common.xml16
-rw-r--r--sources/pyside6/PySide6/glue/qtcore.cpp5
-rw-r--r--sources/pyside6/tests/QtCore/blocking_signals_test.py8
-rw-r--r--sources/pyside6/tests/QtCore/bug_686.py13
6 files changed, 58 insertions, 24 deletions
diff --git a/examples/corelib/threads/mandelbrot.py b/examples/corelib/threads/mandelbrot.py
index 70658dc58..5617818fe 100644
--- a/examples/corelib/threads/mandelbrot.py
+++ b/examples/corelib/threads/mandelbrot.py
@@ -102,18 +102,17 @@ class RenderThread(QThread):
self.wait(2000)
def render(self, centerX, centerY, scale_factor, resultSize):
- locker = QMutexLocker(self.mutex)
-
- self._center_x = centerX
- self._center_y = centerY
- self._scale_factor = scale_factor
- self._result_size = resultSize
-
- if not self.isRunning():
- self.start(QThread.LowPriority)
- else:
- self.restart = True
- self.condition.wakeOne()
+ with QMutexLocker(self.mutex):
+ self._center_x = centerX
+ self._center_y = centerY
+ self._scale_factor = scale_factor
+ self._result_size = resultSize
+
+ if not self.isRunning():
+ self.start(QThread.LowPriority)
+ else:
+ self.restart = True
+ self.condition.wakeOne()
def run(self):
timer = QElapsedTimer()
@@ -185,7 +184,8 @@ class RenderThread(QThread):
if elapsed > 2000:
elapsed /= 1000
unit = 's'
- text = f"Pass {curpass+1}/{NUM_PASSES}, max iterations: {max_iterations}, time: {elapsed}{unit}"
+ text = (f"Pass {curpass + 1}/{NUM_PASSES}, "
+ f"max iterations: {max_iterations}, time: {elapsed}{unit}")
image.setText(INFO_KEY, text)
self.rendered_image.emit(image, scale_factor)
curpass += 1
diff --git a/examples/network/blockingfortuneclient/blockingfortuneclient.py b/examples/network/blockingfortuneclient/blockingfortuneclient.py
index 50f4c1662..b997a8f7d 100644
--- a/examples/network/blockingfortuneclient/blockingfortuneclient.py
+++ b/examples/network/blockingfortuneclient/blockingfortuneclient.py
@@ -73,13 +73,13 @@ class FortuneThread(QThread):
self.wait()
def request_new_fortune(self, hostname, port):
- locker = QMutexLocker(self.mutex)
- self._host_name = hostname
- self.port = port
- if not self.isRunning():
- self.start()
- else:
- self.cond.wakeOne()
+ with QMutexLocker(self.mutex):
+ self._host_name = hostname
+ self.port = port
+ if not self.isRunning():
+ self.start()
+ else:
+ self.cond.wakeOne()
def run(self):
self.mutex.lock()
diff --git a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml
index 14693c2e4..3683b2543 100644
--- a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml
+++ b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml
@@ -1450,7 +1450,9 @@
</object-type>
<object-type name="QMessageAuthenticationCode"/>
<object-type name="QSignalBlocker">
- <add-function signature="__enter__()"/>
+ <add-function signature="__enter__()" return-type="QSignalBlocker">
+ <inject-code file="../glue/qtcore.cpp" snippet="default-enter"/>
+ </add-function>
<add-function signature="__exit__(PyObject*,PyObject*,PyObject*)">
<inject-code file="../glue/qtcore.cpp" snippet="qsignalblocker-unblock"/>
</add-function>
@@ -1471,7 +1473,9 @@
</modify-argument>
</modify-function>
<modify-function signature="relock()" allow-thread="yes"/>
- <add-function signature="__enter__()"/>
+ <add-function signature="__enter__()" return-type="QReadLocker">
+ <inject-code file="../glue/qtcore.cpp" snippet="default-enter"/>
+ </add-function>
<add-function signature="__exit__(PyObject*,PyObject*,PyObject*)">
<inject-code file="../glue/qtcore.cpp" snippet="unlock"/>
</add-function>
@@ -1483,7 +1487,9 @@
</modify-argument>
</modify-function>
<modify-function signature="relock()" allow-thread="yes"/>
- <add-function signature="__enter__()"/>
+ <add-function signature="__enter__()" return-type="QWriteLocker">
+ <inject-code file="../glue/qtcore.cpp" snippet="default-enter"/>
+ </add-function>
<add-function signature="__exit__(PyObject*,PyObject*,PyObject*)">
<inject-code file="../glue/qtcore.cpp" snippet="unlock"/>
</add-function>
@@ -2331,7 +2337,9 @@
<reference-count action="set"/>
</modify-argument>
</modify-function>
- <add-function signature="__enter__()"/>
+ <add-function signature="__enter__()" return-type="QMutexLocker">
+ <inject-code file="../glue/qtcore.cpp" snippet="default-enter"/>
+ </add-function>
<add-function signature="__exit__(PyObject*,PyObject*,PyObject*)">
<inject-code file="../glue/qtcore.cpp" snippet="unlock"/>
</add-function>
diff --git a/sources/pyside6/PySide6/glue/qtcore.cpp b/sources/pyside6/PySide6/glue/qtcore.cpp
index 251c660a0..413649dd1 100644
--- a/sources/pyside6/PySide6/glue/qtcore.cpp
+++ b/sources/pyside6/PySide6/glue/qtcore.cpp
@@ -802,6 +802,11 @@ Py_XDECREF(result);
return !result ? -1 : 0;
// @snippet qbitarray-setitem
+// @snippet default-enter
+Py_INCREF(%PYSELF);
+pyResult = %PYSELF;
+// @snippet default-enter
+
// @snippet qsignalblocker-unblock
%CPPSELF.unblock();
// @snippet qsignalblocker-unblock
diff --git a/sources/pyside6/tests/QtCore/blocking_signals_test.py b/sources/pyside6/tests/QtCore/blocking_signals_test.py
index d4d59b457..b4b6c311b 100644
--- a/sources/pyside6/tests/QtCore/blocking_signals_test.py
+++ b/sources/pyside6/tests/QtCore/blocking_signals_test.py
@@ -72,6 +72,14 @@ class TestSignalsBlockedBasic(unittest.TestCase):
self.assertTrue(obj.signalsBlocked())
self.assertTrue(not obj.signalsBlocked())
+ def testContextWithAs(self):
+ obj = QObject()
+ self.assertTrue(not obj.signalsBlocked())
+ with QSignalBlocker(obj) as blocker:
+ self.assertTrue(obj.signalsBlocked())
+ self.assertEqual(type(blocker), QSignalBlocker)
+ self.assertTrue(not obj.signalsBlocked())
+
class TestSignalsBlocked(unittest.TestCase):
'''Test case to check if the signals are really blocked'''
diff --git a/sources/pyside6/tests/QtCore/bug_686.py b/sources/pyside6/tests/QtCore/bug_686.py
index 6e78e7f80..2437d101e 100644
--- a/sources/pyside6/tests/QtCore/bug_686.py
+++ b/sources/pyside6/tests/QtCore/bug_686.py
@@ -125,6 +125,19 @@ class TestQMutex (unittest.TestCase):
self.assertTrue(thread.wait(2000))
self.assertTrue(thread.canQuit)
+ def testWithAsLocker(self):
+ lock = QReadWriteLock()
+ with QReadLocker(lock) as locker:
+ self.assertTrue(isinstance(locker, QReadLocker))
+ with QWriteLocker(lock) as locker:
+ self.assertTrue(isinstance(locker, QWriteLocker))
+ mutex = QMutex()
+ with QMutexLocker(mutex) as locker:
+ self.assertTrue(isinstance(locker, QMutexLocker))
+ with self.assertRaises(TypeError):
+ with QMutexLocker(lock) as locker:
+ pass
+
if __name__ == '__main__':
unittest.main()