Skip to content

Commit 42a6246

Browse files
simonjayhawkinsjreback
authored andcommitted
STY: use pytest.raises context manager (tests/test_*) (#25452)
* STY: use pytest.raises context manager (tests/test_*) * fix ci failures * skip py2 ci failure
1 parent 72367b7 commit 42a6246

File tree

7 files changed

+193
-92
lines changed

7 files changed

+193
-92
lines changed

pandas/tests/test_algos.py

+18-7
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from pandas._libs import (
1313
algos as libalgos, groupby as libgroupby, hashtable as ht)
14-
from pandas.compat import lrange, range
14+
from pandas.compat import PY2, lrange, range
1515
from pandas.compat.numpy import np_array_datetime64_compat
1616
import pandas.util._test_decorators as td
1717

@@ -224,11 +224,16 @@ def test_factorize_tuple_list(self, data, expected_label, expected_level):
224224
dtype=object)
225225
tm.assert_numpy_array_equal(result[1], expected_level_array)
226226

227+
@pytest.mark.skipif(PY2, reason="pytest.raises match regex fails")
227228
def test_complex_sorting(self):
228229
# gh 12666 - check no segfault
229230
x17 = np.array([complex(i) for i in range(17)], dtype=object)
230231

231-
pytest.raises(TypeError, algos.factorize, x17[::-1], sort=True)
232+
msg = ("'<' not supported between instances of 'complex' and"
233+
r" 'complex'|"
234+
r"unorderable types: complex\(\) > complex\(\)")
235+
with pytest.raises(TypeError, match=msg):
236+
algos.factorize(x17[::-1], sort=True)
232237

233238
def test_float64_factorize(self, writable):
234239
data = np.array([1.0, 1e8, 1.0, 1e-8, 1e8, 1.0], dtype=np.float64)
@@ -589,9 +594,14 @@ class TestIsin(object):
589594

590595
def test_invalid(self):
591596

592-
pytest.raises(TypeError, lambda: algos.isin(1, 1))
593-
pytest.raises(TypeError, lambda: algos.isin(1, [1]))
594-
pytest.raises(TypeError, lambda: algos.isin([1], 1))
597+
msg = (r"only list-like objects are allowed to be passed to isin\(\),"
598+
r" you passed a \[int\]")
599+
with pytest.raises(TypeError, match=msg):
600+
algos.isin(1, 1)
601+
with pytest.raises(TypeError, match=msg):
602+
algos.isin(1, [1])
603+
with pytest.raises(TypeError, match=msg):
604+
algos.isin([1], 1)
595605

596606
def test_basic(self):
597607

@@ -819,8 +829,9 @@ def test_value_counts_dtypes(self):
819829
result = algos.value_counts(Series([1, 1., '1'])) # object
820830
assert len(result) == 2
821831

822-
pytest.raises(TypeError, lambda s: algos.value_counts(s, bins=1),
823-
['1', 1])
832+
msg = "bins argument only works with numeric data"
833+
with pytest.raises(TypeError, match=msg):
834+
algos.value_counts(['1', 1], bins=1)
824835

825836
def test_value_counts_nat(self):
826837
td = Series([np.timedelta64(10000), pd.NaT], dtype='timedelta64[ns]')

pandas/tests/test_config.py

+69-35
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
import pytest
55

6+
from pandas.compat import PY2
7+
68
import pandas as pd
9+
from pandas.core.config import OptionError
710

811

912
class TestConfig(object):
@@ -48,26 +51,35 @@ def test_is_one_of_factory(self):
4851

4952
v(12)
5053
v(None)
51-
pytest.raises(ValueError, v, 1.1)
54+
msg = r"Value must be one of None\|12"
55+
with pytest.raises(ValueError, match=msg):
56+
v(1.1)
5257

5358
def test_register_option(self):
5459
self.cf.register_option('a', 1, 'doc')
5560

5661
# can't register an already registered option
57-
pytest.raises(KeyError, self.cf.register_option, 'a', 1, 'doc')
62+
msg = "Option 'a' has already been registered"
63+
with pytest.raises(OptionError, match=msg):
64+
self.cf.register_option('a', 1, 'doc')
5865

5966
# can't register an already registered option
60-
pytest.raises(KeyError, self.cf.register_option, 'a.b.c.d1', 1,
61-
'doc')
62-
pytest.raises(KeyError, self.cf.register_option, 'a.b.c.d2', 1,
63-
'doc')
67+
msg = "Path prefix to option 'a' is already an option"
68+
with pytest.raises(OptionError, match=msg):
69+
self.cf.register_option('a.b.c.d1', 1, 'doc')
70+
with pytest.raises(OptionError, match=msg):
71+
self.cf.register_option('a.b.c.d2', 1, 'doc')
6472

