Changeset 11258:4c6f5d7a456b in orange


Ignore:
Timestamp:
01/11/13 17:16:34 (16 months ago)
Author:
Ales Erjavec <ales.erjavec@…>
Branch:
default
Message:

Override sys.excepthook with a custom handler.

Location:
Orange/OrangeCanvas
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • Orange/OrangeCanvas/application/outputview.py

    r11257 r11258  
    11""" 
    22""" 
     3import sys 
     4import traceback 
     5 
    36from functools import wraps 
    47from PyQt4.QtGui import ( 
     
    710) 
    811 
    9 from PyQt4.QtCore import Qt, QObject, QEvent, QCoreApplication 
     12from PyQt4.QtCore import Qt, QObject, QEvent, QCoreApplication, QThread 
    1013from PyQt4.QtCore import pyqtSignal as Signal 
    1114 
     
    264267            event.call() 
    265268            event.accept() 
     269 
     270 
     271class ExceptHook(QObject): 
     272    handledException = Signal() 
     273 
     274    def __init__(self, parent=None, stream=None): 
     275        QObject.__init__(self, parent) 
     276        self.stream = stream 
     277 
     278    def __call__(self, exc_type, exc_value, tb): 
     279        text = traceback.format_exception(exc_type, exc_value, tb) 
     280        separator = "-" * 80 + "\n" 
     281        if QThread.currentThread() != QCoreApplication.instance().thread(): 
     282            header = exc_type.__name__ + " (in non GUI thread)" 
     283        else: 
     284            header = exc_type.__name__ 
     285 
     286        header_fmt = "%%%is\n" 
     287        if tb: 
     288            header += (header_fmt % (80 - len(header))) % text[0].strip() 
     289            del text[0] 
     290        else: 
     291            header 
     292 
     293        if self.stream is None: 
     294            stream = sys.stderr 
     295        else: 
     296            stream = self.stream 
     297 
     298        stream.writelines([separator, header] + text) 
     299 
     300        self.handledException.emit() 
  • Orange/OrangeCanvas/application/tests/test_outputview.py

    r11257 r11258  
     1import sys 
    12import multiprocessing.pool 
    23 
     
    78from ...gui.test import QAppTestCase 
    89 
    9 from ..outputview import OutputView, TextStream 
     10from ..outputview import OutputView, TextStream, ExceptHook 
    1011 
    1112 
     
    109110        self.assertTrue(all(correct)) 
    110111        self.assertTrue(len(correct) == 10000) 
     112 
     113    def test_excepthook(self): 
     114        output = OutputView() 
     115        output.resize(500, 300) 
     116        output.show() 
     117 
     118        red_formater = output.formated(color=Qt.red) 
     119 
     120        red = TextStream() 
     121        red.stream.connect(red_formater.write) 
     122 
     123        hook = ExceptHook(stream=red) 
     124 
     125        def raise_exception(i): 
     126            try: 
     127                if i % 2 == 0: 
     128                    raise ValueError("odd") 
     129                else: 
     130                    raise ValueError("even") 
     131            except Exception: 
     132                # explicitly call hook (Thread class has it's own handler) 
     133                hook(*sys.exc_info()) 
     134 
     135        pool = multiprocessing.pool.ThreadPool(10) 
     136        res = pool.map_async(raise_exception, range(100)) 
     137 
     138        self.app.exec_() 
     139 
     140        res.wait() 
  • Orange/OrangeCanvas/main.py

    r11257 r11258  
    2121from Orange.OrangeCanvas.application.application import CanvasApplication 
    2222from Orange.OrangeCanvas.application.canvasmain import CanvasMainWindow 
    23 from Orange.OrangeCanvas.application.outputview import TextStream 
     23from Orange.OrangeCanvas.application.outputview import TextStream, ExceptHook 
    2424 
    2525from Orange.OrangeCanvas.gui.splashscreen import SplashScreen, QPixmap 
     
    260260        stderr = sys.stderr 
    261261 
     262    if stderr_redirect: 
     263        sys.excepthook = ExceptHook() 
     264        sys.excepthook.handledException.connect(output_view.parent().show) 
     265 
    262266    with nested(redirect_stdout(stdout), redirect_stderr(stderr)): 
    263267        log.info("Entering main event loop.") 
Note: See TracChangeset for help on using the changeset viewer.