summaryrefslogtreecommitdiff
path: root/tests/conftest.py
diff options
context:
space:
mode:
authorChristoph Reiter <reiter.christoph@gmail.com>2018-02-16 08:49:38 +0100
committerChristoph Reiter <reiter.christoph@gmail.com>2018-02-16 09:17:26 +0100
commite00e38f9c44568f7fab643a069f86c576011ddcc (patch)
tree5c25f85a9f1a775fd3cc8bfff7c1d76744178852 /tests/conftest.py
parentaae383cf44ee3eabcc4b4122049ea277524d5001 (diff)
downloadpygobject-e00e38f9c44568f7fab643a069f86c576011ddcc.tar.gz
tests: add a pytest hook for handling unhandled exception in closures
In PyGObject when an exception is raised in a closure called from C then the error gets passed to sys.excepthook (on the main thread at least) and the error is by default printed to stdout. Since pytest by default hides stdout, errors can be easily missed now. To make these errors more visible add a test wrapper which checks sys.excepthook for unhandled exceptions and reraises them. This makes the tests fail and as a bonus also shows the right stack trace instead of just the error message.
Diffstat (limited to 'tests/conftest.py')
-rw-r--r--tests/conftest.py31
1 files changed, 31 insertions, 0 deletions
diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644
index 00000000..f69405d4
--- /dev/null
+++ b/tests/conftest.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+
+import sys
+
+import pytest
+
+from .compathelper import reraise
+
+
+@pytest.hookimpl(hookwrapper=True)
+def pytest_runtest_call(item):
+ """A pytest hook which takes over sys.excepthook and raises any uncaught
+ exception (with PyGObject this happesn often when we get called from C,
+ like any signal handler, vfuncs tc)
+ """
+
+ assert sys.excepthook is sys.__excepthook__
+
+ exceptions = []
+
+ def on_hook(type_, value, tback):
+ exceptions.append((type_, value, tback))
+
+ sys.excepthook = on_hook
+ try:
+ yield
+ finally:
+ assert sys.excepthook in (on_hook, sys.__excepthook__)
+ sys.excepthook = sys.__excepthook__
+ if exceptions:
+ reraise(*exceptions[0])