Skip to content

Commit aa6a670

Browse files
author
Joan Massich
committed
Add match_regex functionality to warns
1 parent d8ecca5 commit aa6a670

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

_pytest/recwarn.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import sys
99
import warnings
1010

11+
import re
12+
1113
from _pytest.fixtures import yield_fixture
1214
from _pytest.outcomes import fail
1315

@@ -99,22 +101,24 @@ def warns(expected_warning, *args, **kwargs):
99101
>>> with warns(RuntimeWarning):
100102
... warnings.warn("my warning", RuntimeWarning)
101103
"""
102-
wcheck = WarningsChecker(expected_warning)
104+
match_expr = None
103105
if not args:
104-
return wcheck
106+
if "match" in kwargs:
107+
match_expr = kwargs.pop("match")
108+
return WarningsChecker(expected_warning, match_expr=match_expr)
105109
elif isinstance(args[0], str):
106110
code, = args
107111
assert isinstance(code, str)
108112
frame = sys._getframe(1)
109113
loc = frame.f_locals.copy()
110114
loc.update(kwargs)
111115

112-
with wcheck:
116+
with WarningsChecker(expected_warning, match_expr=match_expr):
113117
code = _pytest._code.Source(code).compile()
114118
py.builtin.exec_(code, frame.f_globals, loc)
115119
else:
116120
func = args[0]
117-
with wcheck:
121+
with WarningsChecker(expected_warning, match_expr=match_expr):
118122
return func(*args[1:], **kwargs)
119123

120124

@@ -174,7 +178,7 @@ def __exit__(self, *exc_info):
174178

175179

176180
class WarningsChecker(WarningsRecorder):
177-
def __init__(self, expected_warning=None):
181+
def __init__(self, expected_warning=None, match_expr=None):
178182
super(WarningsChecker, self).__init__()
179183

180184
msg = ("exceptions must be old-style classes or "
@@ -189,6 +193,7 @@ def __init__(self, expected_warning=None):
189193
raise TypeError(msg % type(expected_warning))
190194

191195
self.expected_warning = expected_warning
196+
self.match_expr = match_expr
192197

193198
def __exit__(self, *exc_info):
194199
super(WarningsChecker, self).__exit__(*exc_info)
@@ -203,3 +208,15 @@ def __exit__(self, *exc_info):
203208
"The list of emitted warnings is: {1}.".format(
204209
self.expected_warning,
205210
[each.message for each in self]))
211+
elif self.match_expr is not None:
212+
for r in self:
213+
if issubclass(r.category, self.expected_warning):
214+
if re.compile(self.match_expr).search(str(r.message)):
215+
break
216+
else:
217+
fail("DID NOT WARN. No warnings of type {0} matching"
218+
" ('{1}') was emitted. The list of emitted warnings"
219+
" is: {2}.".format(
220+
self.expected_warning,
221+
self.match_expr,
222+
[each.message for each in self]))

testing/test_recwarn.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -289,20 +289,22 @@ def test_match_regex(self):
289289
with pytest.warns(UserWarning, match=r'must be \d+$'):
290290
warnings.warn("value must be 42", UserWarning)
291291

292-
with pytest.raises(AssertionError, match='pattern not found'):
292+
with pytest.raises(pytest.fail.Exception):
293293
with pytest.warns(UserWarning, match=r'must be \d+$'):
294294
warnings.warn("this is not here", UserWarning)
295295

296-
def test_one_from_multiple_warns():
297-
with warns(UserWarning, match=r'aaa'):
296+
with pytest.raises(pytest.fail.Exception):
297+
with pytest.warns(FutureWarning, match=r'must be \d+$'):
298+
warnings.warn("value must be 42", UserWarning)
299+
300+
def test_one_from_multiple_warns(self):
301+
with pytest.warns(UserWarning, match=r'aaa'):
298302
warnings.warn("cccccccccc", UserWarning)
299303
warnings.warn("bbbbbbbbbb", UserWarning)
300304
warnings.warn("aaaaaaaaaa", UserWarning)
301305

302-
def test_none_of_multiple_warns():
303-
a, b, c = ('aaa', 'bbbbbbbbbb', 'cccccccccc')
304-
expected_msg = "'{}' pattern not found in \['{}', '{}'\]".format(a, b, c)
305-
with raises(AssertionError, match=expected_msg):
306-
with warns(UserWarning, match=r'aaa'):
306+
def test_none_of_multiple_warns(self):
307+
with pytest.raises(pytest.fail.Exception):
308+
with pytest.warns(UserWarning, match=r'aaa'):
307309
warnings.warn("bbbbbbbbbb", UserWarning)
308310
warnings.warn("cccccccccc", UserWarning)

0 commit comments

Comments
 (0)