functions: revert the function init order to make pylint happy again. See #217
[pygobject.git] / tests / helper.py
blob1485ec3de9022d3a32fd7e67f9bd3ba9b10d4c91
1 from __future__ import absolute_import
3 import contextlib
4 import unittest
5 import inspect
6 import warnings
7 import functools
8 import sys
9 from collections import namedtuple
11 import gi
12 from gi import PyGIDeprecationWarning
13 from gi.repository import GLib
14 from gi._compat import StringIO
17 ExceptionInfo = namedtuple("ExceptionInfo", ["type", "value", "traceback"])
18 """The type used for storing exceptions used by capture_exceptions()"""
21 @contextlib.contextmanager
22 def capture_exceptions():
23 """Installs a temporary sys.excepthook which records all exceptions
24 instead of printing them.
25 """
27 exceptions = []
29 def custom_excepthook(*args):
30 exceptions.append(ExceptionInfo(*args))
32 old_hook = sys.excepthook
33 sys.excepthook = custom_excepthook
34 try:
35 yield exceptions
36 finally:
37 sys.excepthook = old_hook
40 def ignore_gi_deprecation_warnings(func_or_class):
41 """A unittest class and function decorator which makes them ignore
42 PyGIDeprecationWarning.
43 """
45 if inspect.isclass(func_or_class):
46 assert issubclass(func_or_class, unittest.TestCase)
47 cls = func_or_class
48 for name, value in cls.__dict__.items():
49 if callable(value) and name.startswith("test_"):
50 new_value = ignore_gi_deprecation_warnings(value)
51 setattr(cls, name, new_value)
52 return cls
53 else:
54 func = func_or_class
56 @functools.wraps(func)
57 def wrapper(*args, **kwargs):
58 with capture_gi_deprecation_warnings():
59 return func(*args, **kwargs)
61 return wrapper
64 @contextlib.contextmanager
65 def capture_gi_deprecation_warnings():
66 """Temporarily suppress PyGIDeprecationWarning output and record them"""
68 with warnings.catch_warnings(record=True) as warn:
69 warnings.simplefilter('always', category=PyGIDeprecationWarning)
70 yield warn
73 @contextlib.contextmanager
74 def capture_glib_warnings(allow_warnings=False, allow_criticals=False):
75 """Temporarily suppress glib warning output and record them.
77 The test suite is run with G_DEBUG="fatal-warnings fatal-criticals"
78 by default. Setting allow_warnings and allow_criticals will temporarily
79 allow warnings or criticals without terminating the test run.
80 """
82 old_mask = GLib.log_set_always_fatal(GLib.LogLevelFlags(0))
84 new_mask = old_mask
85 if allow_warnings:
86 new_mask &= ~GLib.LogLevelFlags.LEVEL_WARNING
87 if allow_criticals:
88 new_mask &= ~GLib.LogLevelFlags.LEVEL_CRITICAL
90 GLib.log_set_always_fatal(GLib.LogLevelFlags(new_mask))
92 GLibWarning = gi._gi.Warning
93 try:
94 with warnings.catch_warnings(record=True) as warn:
95 warnings.filterwarnings('always', category=GLibWarning)
96 yield warn
97 finally:
98 GLib.log_set_always_fatal(old_mask)
101 @contextlib.contextmanager
102 def capture_glib_deprecation_warnings():
103 """Temporarily suppress glib deprecation warning output and record them"""
105 GLibWarning = gi._gi.Warning
106 with warnings.catch_warnings(record=True) as warn:
107 warnings.filterwarnings(
108 'always', category=GLibWarning,
109 message=".+ is deprecated and shouldn't be used anymore\\. "
110 "It will be removed in a future version\\.")
111 yield warn
114 @contextlib.contextmanager
115 def capture_output():
117 with capture_output() as (stdout, stderr):
118 some_action()
119 print(stdout.getvalue(), stderr.getvalue())
122 err = StringIO()
123 out = StringIO()
124 old_err = sys.stderr
125 old_out = sys.stdout
126 sys.stderr = err
127 sys.stdout = out
129 try:
130 yield (out, err)
131 finally:
132 sys.stderr = old_err
133 sys.stdout = old_out