6573
# no python keywords
66-
pytest.raises(ValueError, self.cf.register_option, 'for', 0)
67-
pytest.raises(ValueError, self.cf.register_option, 'a.for.b', 0)
74+
msg = "for is a python keyword"
75+
with pytest.raises(ValueError, match=msg):
76+
self.cf.register_option('for', 0)
77+
with pytest.raises(ValueError, match=msg):
78+
self.cf.register_option('a.for.b', 0)
6879
# must be valid identifier (ensure attribute access works)
69-
pytest.raises(ValueError, self.cf.register_option,
70-
'Oh my Goddess!', 0)
80+
msg = "oh my goddess! is not a valid identifier"
81+
with pytest.raises(ValueError, match=msg):
82+
self.cf.register_option('Oh my Goddess!', 0)
7183

7284
# we can register options several levels deep
7385
# without predefining the intermediate steps
@@ -90,7 +102,9 @@ def test_describe_option(self):
90102
self.cf.register_option('l', "foo")
91103

92104
# non-existent keys raise KeyError
93-
pytest.raises(KeyError, self.cf.describe_option, 'no.such.key')
105+
msg = r"No such keys\(s\)"
106+
with pytest.raises(OptionError, match=msg):
107+
self.cf.describe_option('no.such.key')
94108

95109
# we can get the description for any key we registered
96110
assert 'doc' in self.cf.describe_option('a', _print_desc=False)
@@ -122,7 +136,9 @@ def test_case_insensitive(self):
122136
assert self.cf.get_option('kAnBaN') == 2
123137

124138
# gets of non-existent keys fail
125-
pytest.raises(KeyError, self.cf.get_option, 'no_such_option')
139+
msg = r"No such keys\(s\): 'no_such_option'"
140+
with pytest.raises(OptionError, match=msg):
141+
self.cf.get_option('no_such_option')
126142
self.cf.deprecate_option('KanBan')
127143

128144
assert self.cf._is_deprecated('kAnBaN')
@@ -138,7 +154,9 @@ def test_get_option(self):
138154
assert self.cf.get_option('b.b') is None
139155

140156
# gets of non-existent keys fail
141-
pytest.raises(KeyError, self.cf.get_option, 'no_such_option')
157+
msg = r"No such keys\(s\): 'no_such_option'"
158+
with pytest.raises(OptionError, match=msg):
159+
self.cf.get_option('no_such_option')
142160

143161
def test_set_option(self):
144162
self.cf.register_option('a', 1, 'doc')
@@ -157,16 +175,24 @@ def test_set_option(self):
157175
assert self.cf.get_option('b.c') == 'wurld'
158176
assert self.cf.get_option('b.b') == 1.1
159177

160-
pytest.raises(KeyError, self.cf.set_option, 'no.such.key', None)
178+
msg = r"No such keys\(s\): 'no.such.key'"
179+
with pytest.raises(OptionError, match=msg):
180+
self.cf.set_option('no.such.key', None)
161181

162182
def test_set_option_empty_args(self):
163-
pytest.raises(ValueError, self.cf.set_option)
183+
msg = "Must provide an even number of non-keyword arguments"
184+
with pytest.raises(ValueError, match=msg):
185+
self.cf.set_option()
164186

165187
def test_set_option_uneven_args(self):
166-
pytest.raises(ValueError, self.cf.set_option, 'a.b', 2, 'b.c')
188+
msg = "Must provide an even number of non-keyword arguments"
189+
with pytest.raises(ValueError, match=msg):
190+
self.cf.set_option('a.b', 2, 'b.c')
167191

168192
def test_set_option_invalid_single_argument_type(self):
169-
pytest.raises(ValueError, self.cf.set_option, 2)
193+
msg = "Must provide an even number of non-keyword arguments"
194+
with pytest.raises(ValueError, match=msg):
195+
self.cf.set_option(2)
170196

171197
def test_set_option_multiple(self):
172198
self.cf.register_option('a', 1, 'doc')
@@ -183,27 +209,36 @@ def test_set_option_multiple(self):
183209
assert self.cf.get_option('b.c') is None
184210
assert self.cf.get_option('b.b') == 10.0
185211

