PySide Bug Reproduction: Final version of threading that shows the pyside bug
[gc-dialer] / hand_tests / threading.py
index d4f9c91..22084ed 100755 (executable)
@@ -3,9 +3,57 @@
 from __future__ import with_statement
 from __future__ import division
 
+import functools
 import time
 
-import PyQt4.QtCore as QtCore
+
+FORCE_PYQT = False
+DECORATE = True
+
+
+try:
+       if FORCE_PYQT:
+               raise ImportError()
+       import PySide.QtCore as _QtCore
+       QtCore = _QtCore
+       USES_PYSIDE = True
+except ImportError:
+       import sip
+       sip.setapi('QString', 2)
+       sip.setapi('QVariant', 2)
+       import PyQt4.QtCore as _QtCore
+       QtCore = _QtCore
+       USES_PYSIDE = False
+
+
+if USES_PYSIDE:
+       Signal = QtCore.Signal
+       Slot = QtCore.Slot
+       Property = QtCore.Property
+else:
+       Signal = QtCore.pyqtSignal
+       Slot = QtCore.pyqtSlot
+       Property = QtCore.pyqtProperty
+
+
+def log_exception():
+
+       def log_exception_decorator(func):
+
+               @functools.wraps(func)
+               def wrapper(*args, **kwds):
+                       try:
+                               return func(*args, **kwds)
+                       except Exception:
+                               print "Exception", func.__name__
+                               raise
+
+               if DECORATE:
+                       return wrapper
+               else:
+                       return func
+
+       return log_exception_decorator
 
 
 class QThread44(QtCore.QThread):
@@ -24,13 +72,14 @@ class QThread44(QtCore.QThread):
 
 class Producer(QtCore.QObject):
 
-       data = QtCore.pyqtSignal(int)
-       done = QtCore.pyqtSignal()
+       data = Signal(int)
+       done = Signal()
 
        def __init__(self):
                QtCore.QObject.__init__(self)
 
-       @QtCore.pyqtSlot()
+       @Slot()
+       @log_exception()
        def process(self):
                print "Starting producer"
                for i in xrange(10):
@@ -44,20 +93,23 @@ class Consumer(QtCore.QObject):
        def __init__(self):
                QtCore.QObject.__init__(self)
 
-       @QtCore.pyqtSlot()
+       @Slot()
+       @log_exception()
        def process(self):
                print "Starting consumer"
 
-       @QtCore.pyqtSlot()
+       @Slot()
+       @log_exception()
        def print_done(self):
                print "Done"
 
-       @QtCore.pyqtSlot(int)
+       @Slot(int)
+       @log_exception()
        def print_data(self, i):
                print i
 
 
-if __name__ == "__main__":
+def run_producer_consumer():
        app = QtCore.QCoreApplication([])
 
        producerThread = QThread44()
@@ -73,7 +125,8 @@ if __name__ == "__main__":
        producer.data.connect(consumer.print_data)
        producer.done.connect(consumer.print_done)
 
-       @QtCore.pyqtSlot()
+       @Slot()
+       @log_exception()
        def producer_done():
                print "Shutting down"
                producerThread.quit()
@@ -83,7 +136,8 @@ if __name__ == "__main__":
 
        count = [0]
 
-       @QtCore.pyqtSlot()
+       @Slot()
+       @log_exception()
        def thread_done():
                print "Thread done"
                count[0] += 1
@@ -96,4 +150,8 @@ if __name__ == "__main__":
 
        producerThread.start()
        consumerThread.start()
-       print "Status", app.exec_()
+       print "Status %s" % app.exec_()
+
+
+if __name__ == "__main__":
+       run_producer_consumer()