Skip to content

Commit c66028c

Browse files
simonjayhawkinsjreback
authored andcommitted
STY: use pytest.raises context manager (plotting, reductions, scalar...) (#25483)
* STY: use pytest.raises context manager (plotting, reductions, scalar...) * revert removed testing in test_timedelta.py * remove TODO from test_frame.py * skip py2 ci failure
1 parent cc5b73e commit c66028c

File tree

12 files changed

+180
-81
lines changed

12 files changed

+180
-81
lines changed

Diff for: pandas/tests/plotting/test_boxplot_method.py

+14-7
Original file line numberDiff line numberDiff line change
@@ -267,13 +267,20 @@ def test_grouped_box_return_type(self):
267267
def test_grouped_box_layout(self):
268268
df = self.hist_df
269269

270-
pytest.raises(ValueError, df.boxplot, column=['weight', 'height'],
271-
by=df.gender, layout=(1, 1))
272-
pytest.raises(ValueError, df.boxplot,
273-
column=['height', 'weight', 'category'],
274-
layout=(2, 1), return_type='dict')
275-
pytest.raises(ValueError, df.boxplot, column=['weight', 'height'],
276-
by=df.gender, layout=(-1, -1))
270+
msg = "Layout of 1x1 must be larger than required size 2"
271+
with pytest.raises(ValueError, match=msg):
272+
df.boxplot(column=['weight', 'height'], by=df.gender,
273+
layout=(1, 1))
274+
275+
msg = "The 'layout' keyword is not supported when 'by' is None"
276+
with pytest.raises(ValueError, match=msg):
277+
df.boxplot(column=['height', 'weight', 'category'],
278+
layout=(2, 1), return_type='dict')
279+
280+
msg = "At least one dimension of layout must be positive"
281+
with pytest.raises(ValueError, match=msg):
282+
df.boxplot(column=['weight', 'height'], by=df.gender,
283+
layout=(-1, -1))
277284

278285
# _check_plot_works adds an ax so catch warning. see GH #13188
279286
with tm.assert_produces_warning(UserWarning):

Diff for: pandas/tests/plotting/test_datetimelike.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ def test_nonnumeric_exclude(self):
9797
assert len(ax.get_lines()) == 1 # B was plotted
9898
self.plt.close(fig)
9999

100-
pytest.raises(TypeError, df['A'].plot)
100+
msg = "Empty 'DataFrame': no numeric data to plot"
101+
with pytest.raises(TypeError, match=msg):
102+
df['A'].plot()
101103

102104
def test_tsplot_deprecated(self):
103105
from pandas.tseries.plotting import tsplot
@@ -140,10 +142,15 @@ def f(*args, **kwds):
140142
def test_both_style_and_color(self):
141143

142144
ts = tm.makeTimeSeries()
143-
pytest.raises(ValueError, ts.plot, style='b-', color='#000099')
145+
msg = ("Cannot pass 'style' string with a color symbol and 'color' "
146+
"keyword argument. Please use one or the other or pass 'style'"
147+
" without a color symbol")
148+
with pytest.raises(ValueError, match=msg):
149+
ts.plot(style='b-', color='#000099')
144150

145151
s = ts.reset_index(drop=True)
146-
pytest.raises(ValueError, s.plot, style='b-', color='#000099')
152+
with pytest.raises(ValueError, match=msg):
153+
s.plot(style='b-', color='#000099')
147154

148155
@pytest.mark.slow
149156
def test_high_freq(self):

Diff for: pandas/tests/plotting/test_hist_method.py

+11-6
Original file line numberDiff line numberDiff line change
@@ -332,12 +332,17 @@ def test_grouped_hist_legacy2(self):
332332
@pytest.mark.slow
333333
def test_grouped_hist_layout(self):
334334
df = self.hist_df
335-
pytest.raises(ValueError, df.hist, column='weight', by=df.gender,
336-
layout=(1, 1))
337-
pytest.raises(ValueError, df.hist, column='height', by=df.category,
338-
layout=(1, 3))
339-
pytest.raises(ValueError, df.hist, column='height', by=df.category,
340-
layout=(-1, -1))
335+
msg = "Layout of 1x1 must be larger than required size 2"
336+
with pytest.raises(ValueError, match=msg):
337+
df.hist(column='weight', by=df.gender, layout=(1, 1))
338+
339+
msg = "Layout of 1x3 must be larger than required size 4"
340+
with pytest.raises(ValueError, match=msg):
341+
df.hist(column='height', by=df.category, layout=(1, 3))
342+
343+
msg = "At least one dimension of layout must be positive"
344+
with pytest.raises(ValueError, match=msg):
345+
df.hist(column='height', by=df.category, layout=(-1, -1))
341346

342347
with tm.assert_produces_warning(UserWarning):
343348
axes = _check_plot_works(df.hist, column='height', by=df.gender,

Diff for: pandas/tests/plotting/test_misc.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -278,14 +278,20 @@ def test_subplot_titles(self, iris):
278278
assert [p.get_title() for p in plot] == title
279279

280280
# Case len(title) > len(df)
281-
pytest.raises(ValueError, df.plot, subplots=True,
282-
title=title + ["kittens > puppies"])
281+
msg = ("The length of `title` must equal the number of columns if"
282+
" using `title` of type `list` and `subplots=True`")
283+
with pytest.raises(ValueError, match=msg):
284+
df.plot(subplots=True, title=title + ["kittens > puppies"])
283285

284286
# Case len(title) < len(df)
285-
pytest.raises(ValueError, df.plot, subplots=True, title=title[:2])
287+
with pytest.raises(ValueError, match=msg):
288+
df.plot(subplots=True, title=title[:2])
286289

287290
# Case subplots=False and title is of type list
288-
pytest.raises(ValueError, df.plot, subplots=False, title=title)
291+
msg = ("Using `title` of type `list` is not supported unless"
292+
" `subplots=True` is passed")
293+
with pytest.raises(ValueError, match=msg):
294+
df.plot(subplots=False, title=title)
289295

290296
# Case df with 3 numeric columns but layout of (2,2)
291297
plot = df.drop('SepalWidth', axis=1).plot(subplots=True, layout=(2, 2),

Diff for: pandas/tests/reductions/test_reductions.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,9 @@ def test_timedelta_ops(self):
276276

277277
# invalid ops
278278
for op in ['skew', 'kurt', 'sem', 'prod']:
279-
pytest.raises(TypeError, getattr(td, op))
279+
msg = "reduction operation '{}' not allowed for this dtype"
280+
with pytest.raises(TypeError, match=msg.format(op)):
281+
getattr(td, op)()
280282

281283
# GH#10040
282284
# make sure NaT is properly handled by median()

Diff for: pandas/tests/scalar/period/test_period.py

+12-9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from pandas._libs.tslibs.ccalendar import DAYS, MONTHS
99
from pandas._libs.tslibs.frequencies import INVALID_FREQ_ERR_MSG
1010
from pandas._libs.tslibs.parsing import DateParseError
11+
from pandas._libs.tslibs.period import IncompatibleFrequency
1112
from pandas._libs.tslibs.timezones import dateutil_gettz, maybe_get_tz
1213
from pandas.compat import iteritems, text_type
1314
from pandas.compat.numpy import np_datetime64_compat
@@ -35,7 +36,9 @@ def test_construction(self):
3536
i4 = Period('2005', freq='M')
3637
i5 = Period('2005', freq='m')
3738

38-
pytest.raises(ValueError, i1.__ne__, i4)
39+
msg = r"Input has different freq=M from Period\(freq=A-DEC\)"
40+
with pytest.raises(IncompatibleFrequency, match=msg):
41+
i1 != i4
3942
assert i4 == i5
4043

4144
i1 = Period.now('Q')
@@ -74,9 +77,12 @@ def test_construction(self):
7477
freq='U')
7578
assert i1 == expected
7679

77-
pytest.raises(ValueError, Period, ordinal=200701)
80+
msg = "Must supply freq for ordinal value"
81+
with pytest.raises(ValueError, match=msg):
82+
Period(ordinal=200701)
7883

79-
pytest.raises(ValueError, Period, '2007-1-1', freq='X')
84+
with pytest.raises(ValueError, match="Invalid frequency: X"):
85+
Period('2007-1-1', freq='X')
8086

8187
def test_construction_bday(self):
8288

@@ -233,10 +239,6 @@ def test_period_constructor_offsets(self):
233239
freq='U')
234240
assert i1 == expected
235241

236-
pytest.raises(ValueError, Period, ordinal=200701)
237-
238-
pytest.raises(ValueError, Period, '2007-1-1', freq='X')
239-
240242
def test_invalid_arguments(self):
241243
with pytest.raises(ValueError):
242244
Period(datetime.now())
@@ -925,8 +927,9 @@ def test_properties_secondly(self):
925927
class TestPeriodField(object):
926928

927929
def test_get_period_field_array_raises_on_out_of_range(self):
928-
pytest.raises(ValueError, libperiod.get_period_field_arr, -1,
929-
np.empty(1), 0)
930+
msg = "Buffer dtype mismatch, expected 'int64_t' but got 'double'"
931+
with pytest.raises(ValueError, match=msg):
932+
libperiod.get_period_field_arr(-1, np.empty(1), 0)
930933

931934

932935
class TestComparisons(object):

Diff for: pandas/tests/scalar/timedelta/test_timedelta.py

+32-13
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,13 @@ def check(value):
250250
assert rng.microseconds == 0
251251
assert rng.nanoseconds == 0
252252

253-
pytest.raises(AttributeError, lambda: rng.hours)
254-
pytest.raises(AttributeError, lambda: rng.minutes)
255-
pytest.raises(AttributeError, lambda: rng.milliseconds)
253+
msg = "'Timedelta' object has no attribute '{}'"
254+
with pytest.raises(AttributeError, match=msg.format('hours')):
255+
rng.hours
256+
with pytest.raises(AttributeError, match=msg.format('minutes')):
257+
rng.minutes
258+
with pytest.raises(AttributeError, match=msg.format('milliseconds')):
259+
rng.milliseconds
256260

257261
# GH 10050
258262
check(rng.days)
@@ -272,9 +276,13 @@ def check(value):
272276
assert rng.seconds == 10 * 3600 + 11 * 60 + 12
273277
assert rng.microseconds == 100 * 1000 + 123
274278
assert rng.nanoseconds == 456
275-
pytest.raises(AttributeError, lambda: rng.hours)
276-
pytest.raises(AttributeError, lambda: rng.minutes)
277-
pytest.raises(AttributeError, lambda: rng.milliseconds)
279+
msg = "'Timedelta' object has no attribute '{}'"
280+
with pytest.raises(AttributeError, match=msg.format('hours')):
281+
rng.hours
282+
with pytest.raises(AttributeError, match=msg.format('minutes')):
283+
rng.minutes
284+
with pytest.raises(AttributeError, match=msg.format('milliseconds')):
285+
rng.milliseconds
278286

279287
# components
280288
tup = pd.to_timedelta(-1, 'us').components
@@ -449,8 +457,12 @@ def test_round(self):
449457
assert r2 == s2
450458

451459
# invalid
452-
for freq in ['Y', 'M', 'foobar']:
453-
pytest.raises(ValueError, lambda: t1.round(freq))
460+
for freq, msg in [
461+
('Y', '<YearEnd: month=12> is a non-fixed frequency'),
462+
('M', '<MonthEnd> is a non-fixed frequency'),
463+
('foobar', 'Invalid frequency: foobar')]:
464+
with pytest.raises(ValueError, match=msg):
465+
t1.round(freq)
454466

455467
t1 = timedelta_range('1 days', periods=3, freq='1 min 2 s 3 us')
456468
t2 = -1 * t1
@@ -495,11 +507,15 @@ def test_round(self):
495507
r1 = t1.round(freq)
496508
tm.assert_index_equal(r1, s1)
497509
r2 = t2.round(freq)
498-
tm.assert_index_equal(r2, s2)
510+
tm.assert_index_equal(r2, s2)
499511

500512
# invalid
501-
for freq in ['Y', 'M', 'foobar']:
502-
pytest.raises(ValueError, lambda: t1.round(freq))
513+
for freq, msg in [
514+
('Y', '<YearEnd: month=12> is a non-fixed frequency'),
515+
('M', '<MonthEnd> is a non-fixed frequency'),
516+
('foobar', 'Invalid frequency: foobar')]:
517+
with pytest.raises(ValueError, match=msg):
518+
t1.round(freq)
503519

504520
def test_contains(self):
505521
# Checking for any NaT-like objects
@@ -609,9 +625,12 @@ def test_overflow(self):
609625
assert np.allclose(result.value / 1000, expected.value / 1000)
610626

611627
# sum
612-
pytest.raises(ValueError, lambda: (s - s.min()).sum())
628+
msg = "overflow in timedelta operation"
629+
with pytest.raises(ValueError, match=msg):
630+
(s - s.min()).sum()
613631
s1 = s[0:10000]
614-
pytest.raises(ValueError, lambda: (s1 - s1.min()).sum())
632+
with pytest.raises(ValueError, match=msg):
633+
(s1 - s1.min()).sum()
615634
s2 = s[0:1000]
616635
result = (s2 - s2.min()).sum()
617636

Diff for: pandas/tests/scalar/timestamp/test_timestamp.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ def check(value, equal):
6060
check(ts.hour, 9)
6161
check(ts.minute, 6)
6262
check(ts.second, 3)
63-
pytest.raises(AttributeError, lambda: ts.millisecond)
63+
msg = "'Timestamp' object has no attribute 'millisecond'"
64+
with pytest.raises(AttributeError, match=msg):
65+
ts.millisecond
6466
check(ts.microsecond, 100)
6567
check(ts.nanosecond, 1)
6668
check(ts.dayofweek, 6)
@@ -78,7 +80,9 @@ def check(value, equal):
7880
check(ts.hour, 23)
7981
check(ts.minute, 59)
8082
check(ts.second, 0)
81-
pytest.raises(AttributeError, lambda: ts.millisecond)
83+
msg = "'Timestamp' object has no attribute 'millisecond'"
84+
with pytest.raises(AttributeError, match=msg):
85+
ts.millisecond
8286
check(ts.microsecond, 0)
8387
check(ts.nanosecond, 0)
8488
check(ts.dayofweek, 2)

Diff for: pandas/tests/sparse/frame/test_frame.py

+32-15
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import pytest
88

99
from pandas._libs.sparse import BlockIndex, IntIndex
10-
from pandas.compat import lrange
10+
from pandas.compat import PY2, lrange
1111
from pandas.errors import PerformanceWarning
1212

1313
import pandas as pd
@@ -145,8 +145,9 @@ def test_constructor_ndarray(self, float_frame):
145145
tm.assert_sp_frame_equal(sp, float_frame.reindex(columns=['A']))
146146

147147
# raise on level argument
148-
pytest.raises(TypeError, float_frame.reindex, columns=['A'],
149-
level=1)
148+
msg = "Reindex by level not supported for sparse"
149+
with pytest.raises(TypeError, match=msg):
150+
float_frame.reindex(columns=['A'], level=1)
150151

151152
# wrong length index / columns
152153
with pytest.raises(ValueError, match="^Index length"):
@@ -433,7 +434,8 @@ def test_getitem(self):
433434
exp = sdf.reindex(columns=['a', 'b'])
434435
tm.assert_sp_frame_equal(result, exp)
435436

436-
pytest.raises(Exception, sdf.__getitem__, ['a', 'd'])
437+
with pytest.raises(KeyError, match=r"\['d'\] not in index"):
438+
sdf[['a', 'd']]
437439

438440
def test_iloc(self, float_frame):
439441

@@ -504,7 +506,9 @@ def test_getitem_overload(self, float_frame):
504506
subframe = float_frame[indexer]
505507

506508
tm.assert_index_equal(subindex, subframe.index)
507-
pytest.raises(Exception, float_frame.__getitem__, indexer[:-1])
509+
msg = "Item wrong length 9 instead of 10"
510+
with pytest.raises(ValueError, match=msg):
511+
float_frame[indexer[:-1]]
508512

509513
def test_setitem(self, float_frame, float_frame_int_kind,
510514
float_frame_dense,
@@ -551,8 +555,9 @@ def _check_frame(frame, orig):
551555
assert len(frame['I'].sp_values) == N // 2
552556

553557
# insert ndarray wrong size
554-
pytest.raises(Exception, frame.__setitem__, 'foo',
555-
np.random.randn(N - 1))
558+
msg = "Length of values does not match length of index"
559+
with pytest.raises(AssertionError, match=msg):
560+
frame['foo'] = np.random.randn(N - 1)
556561

557562
# scalar value
558563
frame['J'] = 5
@@ -625,17 +630,22 @@ def test_delitem(self, float_frame):
625630

626631
def test_set_columns(self, float_frame):
627632
float_frame.columns = float_frame.columns
628-
pytest.raises(Exception, setattr, float_frame, 'columns',
629-
float_frame.columns[:-1])
633+
msg = ("Length mismatch: Expected axis has 4 elements, new values have"
634+
" 3 elements")
635+
with pytest.raises(ValueError, match=msg):
636+
float_frame.columns = float_frame.columns[:-1]
630637

631638
def test_set_index(self, float_frame):
632639
float_frame.index = float_frame.index
633-
pytest.raises(Exception, setattr, float_frame, 'index',
634-
float_frame.index[:-1])
640+
msg = ("Length mismatch: Expected axis has 10 elements, new values"
641+
" have 9 elements")
642+
with pytest.raises(ValueError, match=msg):
643+
float_frame.index = float_frame.index[:-1]
635644

636645
def test_ctor_reindex(self):
637646
idx = pd.Index([0, 1, 2, 3])
638-
with pytest.raises(ValueError, match=''):
647+
msg = "Length of passed values is 2, index implies 4"
648+
with pytest.raises(ValueError, match=msg):
639649
pd.SparseDataFrame({"A": [1, 2]}, index=idx)
640650

641651
def test_append(self, float_frame):
@@ -858,14 +868,18 @@ def test_describe(self, float_frame):
858868
str(float_frame)
859869
desc = float_frame.describe() # noqa
860870

871+
@pytest.mark.skipif(PY2, reason="pytest.raises match regex fails")
861872
def test_join(self, float_frame):
862873
left = float_frame.loc[:, ['A', 'B']]
863874
right = float_frame.loc[:, ['C', 'D']]
864875
joined = left.join(right)
865876
tm.assert_sp_frame_equal(joined, float_frame, exact_indices=False)
866877

867878
right = float_frame.loc[:, ['B', 'D']]
868-
pytest.raises(Exception, left.join, right)
879+
msg = (r"columns overlap but no suffix specified: Index\(\['B'\],"
880+
r" dtype='object'\)")
881+
with pytest.raises(ValueError, match=msg):
882+
left.join(right)
869883

870884
with pytest.raises(ValueError, match='Other Series must have a name'):
871885
float_frame.join(Series(
@@ -1046,8 +1060,11 @@ def _check(frame):
10461060
_check(float_frame_int_kind)
10471061

10481062
# for now
1049-
pytest.raises(Exception, _check, float_frame_fill0)
1050-
pytest.raises(Exception, _check, float_frame_fill2)
1063+
msg = "This routine assumes NaN fill value"
1064+
with pytest.raises(TypeError, match=msg):
1065+
_check(float_frame_fill0)
1066+
with pytest.raises(TypeError, match=msg):
1067+
_check(float_frame_fill2)
10511068

10521069
def test_transpose(self, float_frame, float_frame_int_kind,
10531070
float_frame_dense,

0 commit comments

Comments
 (0)