212+
@pytest.mark.skipif(PY2, reason="pytest.raises match regex fails")
186213
def test_validation(self):
187214
self.cf.register_option('a', 1, 'doc', validator=self.cf.is_int)
188215
self.cf.register_option('b.c', 'hullo', 'doc2',
189216
validator=self.cf.is_text)
190-
pytest.raises(ValueError, self.cf.register_option, 'a.b.c.d2',
191-
'NO', 'doc', validator=self.cf.is_int)
217+
msg = "Value must have type '<class 'int'>'"
218+
with pytest.raises(ValueError, match=msg):
219+
self.cf.register_option(
220+
'a.b.c.d2', 'NO', 'doc', validator=self.cf.is_int)
192221

193222
self.cf.set_option('a', 2) # int is_int
194223
self.cf.set_option('b.c', 'wurld') # str is_str
195224

196-
pytest.raises(
197-
ValueError, self.cf.set_option, 'a', None) # None not is_int
198-
pytest.raises(ValueError, self.cf.set_option, 'a', 'ab')
199-
pytest.raises(ValueError, self.cf.set_option, 'b.c', 1)
225+
# None not is_int
226+
with pytest.raises(ValueError, match=msg):
227+
self.cf.set_option('a', None)
228+
with pytest.raises(ValueError, match=msg):
229+
self.cf.set_option('a', 'ab')
230+
231+
msg = r"Value must be an instance of <class 'str'>\|<class 'bytes'>"
232+
with pytest.raises(ValueError, match=msg):
233+
self.cf.set_option('b.c', 1)
200234

201235
validator = self.cf.is_one_of_factory([None, self.cf.is_callable])
202236
self.cf.register_option('b', lambda: None, 'doc',
203237
validator=validator)
204238
self.cf.set_option('b', '%.1f'.format) # Formatter is callable
205239
self.cf.set_option('b', None) # Formatter is none (default)
206-
pytest.raises(ValueError, self.cf.set_option, 'b', '%.1f')
240+
with pytest.raises(ValueError, match="Value must be a callable"):
241+
self.cf.set_option('b', '%.1f')
207242

208243
def test_reset_option(self):
209244
self.cf.register_option('a', 1, 'doc', validator=self.cf.is_int)
@@ -267,8 +302,9 @@ def test_deprecate_option(self):
267302
assert 'eprecated' in str(w[-1]) # we get the default message
268303
assert 'nifty_ver' in str(w[-1]) # with the removal_ver quoted
269304

270-
pytest.raises(
271-
KeyError, self.cf.deprecate_option, 'a') # can't depr. twice
305+
msg = "Option 'a' has already been defined as deprecated"
306+
with pytest.raises(OptionError, match=msg):
307+
self.cf.deprecate_option('a')
272308

273309
self.cf.deprecate_option('b.c', 'zounds!')
274310
with warnings.catch_warnings(record=True) as w:
@@ -374,12 +410,6 @@ def eq(val):
374410
def test_attribute_access(self):
375411
holder = []
376412

377-
def f():
378-
options.b = 1
379-
380-
def f2():
381-
options.display = 1
382-
383413
def f3(key):
384414
holder.append(True)
385415

@@ -397,8 +427,11 @@ def f3(key):
397427
self.cf.reset_option("a")
398428
assert options.a == self.cf.get_option("a", 0)
399429

400-
pytest.raises(KeyError, f)
401-
pytest.raises(KeyError, f2)
430+
msg = "You can only set the value of existing options"
431+
with pytest.raises(OptionError, match=msg):
432+
options.b = 1
433+
with pytest.raises(OptionError, match=msg):
434+
options.display = 1
402435

403436
# make sure callback kicks when using this form of setting
404437
options.c = 1
@@ -429,5 +462,6 @@ def test_option_context_scope(self):
429462
def test_dictwrapper_getattr(self):
430463
options = self.cf.options
431464
# GH 19789
432-
pytest.raises(self.cf.OptionError, getattr, options, 'bananas')
465+
with pytest.raises(OptionError, match="No such option"):
466+
options.bananas
433467
assert not hasattr(options, 'bananas')

pandas/tests/test_multilevel.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -886,8 +886,11 @@ def test_count(self):
886886
tm.assert_series_equal(result, expect, check_names=False)
887887
assert result.index.name == 'a'
888888

889-
pytest.raises(KeyError, series.count, 'x')
890-
pytest.raises(KeyError, frame.count, level='x')
889+
msg = "Level x not found"
890+
with pytest.raises(KeyError, match=msg):
891+
series.count('x')
892+
with pytest.raises(KeyError, match=msg):
893+
frame.count(level='x')
891894

