7 from collections
import namedtuple
10 from gi
import PyGIDeprecationWarning
11 from gi
.repository
import GLib
13 from compathelper
import callable, StringIO
16 ExceptionInfo
= namedtuple("ExceptionInfo", ["type", "value", "traceback"])
17 """The type used for storing exceptions used by capture_exceptions()"""
20 @contextlib.contextmanager
21 def capture_exceptions():
22 """Installs a temporary sys.excepthook which records all exceptions
23 instead of printing them.
28 def custom_excepthook(*args
):
29 exceptions
.append(ExceptionInfo(*args
))
31 old_hook
= sys
.excepthook
32 sys
.excepthook
= custom_excepthook
36 sys
.excepthook
= old_hook
39 def ignore_gi_deprecation_warnings(func_or_class
):
40 """A unittest class and function decorator which makes them ignore
41 PyGIDeprecationWarning.
44 if inspect
.isclass(func_or_class
):
45 assert issubclass(func_or_class
, unittest
.TestCase
)
47 for name
, value
in cls
.__dict
__.items():
48 if callable(value
) and name
.startswith("test_"):
49 new_value
= ignore_gi_deprecation_warnings(value
)
50 setattr(cls
, name
, new_value
)
55 @functools.wraps(func
)
56 def wrapper(*args
, **kwargs
):
57 with
capture_gi_deprecation_warnings():
58 return func(*args
, **kwargs
)
63 @contextlib.contextmanager
64 def capture_gi_deprecation_warnings():
65 """Temporarily suppress PyGIDeprecationWarning output and record them"""
67 with warnings
.catch_warnings(record
=True) as warn
:
68 warnings
.simplefilter('always', category
=PyGIDeprecationWarning
)
72 @contextlib.contextmanager
73 def capture_glib_warnings(allow_warnings
=False, allow_criticals
=False):
74 """Temporarily suppress glib warning output and record them.
76 The test suite is run with G_DEBUG="fatal-warnings fatal-criticals"
77 by default. Setting allow_warnings and allow_criticals will temporarily
78 allow warnings or criticals without terminating the test run.
81 old_mask
= GLib
.log_set_always_fatal(GLib
.LogLevelFlags(0))
85 new_mask
&= ~GLib
.LogLevelFlags
.LEVEL_WARNING
87 new_mask
&= ~GLib
.LogLevelFlags
.LEVEL_CRITICAL
89 GLib
.log_set_always_fatal(GLib
.LogLevelFlags(new_mask
))
91 GLibWarning
= gi
._gi
._gobject
.Warning
93 with warnings
.catch_warnings(record
=True) as warn
:
94 warnings
.filterwarnings('always', category
=GLibWarning
)
97 GLib
.log_set_always_fatal(old_mask
)
100 @contextlib.contextmanager
101 def capture_glib_deprecation_warnings():
102 """Temporarily suppress glib deprecation warning output and record them"""
104 GLibWarning
= gi
._gi
._gobject
.Warning
105 with warnings
.catch_warnings(record
=True) as warn
:
106 warnings
.filterwarnings(
107 'always', category
=GLibWarning
,
108 message
=".+ is deprecated and shouldn't be used anymore\. "
109 "It will be removed in a future version\.")
113 @contextlib.contextmanager
114 def capture_output():
116 with capture_output as (stdout, stderr):
118 print(stdout.getvalue(), stderr.getvalue())