Slaknation
Slaknation

Reputation: 1926

Python: can't see exception that is getting thrown

I am running a unit test and I realize that there is an exception getting thrown. However, I am just not sure what exactly is getting thrown.

from pt_hil.utilities.PT_HIL_Interface_Utils.widgets import PathPicker
import unittest
import wx

class TestUM(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        print 'setUpClass called'
        cls.path_picker = PathPicker()
        print 'path_picker has been declared'

    def test_PathPicker(self):
        self.assertRaises(NotImplementedError, wx.UIActionSimulator.MouseClick(self.path_picker.browse))

if __name__ == '__main__':
    unittest.main()

the PathPicker class:

class PathPicker(Widget):

    def __init__(self, parent=None, name="PathPicker"):
        print 'hi1'
        try:
            Widget.__init__(self, name, parent)
        except Exception as e:
            print 'hello'
            return logging.error(traceback.format_exc())
        print 'hi2'

the output I get when I run the unit test is:

setUpClass called
hi1

Process finished with exit code 1

So clearly, something is going wrong at: Widget.__init__(self, name, parent) but I can't see what it is. Is there any way I can get this to print out what exception or error is getting thrown?

edit: here is the Widget class to go along with it:

class Widget(QWidget):
    def __init__(self, name, parent=None):
        print 'hey2'
        try:
            super(Widget, self).__init__()
        except BaseException as e:
            print 'hello'
            return logging.error(traceback.format_exc())
        print 'hey3'

now it is giving me:

setUpClass called
hi1
hey2

Process finished with exit code 1

Upvotes: 3

Views: 575

Answers (2)

Slaknation
Slaknation

Reputation: 1926

I needed to add app = QApplication(sys.argv) and sys.exit(app.exec_()) in the script with the class TestUM(unittest.TestCase):

so that script above should look like:

from pt_hil.utilities.PT_HIL_Interface_Utils.widgets import PathPicker
import unittest
import wx

class TestUM(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        print 'setUpClass called'
        cls.path_picker = PathPicker()
        print 'path_picker has been declared'

    def test_PathPicker(self):
        self.assertRaises(NotImplementedError, wx.UIActionSimulator.MouseClick(self.path_picker.browse))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    unittest.main()
    sys.exit(app.exec_())

note that this does not solve the problem I had of throwing the exception I needed (since no exception was visible). But it did solve the problem and the script would run. Thanks!

Upvotes: 1

Cédric Julien
Cédric Julien

Reputation: 80761

As you can see here, the top exceptions in python (2.x) are :

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StandardError
      ....

So, in your case, by catching Exception you are missing some other exceptions (rare exceptions, but probably happening in your case) : SystemExit, KeyboardInterrupt and GeneratorExit. Try to change your except clause into :

except BaseException as e:

this way, you'll be sure to catch all exceptions, and detect your problem.

EDIT:

BUT, PyQT can be fun inside. As mentionned here :

In PyQt v5.5 an unhandled Python exception will result in a call to Qt’s qFatal() function. By default this will call abort() and the application will terminate. Note that an application installed exception hook will still take precedence.

So, an unexcepted exception (that can happend for many reasons in C++ code, bad parameters...) can silently stop your application. Yet, the last part sounds useful, if you install an exception hook, it will be called before the silently abort. Let's try to add a exception hook :

sys._excepthook = sys.excepthook # always save before overriding

def application_exception_hook(exctype, value, traceback):
    # Let's try to write the problem
    print "Exctype : %s, value : %s traceback : %s"%(exctype, value, traceback)
    # Call the normal Exception hook after (this will probably abort application)
    sys._excepthook(exctype, value, traceback)
    sys.exit(1)

# Do not forget to our exception hook
sys.excepthook = application_exception_hook

Upvotes: 3

Related Questions