From dc0545a6966281b16b32f937b8c020715e4a49d1 Mon Sep 17 00:00:00 2001 From: Simon Hawkins Date: Sun, 6 Jan 2019 22:24:00 +0000 Subject: [PATCH 1/3] STY: use pytest.raises context syntax --- pandas/tests/io/formats/test_format.py | 13 ++-- pandas/tests/io/json/test_normalize.py | 19 +++--- pandas/tests/io/json/test_pandas.py | 85 +++++++++++++++++--------- pandas/tests/io/json/test_ujson.py | 8 ++- pandas/tests/io/msgpack/test_except.py | 20 +++--- pandas/tests/io/msgpack/test_limits.py | 15 +++-- pandas/tests/io/msgpack/test_obj.py | 19 +++--- pandas/tests/io/msgpack/test_pack.py | 17 ++++-- 8 files changed, 121 insertions(+), 75 deletions(-) diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index d175f669703c7..52dce572c6d4f 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -2720,7 +2720,12 @@ def test_format_percentiles(): expected = ['0%', '50%', '2.0%', '50%', '66.67%', '99.99%'] assert result == expected - pytest.raises(ValueError, fmt.format_percentiles, [0.1, np.nan, 0.5]) - pytest.raises(ValueError, fmt.format_percentiles, [-0.001, 0.1, 0.5]) - pytest.raises(ValueError, fmt.format_percentiles, [2, 0.1, 0.5]) - pytest.raises(ValueError, fmt.format_percentiles, [0.1, 0.5, 'a']) + msg = r"percentiles should all be in the interval \[0,1\]" + with pytest.raises(ValueError, match=msg): + fmt.format_percentiles([0.1, np.nan, 0.5]) + with pytest.raises(ValueError, match=msg): + fmt.format_percentiles([-0.001, 0.1, 0.5]) + with pytest.raises(ValueError, match=msg): + fmt.format_percentiles([2, 0.1, 0.5]) + with pytest.raises(ValueError, match=msg): + fmt.format_percentiles([0.1, 0.5, 'a']) diff --git a/pandas/tests/io/json/test_normalize.py b/pandas/tests/io/json/test_normalize.py index fd0953a4834ca..dac093da5cbf7 100644 --- a/pandas/tests/io/json/test_normalize.py +++ b/pandas/tests/io/json/test_normalize.py @@ -197,7 +197,8 @@ def test_meta_name_conflict(self): 'data': [{'foo': 'something', 'bar': 'else'}, {'foo': 'something2', 'bar': 'else2'}]}] - with pytest.raises(ValueError): + msg = "Conflicting metadata name foo, need distinguishing prefix" + with pytest.raises(ValueError, match=msg): json_normalize(data, 'data', meta=['foo', 'bar']) result = json_normalize(data, 'data', meta=['foo', 'bar'], @@ -366,13 +367,15 @@ def test_json_normalize_errors(self): assert j.fillna('').to_dict() == expected - pytest.raises(KeyError, - json_normalize, data=i['Trades'], - record_path=[['general', 'stocks']], - meta=[['general', 'tradeid'], - ['general', 'trade_version']], - errors='raise' - ) + msg = ("Try running with errors='ignore' as key 'trade_version'" + " is not always present") + with pytest.raises(KeyError, match=msg): + json_normalize( + data=i['Trades'], + record_path=[['general', 'stocks']], + meta=[['general', 'tradeid'], + ['general', 'trade_version']], + errors='raise') def test_donot_drop_nonevalues(self): # GH21356 diff --git a/pandas/tests/io/json/test_pandas.py b/pandas/tests/io/json/test_pandas.py index 5468413033002..155083900f83a 100644 --- a/pandas/tests/io/json/test_pandas.py +++ b/pandas/tests/io/json/test_pandas.py @@ -101,8 +101,12 @@ def test_frame_non_unique_index(self): df = DataFrame([['a', 'b'], ['c', 'd']], index=[1, 1], columns=['x', 'y']) - pytest.raises(ValueError, df.to_json, orient='index') - pytest.raises(ValueError, df.to_json, orient='columns') + msg = "DataFrame index must be unique for orient='index'" + with pytest.raises(ValueError, match=msg): + df.to_json(orient='index') + msg = "DataFrame index must be unique for orient='columns'" + with pytest.raises(ValueError, match=msg): + df.to_json(orient='columns') assert_frame_equal(df, read_json(df.to_json(orient='split'), orient='split')) @@ -116,9 +120,15 @@ def test_frame_non_unique_columns(self): df = DataFrame([['a', 'b'], ['c', 'd']], index=[1, 2], columns=['x', 'x']) - pytest.raises(ValueError, df.to_json, orient='index') - pytest.raises(ValueError, df.to_json, orient='columns') - pytest.raises(ValueError, df.to_json, orient='records') + msg = "DataFrame columns must be unique for orient='index'" + with pytest.raises(ValueError, match=msg): + df.to_json(orient='index') + msg = "DataFrame columns must be unique for orient='columns'" + with pytest.raises(ValueError, match=msg): + df.to_json(orient='columns') + msg = "DataFrame columns must be unique for orient='records'" + with pytest.raises(ValueError, match=msg): + df.to_json(orient='records') assert_frame_equal(df, read_json(df.to_json(orient='split'), orient='split', dtype=False)) @@ -156,13 +166,16 @@ def _check_orient(df, orient, dtype=None, numpy=False, # if we are not unique, then check that we are raising ValueError # for the appropriate orients if not df.index.is_unique and orient in ['index', 'columns']: - pytest.raises( - ValueError, lambda: df.to_json(orient=orient)) + msg = ("DataFrame index must be unique for orient='{}'" + .format(orient)) + with pytest.raises(ValueError, match=msg): + df.to_json(orient=orient) return if (not df.columns.is_unique and orient in ['index', 'columns', 'records']): - pytest.raises( - ValueError, lambda: df.to_json(orient=orient)) + # TODO: not executed. fix this. + with pytest.raises(ValueError, match='ksjkajksfjksjfkjs'): + df.to_json(orient=orient) return dfjson = df.to_json(orient=orient) @@ -326,21 +339,24 @@ def _check_all_orients(df, dtype=None, convert_axes=True, _check_orient(df.transpose().transpose(), "index", dtype=False) def test_frame_from_json_bad_data(self): - pytest.raises(ValueError, read_json, StringIO('{"key":b:a:d}')) + with pytest.raises(ValueError, match='Expected object or value'): + read_json(StringIO('{"key":b:a:d}')) # too few indices json = StringIO('{"columns":["A","B"],' '"index":["2","3"],' '"data":[[1.0,"1"],[2.0,"2"],[null,"3"]]}') - pytest.raises(ValueError, read_json, json, - orient="split") + msg = r"Shape of passed values is \(2, 3\), indices imply \(2, 2\)" + with pytest.raises(ValueError, match=msg): + read_json(json, orient="split") # too many columns json = StringIO('{"columns":["A","B","C"],' '"index":["1","2","3"],' '"data":[[1.0,"1"],[2.0,"2"],[null,"3"]]}') - pytest.raises(AssertionError, read_json, json, - orient="split") + msg = "3 columns passed, passed data had 2 columns" + with pytest.raises(AssertionError, match=msg): + read_json(json, orient="split") # bad key json = StringIO('{"badkey":["A","B"],' @@ -414,7 +430,9 @@ def test_frame_to_json_float_precision(self): def test_frame_to_json_except(self): df = DataFrame([1, 2, 3]) - pytest.raises(ValueError, df.to_json, orient="garbage") + msg = "Invalid value 'garbage' for option 'orient'" + with pytest.raises(ValueError, match=msg): + df.to_json(orient="garbage") def test_frame_empty(self): df = DataFrame(columns=['jim', 'joe']) @@ -540,7 +558,8 @@ def __str__(self): # check if non-printable content throws appropriate Exception df_nonprintable = DataFrame({'A': [binthing]}) - with pytest.raises(OverflowError): + msg = "Unsupported UTF-8 sequence length when encoding string" + with pytest.raises(OverflowError, match=msg): df_nonprintable.to_json() # the same with multiple columns threw segfaults @@ -565,7 +584,9 @@ def test_label_overflow(self): def test_series_non_unique_index(self): s = Series(['a', 'b'], index=[1, 1]) - pytest.raises(ValueError, s.to_json, orient='index') + msg = "Series index must be unique for orient='index'" + with pytest.raises(ValueError, match=msg): + s.to_json(orient='index') assert_series_equal(s, read_json(s.to_json(orient='split'), orient='split', typ='series')) @@ -637,7 +658,9 @@ def _check_all_orients(series, dtype=None, check_index_type=True): def test_series_to_json_except(self): s = Series([1, 2, 3]) - pytest.raises(ValueError, s.to_json, orient="garbage") + msg = "Invalid value 'garbage' for option 'orient'" + with pytest.raises(ValueError, match=msg): + s.to_json(orient="garbage") def test_series_from_json_precise_float(self): s = Series([4.56, 4.56, 4.56]) @@ -752,8 +775,9 @@ def test_w_date(date, date_unit=None): test_w_date('20130101 20:43:42.123456', date_unit='us') test_w_date('20130101 20:43:42.123456789', date_unit='ns') - pytest.raises(ValueError, df.to_json, date_format='iso', - date_unit='foo') + msg = "Invalid value 'foo' for option 'date_unit'" + with pytest.raises(ValueError, match=msg): + df.to_json(date_format='iso', date_unit='foo') def test_date_format_series(self): def test_w_date(date, date_unit=None): @@ -774,8 +798,9 @@ def test_w_date(date, date_unit=None): test_w_date('20130101 20:43:42.123456789', date_unit='ns') ts = Series(Timestamp('20130101 20:43:42.123'), index=self.ts.index) - pytest.raises(ValueError, ts.to_json, date_format='iso', - date_unit='foo') + msg = "Invalid value 'foo' for option 'date_unit'" + with pytest.raises(ValueError, match=msg): + ts.to_json(date_format='iso', date_unit='foo') def test_date_unit(self): df = self.tsframe.copy() @@ -940,14 +965,16 @@ def test_default_handler_numpy_unsupported_dtype(self): assert df.to_json(default_handler=str, orient="values") == expected def test_default_handler_raises(self): + msg = "raisin" + def my_handler_raises(obj): - raise TypeError("raisin") - pytest.raises(TypeError, - DataFrame({'a': [1, 2, object()]}).to_json, - default_handler=my_handler_raises) - pytest.raises(TypeError, - DataFrame({'a': [1, 2, complex(4, -5)]}).to_json, - default_handler=my_handler_raises) + raise TypeError(msg) + with pytest.raises(TypeError, match=msg): + DataFrame({'a': [1, 2, object()]}).to_json( + default_handler=my_handler_raises) + with pytest.raises(TypeError, match=msg): + DataFrame({'a': [1, 2, complex(4, -5)]}).to_json( + default_handler=my_handler_raises) def test_categorical(self): # GH4377 df.to_json segfaults with non-ndarray blocks diff --git a/pandas/tests/io/json/test_ujson.py b/pandas/tests/io/json/test_ujson.py index 7f5241def597f..63ba9bc0f0488 100644 --- a/pandas/tests/io/json/test_ujson.py +++ b/pandas/tests/io/json/test_ujson.py @@ -422,7 +422,9 @@ def test_datetime_units(self): roundtrip = ujson.decode(ujson.encode(val, date_unit='ns')) assert roundtrip == stamp.value - pytest.raises(ValueError, ujson.encode, val, date_unit='foo') + msg = "Invalid value 'foo' for option 'date_unit'" + with pytest.raises(ValueError, match=msg): + ujson.encode(val, date_unit='foo') def test_encode_to_utf8(self): unencoded = "\xe6\x97\xa5\xd1\x88" @@ -695,7 +697,9 @@ def recursive_attr(self): def __str__(self): return str(self.val) - pytest.raises(OverflowError, ujson.encode, _TestObject("foo")) + msg = "Maximum recursion level reached" + with pytest.raises(OverflowError, match=msg): + ujson.encode(_TestObject("foo")) assert '"foo"' == ujson.encode(_TestObject("foo"), default_handler=str) diff --git a/pandas/tests/io/msgpack/test_except.py b/pandas/tests/io/msgpack/test_except.py index d670e846c382a..cd894109e989f 100644 --- a/pandas/tests/io/msgpack/test_except.py +++ b/pandas/tests/io/msgpack/test_except.py @@ -22,16 +22,16 @@ def test_raise_from_object_hook(self): def hook(_): raise DummyException() - pytest.raises(DummyException, unpackb, packb({}), object_hook=hook) - pytest.raises(DummyException, unpackb, packb({'fizz': 'buzz'}), - object_hook=hook) - pytest.raises(DummyException, unpackb, packb({'fizz': 'buzz'}), - object_pairs_hook=hook) - pytest.raises(DummyException, unpackb, - packb({'fizz': {'buzz': 'spam'}}), object_hook=hook) - pytest.raises(DummyException, unpackb, - packb({'fizz': {'buzz': 'spam'}}), - object_pairs_hook=hook) + with pytest.raises(DummyException): + unpackb(packb({}), object_hook=hook) + with pytest.raises(DummyException): + unpackb(packb({'fizz': 'buzz'}), object_hook=hook) + with pytest.raises(DummyException): + unpackb(packb({'fizz': 'buzz'}), object_pairs_hook=hook) + with pytest.raises(DummyException): + unpackb(packb({'fizz': {'buzz': 'spam'}}), object_hook=hook) + with pytest.raises(DummyException): + unpackb(packb({'fizz': {'buzz': 'spam'}}), object_pairs_hook=hook) def test_invalid_value(self): msg = "Unpack failed: error" diff --git a/pandas/tests/io/msgpack/test_limits.py b/pandas/tests/io/msgpack/test_limits.py index cad51da483c71..4d70c6b346c9d 100644 --- a/pandas/tests/io/msgpack/test_limits.py +++ b/pandas/tests/io/msgpack/test_limits.py @@ -12,22 +12,25 @@ class TestLimits(object): def test_integer(self): x = -(2 ** 63) assert unpackb(packb(x)) == x - pytest.raises((OverflowError, ValueError), packb, x - 1) + msg = 'int too big to convert' + with pytest.raises((OverflowError, ValueError), match=msg): + packb(x - 1) x = 2 ** 64 - 1 assert unpackb(packb(x)) == x - pytest.raises((OverflowError, ValueError), packb, x + 1) + with pytest.raises((OverflowError, ValueError), match=msg): + packb(x + 1) def test_array_header(self): packer = Packer() packer.pack_array_header(2 ** 32 - 1) - pytest.raises((OverflowError, ValueError), - packer.pack_array_header, 2 ** 32) + with pytest.raises((OverflowError, ValueError)): + packer.pack_array_header(2 ** 32) def test_map_header(self): packer = Packer() packer.pack_map_header(2 ** 32 - 1) - pytest.raises((OverflowError, ValueError), - packer.pack_array_header, 2 ** 32) + with pytest.raises((OverflowError, ValueError)): + packer.pack_array_header(2 ** 32) def test_max_str_len(self): d = 'x' * 3 diff --git a/pandas/tests/io/msgpack/test_obj.py b/pandas/tests/io/msgpack/test_obj.py index 4a6b89907954e..471212f1bfe32 100644 --- a/pandas/tests/io/msgpack/test_obj.py +++ b/pandas/tests/io/msgpack/test_obj.py @@ -47,31 +47,28 @@ def test_decode_pairs_hook(self): assert unpacked[1] == prod_sum def test_only_one_obj_hook(self): - pytest.raises(TypeError, unpackb, b'', object_hook=lambda x: x, - object_pairs_hook=lambda x: x) + msg = "object_pairs_hook and object_hook are mutually exclusive" + with pytest.raises(TypeError, match=msg): + unpackb(b'', object_hook=lambda x: x, + object_pairs_hook=lambda x: x) def test_bad_hook(self): - def f(): + msg = r"can't serialize \(1\+2j\)" + with pytest.raises(TypeError, match=msg): packed = packb([3, 1 + 2j], default=lambda o: o) unpacked = unpackb(packed, use_list=1) # noqa - pytest.raises(TypeError, f) - def test_array_hook(self): packed = packb([1, 2, 3]) unpacked = unpackb(packed, list_hook=self._arr_to_str, use_list=1) assert unpacked == '123' def test_an_exception_in_objecthook1(self): - def f(): + with pytest.raises(DecodeError, match='Ooops!'): packed = packb({1: {'__complex__': True, 'real': 1, 'imag': 2}}) unpackb(packed, object_hook=self.bad_complex_decoder) - pytest.raises(DecodeError, f) - def test_an_exception_in_objecthook2(self): - def f(): + with pytest.raises(DecodeError, match='Ooops!'): packed = packb({1: [{'__complex__': True, 'real': 1, 'imag': 2}]}) unpackb(packed, list_hook=self.bad_complex_decoder, use_list=1) - - pytest.raises(DecodeError, f) diff --git a/pandas/tests/io/msgpack/test_pack.py b/pandas/tests/io/msgpack/test_pack.py index f69ac0a0bc4ce..1aa7baaa469d0 100644 --- a/pandas/tests/io/msgpack/test_pack.py +++ b/pandas/tests/io/msgpack/test_pack.py @@ -67,12 +67,17 @@ def testIgnoreUnicodeErrors(self): assert re == "abcdef" def testStrictUnicodeUnpack(self): - pytest.raises(UnicodeDecodeError, unpackb, packb(b'abc\xeddef'), - encoding='utf-8', use_list=1) + msg = ("'utf-8' codec can't decode byte 0xed in position 3:" + " invalid continuation byte") + with pytest.raises(UnicodeDecodeError, match=msg): + unpackb(packb(b'abc\xeddef'), encoding='utf-8', use_list=1) def testStrictUnicodePack(self): - pytest.raises(UnicodeEncodeError, packb, compat.u("abc\xeddef"), - encoding='ascii', unicode_errors='strict') + msg = (r"'ascii' codec can't encode character '\\xed' in position 3:" + r" ordinal not in range\(128\)") + with pytest.raises(UnicodeEncodeError, match=msg): + packb(compat.u("abc\xeddef"), encoding='ascii', + unicode_errors='strict') def testIgnoreErrorsPack(self): re = unpackb( @@ -82,7 +87,9 @@ def testIgnoreErrorsPack(self): assert re == compat.u("abcdef") def testNoEncoding(self): - pytest.raises(TypeError, packb, compat.u("abc"), encoding=None) + msg = "Can't encode unicode string: no encoding is specified" + with pytest.raises(TypeError, match=msg): + packb(compat.u("abc"), encoding=None) def testDecodeBinary(self): re = unpackb(packb("abc"), encoding=None, use_list=1) From 4e83d9b928d5f6601bde4663eeb7ce016644865d Mon Sep 17 00:00:00 2001 From: Simon Hawkins Date: Mon, 7 Jan 2019 08:39:58 +0000 Subject: [PATCH 2/3] fix CI failures --- pandas/tests/io/json/test_normalize.py | 3 ++- pandas/tests/io/msgpack/test_limits.py | 3 ++- pandas/tests/io/msgpack/test_pack.py | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pandas/tests/io/json/test_normalize.py b/pandas/tests/io/json/test_normalize.py index dac093da5cbf7..3bf699cc8a1f0 100644 --- a/pandas/tests/io/json/test_normalize.py +++ b/pandas/tests/io/json/test_normalize.py @@ -197,7 +197,8 @@ def test_meta_name_conflict(self): 'data': [{'foo': 'something', 'bar': 'else'}, {'foo': 'something2', 'bar': 'else2'}]}] - msg = "Conflicting metadata name foo, need distinguishing prefix" + msg = (r"Conflicting metadata name (foo|bar)," + " need distinguishing prefix") with pytest.raises(ValueError, match=msg): json_normalize(data, 'data', meta=['foo', 'bar']) diff --git a/pandas/tests/io/msgpack/test_limits.py b/pandas/tests/io/msgpack/test_limits.py index 4d70c6b346c9d..0e4a67b6e644f 100644 --- a/pandas/tests/io/msgpack/test_limits.py +++ b/pandas/tests/io/msgpack/test_limits.py @@ -12,7 +12,8 @@ class TestLimits(object): def test_integer(self): x = -(2 ** 63) assert unpackb(packb(x)) == x - msg = 'int too big to convert' + msg = (r"(int too big to convert|Python int too large" + " to convert to C long)") with pytest.raises((OverflowError, ValueError), match=msg): packb(x - 1) x = 2 ** 64 - 1 diff --git a/pandas/tests/io/msgpack/test_pack.py b/pandas/tests/io/msgpack/test_pack.py index 1aa7baaa469d0..8c82d0d2cf870 100644 --- a/pandas/tests/io/msgpack/test_pack.py +++ b/pandas/tests/io/msgpack/test_pack.py @@ -67,13 +67,13 @@ def testIgnoreUnicodeErrors(self): assert re == "abcdef" def testStrictUnicodeUnpack(self): - msg = ("'utf-8' codec can't decode byte 0xed in position 3:" + msg = (r"'utf-*8' codec can't decode byte 0xed in position 3:" " invalid continuation byte") with pytest.raises(UnicodeDecodeError, match=msg): unpackb(packb(b'abc\xeddef'), encoding='utf-8', use_list=1) def testStrictUnicodePack(self): - msg = (r"'ascii' codec can't encode character '\\xed' in position 3:" + msg = (r"'ascii' codec can't encode character u*'\\xed' in position 3:" r" ordinal not in range\(128\)") with pytest.raises(UnicodeEncodeError, match=msg): packb(compat.u("abc\xeddef"), encoding='ascii', From 3aff8d9bc7a823fbbe6b803abc3db8a6fdc3c641 Mon Sep 17 00:00:00 2001 From: Simon Hawkins Date: Mon, 7 Jan 2019 20:49:49 +0000 Subject: [PATCH 3/3] fix CI failures --- pandas/tests/io/msgpack/test_limits.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/tests/io/msgpack/test_limits.py b/pandas/tests/io/msgpack/test_limits.py index 0e4a67b6e644f..dd8dc8da607a4 100644 --- a/pandas/tests/io/msgpack/test_limits.py +++ b/pandas/tests/io/msgpack/test_limits.py @@ -12,8 +12,8 @@ class TestLimits(object): def test_integer(self): x = -(2 ** 63) assert unpackb(packb(x)) == x - msg = (r"(int too big to convert|Python int too large" - " to convert to C long)") + msg = (r"((long |Python )?(int )?too (big|large) to convert" + r"( to C (unsigned )?long))?") with pytest.raises((OverflowError, ValueError), match=msg): packb(x - 1) x = 2 ** 64 - 1