Skip to content

Commit acf305d

Browse files
committed
NF - check and ignore warnings context managers
1 parent 9699520 commit acf305d

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

nibabel/checkwarns.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*-
2+
# vi: set ft=python sts=4 ts=4 sw=4 et:
3+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
4+
#
5+
# See COPYING file distributed along with the NiBabel package for the
6+
# copyright and license terms.
7+
#
8+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
9+
''' Contexts for *with* statement allowing checks for warnings
10+
11+
When we give up 2.5 compatibility we can use python's own
12+
``tests.test_support.check_warnings``
13+
14+
'''
15+
from __future__ import with_statement
16+
17+
import warnings
18+
19+
20+
class ErrorWarnings(object):
21+
""" Context manager to check for warnings as errors. Usually used with
22+
``assert_raises`` in the with block
23+
24+
Examples
25+
--------
26+
>>> with ErrorWarnings():
27+
... try:
28+
... warnings.warn('Message', UserWarning)
29+
... except UserWarning:
30+
... print 'I consider myself warned'
31+
I consider myself warned
32+
33+
Notes
34+
-----
35+
The manager will raise a RuntimeError if another warning filter gets put on
36+
top of the one it has just added.
37+
"""
38+
def __init__(self):
39+
self.added = None
40+
41+
def __enter__(self):
42+
warnings.simplefilter('error')
43+
self.added = warnings.filters[0]
44+
45+
def __exit__(self, exc, value, tb):
46+
if warnings.filters[0] != self.added:
47+
raise RuntimeError('Somone has done something to the filters')
48+
warnings.filters.pop(0)
49+
return False # allow any exceptions to propagate
50+
51+
52+
class IgnoreWarnings(ErrorWarnings):
53+
""" Context manager to ignore warnings
54+
55+
Examples
56+
--------
57+
>>> with IgnoreWarnings():
58+
... warnings.warn('Message', UserWarning)
59+
60+
(and you get no warning)
61+
62+
Notes
63+
-----
64+
The manager will raise a RuntimeError if another warning filter gets put on
65+
top of the one it has just added.
66+
"""
67+
68+
def __enter__(self):
69+
warnings.simplefilter('ignore')
70+
self.added = warnings.filters[0]

nibabel/tests/test_checkwarns.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
""" Tests for warnings context managers
2+
"""
3+
4+
from __future__ import with_statement
5+
6+
from warnings import warn, simplefilter, filters
7+
8+
from ..checkwarns import ErrorWarnings, IgnoreWarnings
9+
10+
from nose.tools import assert_true, assert_equal, assert_raises
11+
12+
13+
def test_warn_error():
14+
# Check warning error context manager
15+
n_warns = len(filters)
16+
with ErrorWarnings():
17+
assert_raises(UserWarning, warn, 'A test')
18+
assert_equal(n_warns, len(filters))
19+
def f():
20+
with ErrorWarnings():
21+
simplefilter('ignore')
22+
try:
23+
assert_raises(RuntimeError, f)
24+
assert_equal(n_warns+2, len(filters))
25+
finally:
26+
filters.pop(0)
27+
filters.pop(0)
28+
# Check other errors are propagated
29+
def f():
30+
with ErrorWarnings():
31+
raise ValueError('An error')
32+
assert_raises(ValueError, f)
33+
34+
35+
def test_warn_ignore():
36+
# Check warning ignore context manager
37+
n_warns = len(filters)
38+
with IgnoreWarnings():
39+
warn('Here is a warning, you will not see it')
40+
warn('Nor this one', DeprecationWarning)
41+
assert_equal(n_warns, len(filters))
42+
def f():
43+
with IgnoreWarnings():
44+
simplefilter('error')
45+
try:
46+
assert_raises(RuntimeError, f)
47+
assert_equal(n_warns+2, len(filters))
48+
finally:
49+
filters.pop(0)
50+
filters.pop(0)
51+
# Check other errors are propagated
52+
def f():
53+
with IgnoreWarnings():
54+
raise ValueError('An error')
55+
assert_raises(ValueError, f)

0 commit comments

Comments
 (0)