Skip to content

Commit fc3cee8

Browse files
committed
Don't remove, just deprecate assert_raises_regex
1 parent d9dffc5 commit fc3cee8

File tree

2 files changed

+141
-1
lines changed

2 files changed

+141
-1
lines changed

pandas/tests/util/test_testing.py

+10
Original file line numberDiff line numberDiff line change
@@ -877,3 +877,13 @@ def test_datapath_missing(datapath, request):
877877
)
878878

879879
assert result == expected
880+
881+
882+
def test_assert_raises_regex_deprecated():
883+
# see gh-23592
884+
885+
with tm.assert_produces_warning(FutureWarning):
886+
msg = "Not equal!"
887+
888+
with tm.assert_raises_regex(AssertionError, msg):
889+
assert 1 == 2, msg

pandas/util/testing.py

+131-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import pandas.compat as compat
2121
from pandas.compat import (
2222
PY2, PY3, Counter, StringIO, callable, filter, httplib, lmap, lrange, lzip,
23-
map, range, string_types, u, unichr, zip)
23+
map, raise_with_traceback, range, string_types, u, unichr, zip)
2424

2525
from pandas.core.dtypes.common import (
2626
is_bool, is_categorical_dtype, is_datetimelike_v_numeric,
@@ -2512,6 +2512,136 @@ def wrapper(*args, **kwargs):
25122512
with_connectivity_check = network
25132513

25142514

2515+
def assert_raises_regex(_exception, _regexp, _callable=None,
2516+
*args, **kwargs):
2517+
r"""
2518+
DEPRECATED: Please use `pytest.raises` instead.
2519+
2520+
Check that the specified Exception is raised and that the error message
2521+
matches a given regular expression pattern. This may be a regular
2522+
expression object or a string containing a regular expression suitable
2523+
for use by `re.search()`. This is a port of the `assertRaisesRegexp`
2524+
function from unittest in Python 2.7.
2525+
2526+
Examples
2527+
--------
2528+
>>> assert_raises_regex(ValueError, 'invalid literal for.*XYZ', int, 'XYZ')
2529+
>>> import re
2530+
>>> assert_raises_regex(ValueError, re.compile('literal'), int, 'XYZ')
2531+
2532+
If an exception of a different type is raised, it bubbles up.
2533+
2534+
>>> assert_raises_regex(TypeError, 'literal', int, 'XYZ')
2535+
Traceback (most recent call last):
2536+
...
2537+
ValueError: invalid literal for int() with base 10: 'XYZ'
2538+
>>> dct = dict()
2539+
>>> assert_raises_regex(KeyError, 'pear', dct.__getitem__, 'apple')
2540+
Traceback (most recent call last):
2541+
...
2542+
AssertionError: "pear" does not match "'apple'"
2543+
2544+
You can also use this in a with statement.
2545+
2546+
>>> with assert_raises_regex(TypeError, r'unsupported operand type\(s\)'):
2547+
... 1 + {}
2548+
>>> with assert_raises_regex(TypeError, 'banana'):
2549+
... 'apple'[0] = 'b'
2550+
Traceback (most recent call last):
2551+
...
2552+
AssertionError: "banana" does not match "'str' object does not support \
2553+
item assignment"
2554+
"""
2555+
warnings.warn(("assert_raises_regex has been deprecated and will "
2556+
"be removed in the next release. Please use "
2557+
"`pytest.raises` instead."), FutureWarning, stacklevel=2)
2558+
2559+
manager = _AssertRaisesContextmanager(exception=_exception, regexp=_regexp)
2560+
if _callable is not None:
2561+
with manager:
2562+
_callable(*args, **kwargs)
2563+
else:
2564+
return manager
2565+
2566+
2567+
class _AssertRaisesContextmanager(object):
2568+
"""
2569+
Context manager behind `assert_raises_regex`.
2570+
"""
2571+
2572+
def __init__(self, exception, regexp=None):
2573+
"""
2574+
Initialize an _AssertRaisesContextManager instance.
2575+
2576+
Parameters
2577+
----------
2578+
exception : class
2579+
The expected Exception class.
2580+
regexp : str, default None
2581+
The regex to compare against the Exception message.
2582+
"""
2583+
2584+
self.exception = exception
2585+
2586+
if regexp is not None and not hasattr(regexp, "search"):
2587+
regexp = re.compile(regexp, re.DOTALL)
2588+
2589+
self.regexp = regexp
2590+
2591+
def __enter__(self):
2592+
return self
2593+
2594+
def __exit__(self, exc_type, exc_value, trace_back):
2595+
expected = self.exception
2596+
2597+
if not exc_type:
2598+
exp_name = getattr(expected, "__name__", str(expected))
2599+
raise AssertionError("{name} not raised.".format(name=exp_name))
2600+
2601+
return self.exception_matches(exc_type, exc_value, trace_back)
2602+
2603+
def exception_matches(self, exc_type, exc_value, trace_back):
2604+
"""
2605+
Check that the Exception raised matches the expected Exception
2606+
and expected error message regular expression.
2607+
2608+
Parameters
2609+
----------
2610+
exc_type : class
2611+
The type of Exception raised.
2612+
exc_value : Exception
2613+
The instance of `exc_type` raised.
2614+
trace_back : stack trace object
2615+
The traceback object associated with `exc_value`.
2616+
2617+
Returns
2618+
-------
2619+
is_matched : bool
2620+
Whether or not the Exception raised matches the expected
2621+
Exception class and expected error message regular expression.
2622+
2623+
Raises
2624+
------
2625+
AssertionError : The error message provided does not match
2626+
the expected error message regular expression.
2627+
"""
2628+
2629+
if issubclass(exc_type, self.exception):
2630+
if self.regexp is not None:
2631+
val = str(exc_value)
2632+
2633+
if not self.regexp.search(val):
2634+
msg = '"{pat}" does not match "{val}"'.format(
2635+
pat=self.regexp.pattern, val=val)
2636+
e = AssertionError(msg)
2637+
raise_with_traceback(e, trace_back)
2638+
2639+
return True
2640+
else:
2641+
# Failed, so allow Exception to bubble up.
2642+
return False
2643+
2644+
25152645
@contextmanager
25162646
def assert_produces_warning(expected_warning=Warning, filter_level="always",
25172647
clear=None, check_stacklevel=True):

0 commit comments

Comments
 (0)