892895
@pytest.mark.parametrize('op', AGG_FUNCTIONS)
893896
@pytest.mark.parametrize('level', [0, 1])
@@ -1119,7 +1122,8 @@ def test_level_with_tuples(self):
11191122
tm.assert_series_equal(result, expected)
11201123
tm.assert_series_equal(result2, expected)
11211124

1122-
pytest.raises(KeyError, series.__getitem__, (('foo', 'bar', 0), 2))
1125+
with pytest.raises(KeyError, match=r"^\(\('foo', 'bar', 0\), 2\)$"):
1126+
series[('foo', 'bar', 0), 2]
11231127

11241128
result = frame.loc[('foo', 'bar', 0)]
11251129
result2 = frame.xs(('foo', 'bar', 0))

pandas/tests/test_nanops.py

+14-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import numpy as np
88
import pytest
99

10+
from pandas.compat import PY2
1011
from pandas.compat.numpy import _np_version_under1p13
1112
import pandas.util._test_decorators as td
1213

@@ -728,6 +729,7 @@ def test_numeric_values(self):
728729
# Test complex
729730
assert nanops._ensure_numeric(1 + 2j) == 1 + 2j
730731

732+
@pytest.mark.skipif(PY2, reason="pytest.raises match regex fails")
731733
def test_ndarray(self):
732734
# Test numeric ndarray
733735
values = np.array([1, 2, 3])
@@ -743,17 +745,25 @@ def test_ndarray(self):
743745

744746
# Test non-convertible string ndarray
745747
s_values = np.array(['foo', 'bar', 'baz'], dtype=object)
746-
pytest.raises(ValueError, lambda: nanops._ensure_numeric(s_values))
748+
msg = r"could not convert string to float: '(foo|baz)'"
749+
with pytest.raises(ValueError, match=msg):
750+
nanops._ensure_numeric(s_values)
747751

748752
def test_convertable_values(self):
749753
assert np.allclose(nanops._ensure_numeric('1'), 1.0)
750754
assert np.allclose(nanops._ensure_numeric('1.1'), 1.1)
751755
assert np.allclose(nanops._ensure_numeric('1+1j'), 1 + 1j)
752756

753757
def test_non_convertable_values(self):
754-
pytest.raises(TypeError, lambda: nanops._ensure_numeric('foo'))
755-
pytest.raises(TypeError, lambda: nanops._ensure_numeric({}))
756-
pytest.raises(TypeError, lambda: nanops._ensure_numeric([]))
758+
msg = "Could not convert foo to numeric"
759+
with pytest.raises(TypeError, match=msg):
760+
nanops._ensure_numeric('foo')
761+
msg = "Could not convert {} to numeric"
762+
with pytest.raises(TypeError, match=msg):
763+
nanops._ensure_numeric({})
764+
msg = r"Could not convert \[\] to numeric"
765+
with pytest.raises(TypeError, match=msg):
766+
nanops._ensure_numeric([])
757767

758768

759769
class TestNanvarFixedValues(object):

pandas/tests/test_sorting.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from numpy import nan
88
import pytest
99

10+
from pandas.compat import PY2
11+
1012
from pandas import DataFrame, MultiIndex, Series, compat, concat, merge
1113
from pandas.core import common as com
1214
from pandas.core.sorting import (
@@ -403,15 +405,21 @@ def test_mixed_integer_from_list(self):
403405
expected = np.array([0, 0, 1, 'a', 'b', 'b'], dtype=object)
404406
tm.assert_numpy_array_equal(result, expected)
405407

408+
@pytest.mark.skipif(PY2, reason="pytest.raises match regex fails")
406409
def test_unsortable(self):
407410
# GH 13714
408411
arr = np.array([1, 2, datetime.now(), 0, 3], dtype=object)
412+
msg = ("'<' not supported between instances of 'datetime.datetime'"
413+
r" and 'int'|"
414+
r"unorderable types: int\(\) > datetime.datetime\(\)")
409415
if compat.PY2:
410416
# RuntimeWarning: tp_compare didn't return -1 or -2 for exception
411417
with warnings.catch_warnings():
412-
pytest.raises(TypeError, safe_sort, arr)
418+
with pytest.raises(TypeError, match=msg):
419+
safe_sort(arr)
413420
else:
414-
pytest.raises(TypeError, safe_sort, arr)
421+
with pytest.raises(TypeError, match=msg):
422+
safe_sort(arr)
415423

416424
def test_exceptions(self):
417425
with pytest.raises(TypeError,

0 commit comments

Comments
 (0)