From f6f3b05a7e362170272fe02a725d4a99e9390608 Mon Sep 17 00:00:00 2001 From: Brock Date: Thu, 11 Nov 2021 10:14:17 -0800 Subject: [PATCH] TST: parametrize arithmetic tests --- pandas/tests/arithmetic/common.py | 33 +++- pandas/tests/arithmetic/test_datetime64.py | 104 +++------- pandas/tests/arithmetic/test_numeric.py | 21 +-- pandas/tests/arithmetic/test_object.py | 28 +-- pandas/tests/arithmetic/test_period.py | 198 +++++++++----------- pandas/tests/arithmetic/test_timedelta64.py | 18 +- 6 files changed, 175 insertions(+), 227 deletions(-) diff --git a/pandas/tests/arithmetic/common.py b/pandas/tests/arithmetic/common.py index af70cdfe538bb..f3173e8f0eb57 100644 --- a/pandas/tests/arithmetic/common.py +++ b/pandas/tests/arithmetic/common.py @@ -11,7 +11,26 @@ array, ) import pandas._testing as tm -from pandas.core.arrays import PandasArray +from pandas.core.arrays import ( + BooleanArray, + PandasArray, +) + + +def assert_cannot_add(left, right, msg="cannot add"): + """ + Helper to assert that left and right cannot be added. + + Parameters + ---------- + left : object + right : object + msg : str, default "cannot add" + """ + with pytest.raises(TypeError, match=msg): + left + right + with pytest.raises(TypeError, match=msg): + right + left def assert_invalid_addsub_type(left, right, msg=None): @@ -79,21 +98,29 @@ def xbox2(x): # just exclude PandasArray[bool] if isinstance(x, PandasArray): return x._ndarray + if isinstance(x, BooleanArray): + # NB: we are assuming no pd.NAs for now + return x.astype(bool) return x + # rev_box: box to use for reversed comparisons + rev_box = xbox + if isinstance(right, Index) and isinstance(left, Series): + rev_box = np.array + result = xbox2(left == right) expected = xbox(np.zeros(result.shape, dtype=np.bool_)) tm.assert_equal(result, expected) result = xbox2(right == left) - tm.assert_equal(result, expected) + tm.assert_equal(result, rev_box(expected)) result = xbox2(left != right) tm.assert_equal(result, ~expected) result = xbox2(right != left) - tm.assert_equal(result, ~expected) + tm.assert_equal(result, rev_box(~expected)) msg = "|".join( [ diff --git a/pandas/tests/arithmetic/test_datetime64.py b/pandas/tests/arithmetic/test_datetime64.py index bff461dbc7038..87bbdfb3c808f 100644 --- a/pandas/tests/arithmetic/test_datetime64.py +++ b/pandas/tests/arithmetic/test_datetime64.py @@ -41,6 +41,7 @@ ) from pandas.core.ops import roperator from pandas.tests.arithmetic.common import ( + assert_cannot_add, assert_invalid_addsub_type, assert_invalid_comparison, get_upcast_box, @@ -99,6 +100,7 @@ def test_dt64arr_cmp_scalar_invalid(self, other, tz_naive_fixture, box_with_arra @pytest.mark.parametrize( "other", [ + # GH#4968 invalid date/int comparisons list(range(10)), np.arange(10), np.arange(10).astype(np.float32), @@ -111,13 +113,14 @@ def test_dt64arr_cmp_scalar_invalid(self, other, tz_naive_fixture, box_with_arra pd.period_range("1971-01-01", freq="D", periods=10).astype(object), ], ) - def test_dt64arr_cmp_arraylike_invalid(self, other, tz_naive_fixture): - # We don't parametrize this over box_with_array because listlike - # other plays poorly with assert_invalid_comparison reversed checks + def test_dt64arr_cmp_arraylike_invalid( + self, other, tz_naive_fixture, box_with_array + ): tz = tz_naive_fixture dta = date_range("1970-01-01", freq="ns", periods=10, tz=tz)._data - assert_invalid_comparison(dta, other, tm.to_array) + obj = tm.box_expected(dta, box_with_array) + assert_invalid_comparison(obj, other, box_with_array) def test_dt64arr_cmp_mixed_invalid(self, tz_naive_fixture): tz = tz_naive_fixture @@ -215,18 +218,6 @@ def test_nat_comparisons( tm.assert_series_equal(result, expected) - def test_comparison_invalid(self, tz_naive_fixture, box_with_array): - # GH#4968 - # invalid date/int comparisons - tz = tz_naive_fixture - ser = Series(range(5)) - ser2 = Series(date_range("20010101", periods=5, tz=tz)) - - ser = tm.box_expected(ser, box_with_array) - ser2 = tm.box_expected(ser2, box_with_array) - - assert_invalid_comparison(ser, ser2, box_with_array) - @pytest.mark.parametrize( "data", [ @@ -315,8 +306,8 @@ def test_timestamp_compare_series(self, left, right): tm.assert_series_equal(result, expected) # Compare to NaT with series containing NaT - expected = left_f(s_nat, Timestamp("nat")) - result = right_f(Timestamp("nat"), s_nat) + expected = left_f(s_nat, NaT) + result = right_f(NaT, s_nat) tm.assert_series_equal(result, expected) def test_dt64arr_timestamp_equality(self, box_with_array): @@ -832,17 +823,6 @@ def test_dt64arr_add_timedeltalike_scalar( result = rng + two_hours tm.assert_equal(result, expected) - def test_dt64arr_iadd_timedeltalike_scalar( - self, tz_naive_fixture, two_hours, box_with_array - ): - tz = tz_naive_fixture - - rng = date_range("2000-01-01", "2000-02-01", tz=tz) - expected = date_range("2000-01-01 02:00", "2000-02-01 02:00", tz=tz) - - rng = tm.box_expected(rng, box_with_array) - expected = tm.box_expected(expected, box_with_array) - rng += two_hours tm.assert_equal(rng, expected) @@ -860,17 +840,6 @@ def test_dt64arr_sub_timedeltalike_scalar( result = rng - two_hours tm.assert_equal(result, expected) - def test_dt64arr_isub_timedeltalike_scalar( - self, tz_naive_fixture, two_hours, box_with_array - ): - tz = tz_naive_fixture - - rng = date_range("2000-01-01", "2000-02-01", tz=tz) - expected = date_range("1999-12-31 22:00", "2000-01-31 22:00", tz=tz) - - rng = tm.box_expected(rng, box_with_array) - expected = tm.box_expected(expected, box_with_array) - rng -= two_hours tm.assert_equal(rng, expected) @@ -1071,21 +1040,14 @@ def test_dt64arr_add_dt64ndarray_raises(self, tz_naive_fixture, box_with_array): dt64vals = dti.values dtarr = tm.box_expected(dti, box_with_array) - msg = "cannot add" - with pytest.raises(TypeError, match=msg): - dtarr + dt64vals - with pytest.raises(TypeError, match=msg): - dt64vals + dtarr + assert_cannot_add(dtarr, dt64vals) def test_dt64arr_add_timestamp_raises(self, box_with_array): # GH#22163 ensure DataFrame doesn't cast Timestamp to i8 idx = DatetimeIndex(["2011-01-01", "2011-01-02"]) + ts = idx[0] idx = tm.box_expected(idx, box_with_array) - msg = "cannot add" - with pytest.raises(TypeError, match=msg): - idx + Timestamp("2011-01-01") - with pytest.raises(TypeError, match=msg): - Timestamp("2011-01-01") + idx + assert_cannot_add(idx, ts) # ------------------------------------------------------------- # Other Invalid Addition/Subtraction @@ -1267,13 +1229,12 @@ def test_dti_add_tick_tzaware(self, tz_aware_fixture, box_with_array): dates = tm.box_expected(dates, box_with_array) expected = tm.box_expected(expected, box_with_array) - # TODO: parametrize over the scalar being added? radd? sub? - offset = dates + pd.offsets.Hour(5) - tm.assert_equal(offset, expected) - offset = dates + np.timedelta64(5, "h") - tm.assert_equal(offset, expected) - offset = dates + timedelta(hours=5) - tm.assert_equal(offset, expected) + # TODO: sub? + for scalar in [pd.offsets.Hour(5), np.timedelta64(5, "h"), timedelta(hours=5)]: + offset = dates + scalar + tm.assert_equal(offset, expected) + offset = scalar + dates + tm.assert_equal(offset, expected) # ------------------------------------------------------------- # RelativeDelta DateOffsets @@ -1941,8 +1902,7 @@ def test_dt64_mul_div_numeric_invalid(self, one, dt64_series): one / dt64_series # TODO: parametrize over box - @pytest.mark.parametrize("op", ["__add__", "__radd__", "__sub__", "__rsub__"]) - def test_dt64_series_add_intlike(self, tz_naive_fixture, op): + def test_dt64_series_add_intlike(self, tz_naive_fixture): # GH#19123 tz = tz_naive_fixture dti = DatetimeIndex(["2016-01-02", "2016-02-03", "NaT"], tz=tz) @@ -1950,21 +1910,16 @@ def test_dt64_series_add_intlike(self, tz_naive_fixture, op): other = Series([20, 30, 40], dtype="uint8") - method = getattr(ser, op) msg = "|".join( [ "Addition/subtraction of integers and integer-arrays", "cannot subtract .* from ndarray", ] ) - with pytest.raises(TypeError, match=msg): - method(1) - with pytest.raises(TypeError, match=msg): - method(other) - with pytest.raises(TypeError, match=msg): - method(np.array(other)) - with pytest.raises(TypeError, match=msg): - method(pd.Index(other)) + assert_invalid_addsub_type(ser, 1, msg) + assert_invalid_addsub_type(ser, other, msg) + assert_invalid_addsub_type(ser, np.array(other), msg) + assert_invalid_addsub_type(ser, pd.Index(other), msg) # ------------------------------------------------------------- # Timezone-Centric Tests @@ -2062,7 +2017,9 @@ def test_dti_add_intarray_tick(self, int_holder, freq): dti = date_range("2016-01-01", periods=2, freq=freq) other = int_holder([4, -1]) - msg = "Addition/subtraction of integers|cannot subtract DatetimeArray from" + msg = "|".join( + ["Addition/subtraction of integers", "cannot subtract DatetimeArray from"] + ) assert_invalid_addsub_type(dti, other, msg) @pytest.mark.parametrize("freq", ["W", "M", "MS", "Q"]) @@ -2072,7 +2029,9 @@ def test_dti_add_intarray_non_tick(self, int_holder, freq): dti = date_range("2016-01-01", periods=2, freq=freq) other = int_holder([4, -1]) - msg = "Addition/subtraction of integers|cannot subtract DatetimeArray from" + msg = "|".join( + ["Addition/subtraction of integers", "cannot subtract DatetimeArray from"] + ) assert_invalid_addsub_type(dti, other, msg) @pytest.mark.parametrize("int_holder", [np.array, pd.Index]) @@ -2222,10 +2181,7 @@ def test_add_datetimelike_and_dtarr(self, box_with_array, addend, tz): dtarr = tm.box_expected(dti, box_with_array) msg = "cannot add DatetimeArray and" - with pytest.raises(TypeError, match=msg): - dtarr + addend - with pytest.raises(TypeError, match=msg): - addend + dtarr + assert_cannot_add(dtarr, addend, msg) # ------------------------------------------------------------- diff --git a/pandas/tests/arithmetic/test_numeric.py b/pandas/tests/arithmetic/test_numeric.py index 9932adccdbaf2..3bf5fdb257c2a 100644 --- a/pandas/tests/arithmetic/test_numeric.py +++ b/pandas/tests/arithmetic/test_numeric.py @@ -29,6 +29,7 @@ UInt64Index, ) from pandas.core.computation import expressions as expr +from pandas.tests.arithmetic.common import assert_invalid_comparison @pytest.fixture(params=[Index, Series, tm.to_array]) @@ -84,25 +85,13 @@ def test_operator_series_comparison_zerorank(self): expected = 0.0 > Series([1, 2, 3]) tm.assert_series_equal(result, expected) - def test_df_numeric_cmp_dt64_raises(self): + def test_df_numeric_cmp_dt64_raises(self, box_with_array): # GH#8932, GH#22163 ts = pd.Timestamp.now() - df = pd.DataFrame({"x": range(5)}) + obj = np.array(range(5)) + obj = tm.box_expected(obj, box_with_array) - msg = ( - "'[<>]' not supported between instances of 'numpy.ndarray' and 'Timestamp'" - ) - with pytest.raises(TypeError, match=msg): - df > ts - with pytest.raises(TypeError, match=msg): - df < ts - with pytest.raises(TypeError, match=msg): - ts < df - with pytest.raises(TypeError, match=msg): - ts > df - - assert not (df == ts).any().any() - assert (df != ts).all().all() + assert_invalid_comparison(obj, ts, box_with_array) def test_compare_invalid(self): # GH#8058 diff --git a/pandas/tests/arithmetic/test_object.py b/pandas/tests/arithmetic/test_object.py index 9a586fd553428..3069868ebb677 100644 --- a/pandas/tests/arithmetic/test_object.py +++ b/pandas/tests/arithmetic/test_object.py @@ -21,17 +21,15 @@ class TestObjectComparisons: - def test_comparison_object_numeric_nas(self): + def test_comparison_object_numeric_nas(self, comparison_op): ser = Series(np.random.randn(10), dtype=object) shifted = ser.shift(2) - ops = ["lt", "le", "gt", "ge", "eq", "ne"] - for op in ops: - func = getattr(operator, op) + func = comparison_op - result = func(ser, shifted) - expected = func(ser.astype(float), shifted.astype(float)) - tm.assert_series_equal(result, expected) + result = func(ser, shifted) + expected = func(ser.astype(float), shifted.astype(float)) + tm.assert_series_equal(result, expected) def test_object_comparisons(self): ser = Series(["a", "b", np.nan, "c", "a"]) @@ -141,11 +139,13 @@ def test_objarr_radd_str_invalid(self, dtype, data, box_with_array): ser = Series(data, dtype=dtype) ser = tm.box_expected(ser, box_with_array) - msg = ( - "can only concatenate str|" - "did not contain a loop with signature matching types|" - "unsupported operand type|" - "must be str" + msg = "|".join( + [ + "can only concatenate str", + "did not contain a loop with signature matching types", + "unsupported operand type", + "must be str", + ] ) with pytest.raises(TypeError, match=msg): "foo_" + ser @@ -159,7 +159,9 @@ def test_objarr_add_invalid(self, op, box_with_array): obj_ser.name = "objects" obj_ser = tm.box_expected(obj_ser, box) - msg = "can only concatenate str|unsupported operand type|must be str" + msg = "|".join( + ["can only concatenate str", "unsupported operand type", "must be str"] + ) with pytest.raises(Exception, match=msg): op(obj_ser, 1) with pytest.raises(Exception, match=msg): diff --git a/pandas/tests/arithmetic/test_period.py b/pandas/tests/arithmetic/test_period.py index f8814a33292ec..f4404a3483e6f 100644 --- a/pandas/tests/arithmetic/test_period.py +++ b/pandas/tests/arithmetic/test_period.py @@ -26,6 +26,7 @@ from pandas.core import ops from pandas.core.arrays import TimedeltaArray from pandas.tests.arithmetic.common import ( + assert_invalid_addsub_type, assert_invalid_comparison, get_upcast_box, ) @@ -39,6 +40,20 @@ class TestPeriodArrayLikeComparisons: # DataFrame/Series/PeriodIndex/PeriodArray. Ideally all comparison # tests will eventually end up here. + @pytest.mark.parametrize("other", ["2017", Period("2017", freq="D")]) + def test_eq_scalar(self, other, box_with_array): + + idx = PeriodIndex(["2017", "2017", "2018"], freq="D") + idx = tm.box_expected(idx, box_with_array) + xbox = get_upcast_box(idx, other, True) + + expected = np.array([True, True, False]) + expected = tm.box_expected(expected, xbox) + + result = idx == other + + tm.assert_equal(result, expected) + def test_compare_zerodim(self, box_with_array): # GH#26689 make sure we unbox zero-dimensional arrays @@ -54,9 +69,20 @@ def test_compare_zerodim(self, box_with_array): tm.assert_equal(result, expected) @pytest.mark.parametrize( - "scalar", ["foo", Timestamp.now(), Timedelta(days=4), 9, 9.5] + "scalar", + [ + "foo", + Timestamp.now(), + Timedelta(days=4), + 9, + 9.5, + 2000, # specifically don't consider 2000 to match Period("2000", "D") + False, + None, + ], ) def test_compare_invalid_scalar(self, box_with_array, scalar): + # GH#28980 # comparison with scalar that cannot be interpreted as a Period pi = period_range("2000", periods=4) parr = tm.box_expected(pi, box_with_array) @@ -70,6 +96,11 @@ def test_compare_invalid_scalar(self, box_with_array, scalar): np.arange(4), np.arange(4).astype(np.float64), list(range(4)), + # match Period semantics by not treating integers as Periods + [2000, 2001, 2002, 2003], + np.arange(2000, 2004), + np.arange(2000, 2004).astype(object), + pd.Index([2000, 2001, 2002, 2003]), ], ) def test_compare_invalid_listlike(self, box_with_array, other): @@ -138,68 +169,27 @@ def test_compare_object_dtype(self, box_with_array, other_box): class TestPeriodIndexComparisons: # TODO: parameterize over boxes - @pytest.mark.parametrize("other", ["2017", Period("2017", freq="D")]) - def test_eq(self, other): - idx = PeriodIndex(["2017", "2017", "2018"], freq="D") - expected = np.array([True, True, False]) - result = idx == other - - tm.assert_numpy_array_equal(result, expected) - - @pytest.mark.parametrize( - "other", - [ - 2017, - [2017, 2017, 2017], - np.array([2017, 2017, 2017]), - np.array([2017, 2017, 2017], dtype=object), - pd.Index([2017, 2017, 2017]), - ], - ) - def test_eq_integer_disallowed(self, other): - # match Period semantics by not treating integers as Periods - - idx = PeriodIndex(["2017", "2017", "2018"], freq="D") - expected = np.array([False, False, False]) - result = idx == other - - tm.assert_numpy_array_equal(result, expected) - msg = "|".join( - [ - "not supported between instances of 'Period' and 'int'", - r"Invalid comparison between dtype=period\[D\] and ", - ] - ) - with pytest.raises(TypeError, match=msg): - idx < other - with pytest.raises(TypeError, match=msg): - idx > other - with pytest.raises(TypeError, match=msg): - idx <= other - with pytest.raises(TypeError, match=msg): - idx >= other - def test_pi_cmp_period(self): idx = period_range("2007-01", periods=20, freq="M") + per = idx[10] - result = idx < idx[10] + result = idx < per exp = idx.values < idx.values[10] tm.assert_numpy_array_equal(result, exp) # Tests Period.__richcmp__ against ndarray[object, ndim=2] - result = idx.values.reshape(10, 2) < idx[10] + result = idx.values.reshape(10, 2) < per tm.assert_numpy_array_equal(result, exp.reshape(10, 2)) # Tests Period.__richcmp__ against ndarray[object, ndim=0] - result = idx < np.array(idx[10]) + result = idx < np.array(per) tm.assert_numpy_array_equal(result, exp) # TODO: moved from test_datetime64; de-duplicate with version below def test_parr_cmp_period_scalar2(self, box_with_array): pi = period_range("2000-01-01", periods=10, freq="D") - val = Period("2000-01-04", freq="D") - + val = pi[3] expected = [x > val for x in pi] ser = tm.box_expected(pi, box_with_array) @@ -326,23 +316,24 @@ def test_parr_cmp_pi_mismatched_freq(self, freq, box_with_array): @pytest.mark.parametrize("freq", ["M", "2M", "3M"]) def test_pi_cmp_nat(self, freq): idx1 = PeriodIndex(["2011-01", "2011-02", "NaT", "2011-05"], freq=freq) + per = idx1[1] - result = idx1 > Period("2011-02", freq=freq) + result = idx1 > per exp = np.array([False, False, False, True]) tm.assert_numpy_array_equal(result, exp) - result = Period("2011-02", freq=freq) < idx1 + result = per < idx1 tm.assert_numpy_array_equal(result, exp) - result = idx1 == Period("NaT", freq=freq) + result = idx1 == pd.NaT exp = np.array([False, False, False, False]) tm.assert_numpy_array_equal(result, exp) - result = Period("NaT", freq=freq) == idx1 + result = pd.NaT == idx1 tm.assert_numpy_array_equal(result, exp) - result = idx1 != Period("NaT", freq=freq) + result = idx1 != pd.NaT exp = np.array([True, True, True, True]) tm.assert_numpy_array_equal(result, exp) - result = Period("NaT", freq=freq) != idx1 + result = pd.NaT != idx1 tm.assert_numpy_array_equal(result, exp) idx2 = PeriodIndex(["2011-02", "2011-01", "2011-04", "NaT"], freq=freq) @@ -475,28 +466,29 @@ def test_pi_comp_period(self): idx = PeriodIndex( ["2011-01", "2011-02", "2011-03", "2011-04"], freq="M", name="idx" ) + per = idx[2] - f = lambda x: x == Period("2011-03", freq="M") + f = lambda x: x == per exp = np.array([False, False, True, False], dtype=np.bool_) self._check(idx, f, exp) - f = lambda x: Period("2011-03", freq="M") == x + f = lambda x: per == x self._check(idx, f, exp) - f = lambda x: x != Period("2011-03", freq="M") + f = lambda x: x != per exp = np.array([True, True, False, True], dtype=np.bool_) self._check(idx, f, exp) - f = lambda x: Period("2011-03", freq="M") != x + f = lambda x: per != x self._check(idx, f, exp) - f = lambda x: Period("2011-03", freq="M") >= x + f = lambda x: per >= x exp = np.array([True, True, True, False], dtype=np.bool_) self._check(idx, f, exp) - f = lambda x: x > Period("2011-03", freq="M") + f = lambda x: x > per exp = np.array([False, False, False, True], dtype=np.bool_) self._check(idx, f, exp) - f = lambda x: Period("2011-03", freq="M") >= x + f = lambda x: per >= x exp = np.array([True, True, True, False], dtype=np.bool_) self._check(idx, f, exp) @@ -504,11 +496,12 @@ def test_pi_comp_period_nat(self): idx = PeriodIndex( ["2011-01", "NaT", "2011-03", "2011-04"], freq="M", name="idx" ) + per = idx[2] - f = lambda x: x == Period("2011-03", freq="M") + f = lambda x: x == per exp = np.array([False, False, True, False], dtype=np.bool_) self._check(idx, f, exp) - f = lambda x: Period("2011-03", freq="M") == x + f = lambda x: per == x self._check(idx, f, exp) f = lambda x: x == pd.NaT @@ -517,10 +510,10 @@ def test_pi_comp_period_nat(self): f = lambda x: pd.NaT == x self._check(idx, f, exp) - f = lambda x: x != Period("2011-03", freq="M") + f = lambda x: x != per exp = np.array([True, True, False, True], dtype=np.bool_) self._check(idx, f, exp) - f = lambda x: Period("2011-03", freq="M") != x + f = lambda x: per != x self._check(idx, f, exp) f = lambda x: x != pd.NaT @@ -529,11 +522,11 @@ def test_pi_comp_period_nat(self): f = lambda x: pd.NaT != x self._check(idx, f, exp) - f = lambda x: Period("2011-03", freq="M") >= x + f = lambda x: per >= x exp = np.array([True, False, True, False], dtype=np.bool_) self._check(idx, f, exp) - f = lambda x: x < Period("2011-03", freq="M") + f = lambda x: x < per exp = np.array([True, False, False, False], dtype=np.bool_) self._check(idx, f, exp) @@ -696,20 +689,6 @@ def test_sub_n_gt_1_offsets(self, offset, kwd_name, n): # ------------------------------------------------------------- # Invalid Operations - @pytest.mark.parametrize("other", [3.14, np.array([2.0, 3.0])]) - @pytest.mark.parametrize("op", [operator.add, ops.radd, operator.sub, ops.rsub]) - def test_parr_add_sub_float_raises(self, op, other, box_with_array): - dti = pd.DatetimeIndex(["2011-01-01", "2011-01-02"], freq="D") - pi = dti.to_period("D") - pi = tm.box_expected(pi, box_with_array) - msg = ( - r"unsupported operand type\(s\) for [+-]: .* and .*|" - "Concatenation operation is not implemented for NumPy arrays" - ) - - with pytest.raises(TypeError, match=msg): - op(pi, other) - @pytest.mark.parametrize( "other", [ @@ -723,6 +702,8 @@ def test_parr_add_sub_float_raises(self, op, other, box_with_array): pd.date_range("2016-01-01", periods=3, freq="S")._data, pd.date_range("2016-01-01", periods=3, tz="Asia/Tokyo")._data, # Miscellaneous invalid types + 3.14, + np.array([2.0, 3.0, 4.0]), ], ) def test_parr_add_sub_invalid(self, other, box_with_array): @@ -730,11 +711,15 @@ def test_parr_add_sub_invalid(self, other, box_with_array): rng = period_range("1/1/2000", freq="D", periods=3) rng = tm.box_expected(rng, box_with_array) - msg = ( - r"(:?cannot add PeriodArray and .*)" - r"|(:?cannot subtract .* from (:?a\s)?.*)" - r"|(:?unsupported operand type\(s\) for \+: .* and .*)" + msg = "|".join( + [ + r"(:?cannot add PeriodArray and .*)", + r"(:?cannot subtract .* from (:?a\s)?.*)", + r"(:?unsupported operand type\(s\) for \+: .* and .*)", + r"unsupported operand type\(s\) for [+-]: .* and .*", + ] ) + assert_invalid_addsub_type(rng, other, msg) with pytest.raises(TypeError, match=msg): rng + other with pytest.raises(TypeError, match=msg): @@ -1034,9 +1019,11 @@ def test_pi_add_timedeltalike_minute_gt1(self, three_days): result = rng - other tm.assert_index_equal(result, expected) - msg = ( - r"(:?bad operand type for unary -: 'PeriodArray')" - r"|(:?cannot subtract PeriodArray from timedelta64\[[hD]\])" + msg = "|".join( + [ + r"(:?bad operand type for unary -: 'PeriodArray')", + r"(:?cannot subtract PeriodArray from timedelta64\[[hD]\])", + ] ) with pytest.raises(TypeError, match=msg): other - rng @@ -1261,7 +1248,7 @@ def test_parr_add_sub_object_array(self): class TestPeriodSeriesArithmetic: - def test_ops_series_timedelta(self): + def test_parr_add_timedeltalike_scalar(self, three_days, box_with_array): # GH#13043 ser = Series( [Period("2015-01-01", freq="D"), Period("2015-01-02", freq="D")], @@ -1270,21 +1257,18 @@ def test_ops_series_timedelta(self): assert ser.dtype == "Period[D]" expected = Series( - [Period("2015-01-02", freq="D"), Period("2015-01-03", freq="D")], + [Period("2015-01-04", freq="D"), Period("2015-01-05", freq="D")], name="xxx", ) - result = ser + Timedelta("1 days") - tm.assert_series_equal(result, expected) - - result = Timedelta("1 days") + ser - tm.assert_series_equal(result, expected) + obj = tm.box_expected(ser, box_with_array) + expected = tm.box_expected(expected, box_with_array) - result = ser + pd.tseries.offsets.Day() - tm.assert_series_equal(result, expected) + result = obj + three_days + tm.assert_equal(result, expected) - result = pd.tseries.offsets.Day() + ser - tm.assert_series_equal(result, expected) + result = three_days + obj + tm.assert_equal(result, expected) def test_ops_series_period(self): # GH#13043 @@ -1368,9 +1352,13 @@ def test_parr_ops_errors(self, ng, func, box_with_array): ["2011-01", "2011-02", "2011-03", "2011-04"], freq="M", name="idx" ) obj = tm.box_expected(idx, box_with_array) - msg = ( - r"unsupported operand type\(s\)|can only concatenate|" - r"must be str|object to str implicitly" + msg = "|".join( + [ + r"unsupported operand type\(s\)", + "can only concatenate", + r"must be str", + "object to str implicitly", + ] ) with pytest.raises(TypeError, match=msg): @@ -1544,11 +1532,3 @@ def test_pi_sub_period_nat(self): exp = TimedeltaIndex([np.nan, np.nan, np.nan, np.nan], name="idx") tm.assert_index_equal(idx - Period("NaT", freq="M"), exp) tm.assert_index_equal(Period("NaT", freq="M") - idx, exp) - - @pytest.mark.parametrize("scalars", ["a", False, 1, 1.0, None]) - def test_comparison_operations(self, scalars): - # GH 28980 - expected = Series([False, False]) - s = Series([Period("2019"), Period("2020")], dtype="period[A-DEC]") - result = s == scalars - tm.assert_series_equal(result, expected) diff --git a/pandas/tests/arithmetic/test_timedelta64.py b/pandas/tests/arithmetic/test_timedelta64.py index 86980ad42766e..8078e8c90a2bf 100644 --- a/pandas/tests/arithmetic/test_timedelta64.py +++ b/pandas/tests/arithmetic/test_timedelta64.py @@ -84,11 +84,6 @@ def test_compare_timedelta64_zerodim(self, box_with_array): expected = tm.box_expected(expected, xbox) tm.assert_equal(res, expected) - msg = "Invalid comparison between dtype" - with pytest.raises(TypeError, match=msg): - # zero-dim of wrong dtype should still raise - tdi >= np.array(4) - @pytest.mark.parametrize( "td_scalar", [ @@ -120,6 +115,7 @@ def test_compare_timedeltalike_scalar(self, box_with_array, td_scalar): Timestamp.now().to_datetime64(), Timestamp.now().to_pydatetime(), Timestamp.now().date(), + np.array(4), # zero-dim mismatched dtype ], ) def test_td64_comparisons_invalid(self, box_with_array, invalid): @@ -146,17 +142,18 @@ def test_td64_comparisons_invalid(self, box_with_array, invalid): pd.period_range("1971-01-01", freq="D", periods=10).astype(object), ], ) - def test_td64arr_cmp_arraylike_invalid(self, other): + def test_td64arr_cmp_arraylike_invalid(self, other, box_with_array): # We don't parametrize this over box_with_array because listlike # other plays poorly with assert_invalid_comparison reversed checks rng = timedelta_range("1 days", periods=10)._data - assert_invalid_comparison(rng, other, tm.to_array) + rng = tm.box_expected(rng, box_with_array) + assert_invalid_comparison(rng, other, box_with_array) def test_td64arr_cmp_mixed_invalid(self): rng = timedelta_range("1 days", periods=5)._data - other = np.array([0, 1, 2, rng[3], Timestamp.now()]) + result = rng == other expected = np.array([False, False, False, True, False]) tm.assert_numpy_array_equal(result, expected) @@ -1623,10 +1620,7 @@ def test_td64arr_div_td64_scalar(self, m, unit, box_with_array): box = box_with_array xbox = np.ndarray if box is pd.array else box - startdate = Series(pd.date_range("2013-01-01", "2013-01-03")) - enddate = Series(pd.date_range("2013-03-01", "2013-03-03")) - - ser = enddate - startdate + ser = Series([Timedelta(days=59)] * 3) ser[2] = np.nan flat = ser ser = tm.box_expected(ser, box)