From 30a503b0ac5f7273626d52da178032e67d6cc4a5 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Fri, 20 Mar 2020 14:01:09 -0700 Subject: [PATCH 1/4] REF: re-write Period comparison tests; avoid bare pytest.raises --- pandas/tests/scalar/period/test_period.py | 144 +++++++++++----------- 1 file changed, 70 insertions(+), 74 deletions(-) diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py index 3846274dacd75..41a86748016d2 100644 --- a/pandas/tests/scalar/period/test_period.py +++ b/pandas/tests/scalar/period/test_period.py @@ -930,87 +930,83 @@ def test_get_period_field_array_raises_on_out_of_range(self): libperiod.get_period_field_arr(-1, np.empty(1), 0) -class TestComparisons: - def setup_method(self, method): - self.january1 = Period("2000-01", "M") - self.january2 = Period("2000-01", "M") - self.february = Period("2000-02", "M") - self.march = Period("2000-03", "M") - self.day = Period("2012-01-01", "D") - - def test_equal(self): - assert self.january1 == self.january2 - - def test_equal_Raises_Value(self): - with pytest.raises(IncompatibleFrequency): - self.january1 == self.day - - def test_notEqual(self): - assert self.january1 != 1 - assert self.january1 != self.february - - def test_greater(self): - assert self.february > self.january1 - - def test_greater_Raises_Value(self): - with pytest.raises(IncompatibleFrequency): - self.january1 > self.day - - def test_greater_Raises_Type(self): - with pytest.raises(TypeError): - self.january1 > 1 - - def test_greaterEqual(self): - assert self.january1 >= self.january2 - - def test_greaterEqual_Raises_Value(self): - with pytest.raises(IncompatibleFrequency): - self.january1 >= self.day - - with pytest.raises(TypeError): - print(self.january1 >= 1) - - def test_smallerEqual(self): - assert self.january1 <= self.january2 - - def test_smallerEqual_Raises_Value(self): - with pytest.raises(IncompatibleFrequency): - self.january1 <= self.day - - def test_smallerEqual_Raises_Type(self): - with pytest.raises(TypeError): - self.january1 <= 1 - - def test_smaller(self): - assert self.january1 < self.february - - def test_smaller_Raises_Value(self): - with pytest.raises(IncompatibleFrequency): - self.january1 < self.day - - def test_smaller_Raises_Type(self): - with pytest.raises(TypeError): - self.january1 < 1 - - def test_sort(self): - periods = [self.march, self.january1, self.february] - correctPeriods = [self.january1, self.february, self.march] +class TestPeriodComparisons: + def test_comparison_same_period_different_object(self): + # Separate Period objects for the same period + left = Period("2000-01", "M") + right = Period("2000-01", "M") + + assert left == right + assert left >= right + assert left <= right + assert not left < right + assert not left > right + + def test_comparison_same_freq(self): + jan = Period("2000-01", "M") + feb = Period("2000-02", "M") + + assert not jan == feb + assert jan != feb + assert jan < feb + assert jan <= feb + assert not jan > feb + assert not jan >= feb + + def test_comparison_mismatched_freq(self): + jan = Period("2000-01", "M") + day = Period("2012-01-01", "D") + + msg = r"Input has different freq=D from Period\(freq=M\)" + with pytest.raises(IncompatibleFrequency, match=msg): + jan == day + with pytest.raises(IncompatibleFrequency, match=msg): + jan != day + with pytest.raises(IncompatibleFrequency, match=msg): + jan < day + with pytest.raises(IncompatibleFrequency, match=msg): + jan <= day + with pytest.raises(IncompatibleFrequency, match=msg): + jan > day + with pytest.raises(IncompatibleFrequency, match=msg): + jan >= day + + def test_comparison_invalid_type(self): + jan = Period("2000-01", "M") + + assert not jan == 1 + assert jan != 1 + + msg = "Cannot compare type Period with type int" + for left, right in [(jan, 1), (1, jan)]: + + with pytest.raises(TypeError, match=msg): + left > right + with pytest.raises(TypeError, match=msg): + left >= right + with pytest.raises(TypeError, match=msg): + left < right + with pytest.raises(TypeError, match=msg): + left <= right + + def test_sort_periods(self): + jan = Period("2000-01", "M") + feb = Period("2000-02", "M") + mar = Period("2000-03", "M") + periods = [mar, jan, feb] + correctPeriods = [jan, feb, mar] assert sorted(periods) == correctPeriods - def test_period_nat_comp(self): - p_nat = Period("NaT", freq="D") + def test_period_cmp_nat(self): p = Period("2011-01-01", freq="D") - nat = Timestamp("NaT") t = Timestamp("2011-01-01") # confirm Period('NaT') work identical with Timestamp('NaT') for left, right in [ - (p_nat, p), - (p, p_nat), - (p_nat, p_nat), - (nat, t), - (t, nat), - (nat, nat), + (NaT, p), + (p, NaT), + (NaT, t), + (t, NaT), ]: assert not left < right assert not left > right From 7d854c76b44a1bb5975382f46f98188469a887ae Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Fri, 20 Mar 2020 14:13:58 -0700 Subject: [PATCH 2/4] CLN: de-duplicate some Period tests --- pandas/tests/scalar/period/test_period.py | 295 +++++++++------------- 1 file changed, 122 insertions(+), 173 deletions(-) diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py index 41a86748016d2..63a830fab88dc 100644 --- a/pandas/tests/scalar/period/test_period.py +++ b/pandas/tests/scalar/period/test_period.py @@ -347,10 +347,18 @@ def test_period_from_ordinal(self): assert p == res assert isinstance(res, Period) - def test_period_cons_nat(self): - p = Period("NaT", freq="M") - assert p is NaT + @pytest.mark.parametrize("freq", ["A", "M", "D", "H"]) + def test_construct_from_nat_string_and_freq(self, freq): + per = Period("NaT", freq=freq) + assert per is NaT + + per = Period("NaT", freq="2" + freq) + assert per is NaT + per = Period("NaT", freq="3" + freq) + assert per is NaT + + def test_period_cons_nat(self): p = Period("nat", freq="W-SUN") assert p is NaT @@ -1039,13 +1047,6 @@ def test_add_sub_nat(self): assert p - NaT is NaT assert NaT - p is NaT - p = Period("NaT", freq="M") - assert p is NaT - assert p + NaT is NaT - assert NaT + p is NaT - assert p - NaT is NaT - assert NaT - p is NaT - def test_add_invalid(self): # GH#4731 per1 = Period(freq="D", year=2008, month=1, day=1) @@ -1277,90 +1278,65 @@ def test_add_offset(self): with pytest.raises(IncompatibleFrequency): o + p + # TODO: this is really testing NaT and offsets, not Period, also + # the loops in here are highly duplicative def test_add_offset_nat(self): # freq is DateOffset - for freq in ["A", "2A", "3A"]: - p = Period("NaT", freq=freq) - assert p is NaT - for o in [offsets.YearEnd(2)]: - assert p + o is NaT - assert o + p is NaT - - for o in [ - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(365, "D"), - timedelta(365), - ]: - assert p + o is NaT - assert o + p is NaT - - for freq in ["M", "2M", "3M"]: - p = Period("NaT", freq=freq) - assert p is NaT - for o in [offsets.MonthEnd(2), offsets.MonthEnd(12)]: - assert p + o is NaT - assert o + p is NaT - - for o in [ - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(365, "D"), - timedelta(365), - ]: - assert p + o is NaT - assert o + p is NaT - - # freq is Tick - for freq in ["D", "2D", "3D"]: - p = Period("NaT", freq=freq) - assert p is NaT - for o in [ - offsets.Day(5), - offsets.Hour(24), - np.timedelta64(2, "D"), - np.timedelta64(3600 * 24, "s"), - timedelta(-2), - timedelta(hours=48), - ]: - assert p + o is NaT - assert o + p is NaT - for o in [ - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(4, "h"), - timedelta(hours=23), - ]: - assert p + o is NaT - assert o + p is NaT - - for freq in ["H", "2H", "3H"]: - p = Period("NaT", freq=freq) - assert p is NaT - for o in [ - offsets.Day(2), - offsets.Hour(3), - np.timedelta64(3, "h"), - np.timedelta64(3600, "s"), - timedelta(minutes=120), - timedelta(days=4, minutes=180), - ]: - assert p + o is NaT - assert o + p is NaT - - for o in [ - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(3200, "s"), - timedelta(hours=23, minutes=30), - ]: - assert p + o is NaT - assert o + p is NaT + for o in [ + offsets.YearEnd(2), + offsets.YearBegin(2), + offsets.MonthBegin(1), + offsets.Minute(), + np.timedelta64(365, "D"), + timedelta(365), + ]: + assert NaT + o is NaT + assert o + NaT is NaT + + for o in [ + offsets.MonthEnd(2), + offsets.MonthEnd(12), + offsets.YearBegin(2), + offsets.MonthBegin(1), + offsets.Minute(), + np.timedelta64(365, "D"), + timedelta(365), + ]: + assert NaT + o is NaT + assert o + NaT is NaT + + for o in [ + offsets.Day(5), + offsets.Hour(24), + np.timedelta64(2, "D"), + np.timedelta64(3600 * 24, "s"), + timedelta(-2), + timedelta(hours=48), + offsets.YearBegin(2), + offsets.MonthBegin(1), + offsets.Minute(), + np.timedelta64(4, "h"), + timedelta(hours=23), + ]: + assert NaT + o is NaT + assert o + NaT is NaT + + for o in [ + offsets.Day(2), + offsets.Hour(3), + np.timedelta64(3, "h"), + np.timedelta64(3600, "s"), + timedelta(minutes=120), + timedelta(days=4, minutes=180), + offsets.YearBegin(2), + offsets.MonthBegin(1), + offsets.Minute(), + np.timedelta64(3200, "s"), + timedelta(hours=23, minutes=30), + ]: + assert NaT + o is NaT + assert o + NaT is NaT def test_sub_offset(self): # freq is DateOffset @@ -1436,92 +1412,65 @@ def test_sub_offset(self): with pytest.raises(IncompatibleFrequency): p - o + # TODO: this is really testing NaT and offsets, not Period, also + # the loops in here are highly duplicative def test_sub_offset_nat(self): # freq is DateOffset - for freq in ["A", "2A", "3A"]: - p = Period("NaT", freq=freq) - assert p is NaT - for o in [offsets.YearEnd(2)]: - assert p - o is NaT - - for o in [ - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(365, "D"), - timedelta(365), - ]: - assert p - o is NaT - - for freq in ["M", "2M", "3M"]: - p = Period("NaT", freq=freq) - assert p is NaT - for o in [offsets.MonthEnd(2), offsets.MonthEnd(12)]: - assert p - o is NaT - - for o in [ - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(365, "D"), - timedelta(365), - ]: - assert p - o is NaT - - # freq is Tick - for freq in ["D", "2D", "3D"]: - p = Period("NaT", freq=freq) - assert p is NaT - for o in [ - offsets.Day(5), - offsets.Hour(24), - np.timedelta64(2, "D"), - np.timedelta64(3600 * 24, "s"), - timedelta(-2), - timedelta(hours=48), - ]: - assert p - o is NaT - - for o in [ - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(4, "h"), - timedelta(hours=23), - ]: - assert p - o is NaT - - for freq in ["H", "2H", "3H"]: - p = Period("NaT", freq=freq) - assert p is NaT - for o in [ - offsets.Day(2), - offsets.Hour(3), - np.timedelta64(3, "h"), - np.timedelta64(3600, "s"), - timedelta(minutes=120), - timedelta(days=4, minutes=180), - ]: - assert p - o is NaT - - for o in [ - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(3200, "s"), - timedelta(hours=23, minutes=30), - ]: - assert p - o is NaT + for o in [ + offsets.YearEnd(2), + offsets.YearBegin(2), + offsets.MonthBegin(1), + offsets.Minute(), + np.timedelta64(365, "D"), + timedelta(365), + ]: + assert NaT - o is NaT + + for o in [ + offsets.MonthEnd(2), + offsets.MonthEnd(12), + offsets.YearBegin(2), + offsets.MonthBegin(1), + offsets.Minute(), + np.timedelta64(365, "D"), + timedelta(365), + ]: + assert NaT - o is NaT + + for o in [ + offsets.Day(5), + offsets.Hour(24), + np.timedelta64(2, "D"), + np.timedelta64(3600 * 24, "s"), + timedelta(-2), + timedelta(hours=48), + offsets.YearBegin(2), + offsets.MonthBegin(1), + offsets.Minute(), + np.timedelta64(4, "h"), + timedelta(hours=23), + ]: + assert NaT - o is NaT + + for o in [ + offsets.Day(2), + offsets.Hour(3), + np.timedelta64(3, "h"), + np.timedelta64(3600, "s"), + timedelta(minutes=120), + timedelta(days=4, minutes=180), + offsets.YearBegin(2), + offsets.MonthBegin(1), + offsets.Minute(), + np.timedelta64(3200, "s"), + timedelta(hours=23, minutes=30), + ]: + assert NaT - o is NaT @pytest.mark.parametrize("freq", ["M", "2M", "3M"]) - def test_nat_ops(self, freq): - p = Period("NaT", freq=freq) - assert p is NaT - assert p + 1 is NaT - assert 1 + p is NaT - assert p - 1 is NaT - assert p - Period("2011-01", freq=freq) is NaT - assert Period("2011-01", freq=freq) - p is NaT + def test_period_addsub_nat(self, freq): + assert NaT - Period("2011-01", freq=freq) is NaT + assert Period("2011-01", freq=freq) - NaT is NaT def test_period_ops_offset(self): p = Period("2011-04-01", freq="D") From 53d5e8c09637812bff67aedf5471718309cf2dd1 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Fri, 20 Mar 2020 14:21:03 -0700 Subject: [PATCH 3/4] de-duplicate lists --- pandas/tests/scalar/period/test_period.py | 107 +++------------------- 1 file changed, 13 insertions(+), 94 deletions(-) diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py index 63a830fab88dc..d821b5b74520e 100644 --- a/pandas/tests/scalar/period/test_period.py +++ b/pandas/tests/scalar/period/test_period.py @@ -1278,8 +1278,7 @@ def test_add_offset(self): with pytest.raises(IncompatibleFrequency): o + p - # TODO: this is really testing NaT and offsets, not Period, also - # the loops in here are highly duplicative + # TODO: this is really testing NaT and offsets, not Period def test_add_offset_nat(self): # freq is DateOffset @@ -1287,56 +1286,31 @@ def test_add_offset_nat(self): offsets.YearEnd(2), offsets.YearBegin(2), offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(365, "D"), - timedelta(365), - ]: - assert NaT + o is NaT - assert o + NaT is NaT - - for o in [ offsets.MonthEnd(2), offsets.MonthEnd(12), - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(365, "D"), - timedelta(365), - ]: - assert NaT + o is NaT - assert o + NaT is NaT - - for o in [ + offsets.Day(2), offsets.Day(5), offsets.Hour(24), - np.timedelta64(2, "D"), - np.timedelta64(3600 * 24, "s"), - timedelta(-2), - timedelta(hours=48), - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(4, "h"), - timedelta(hours=23), - ]: - assert NaT + o is NaT - assert o + NaT is NaT - - for o in [ - offsets.Day(2), offsets.Hour(3), + offsets.Minute(), np.timedelta64(3, "h"), + np.timedelta64(4, "h"), + np.timedelta64(3200, "s"), np.timedelta64(3600, "s"), + np.timedelta64(3600 * 24, "s"), + np.timedelta64(2, "D"), + np.timedelta64(365, "D"), + timedelta(-2), + timedelta(365), timedelta(minutes=120), timedelta(days=4, minutes=180), - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(3200, "s"), + timedelta(hours=23), timedelta(hours=23, minutes=30), + timedelta(hours=48), ]: assert NaT + o is NaT assert o + NaT is NaT + assert NaT - o is NaT def test_sub_offset(self): # freq is DateOffset @@ -1412,61 +1386,6 @@ def test_sub_offset(self): with pytest.raises(IncompatibleFrequency): p - o - # TODO: this is really testing NaT and offsets, not Period, also - # the loops in here are highly duplicative - def test_sub_offset_nat(self): - # freq is DateOffset - for o in [ - offsets.YearEnd(2), - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(365, "D"), - timedelta(365), - ]: - assert NaT - o is NaT - - for o in [ - offsets.MonthEnd(2), - offsets.MonthEnd(12), - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(365, "D"), - timedelta(365), - ]: - assert NaT - o is NaT - - for o in [ - offsets.Day(5), - offsets.Hour(24), - np.timedelta64(2, "D"), - np.timedelta64(3600 * 24, "s"), - timedelta(-2), - timedelta(hours=48), - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(4, "h"), - timedelta(hours=23), - ]: - assert NaT - o is NaT - - for o in [ - offsets.Day(2), - offsets.Hour(3), - np.timedelta64(3, "h"), - np.timedelta64(3600, "s"), - timedelta(minutes=120), - timedelta(days=4, minutes=180), - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.Minute(), - np.timedelta64(3200, "s"), - timedelta(hours=23, minutes=30), - ]: - assert NaT - o is NaT - @pytest.mark.parametrize("freq", ["M", "2M", "3M"]) def test_period_addsub_nat(self, freq): assert NaT - Period("2011-01", freq=freq) is NaT From b656837298bdf11432cd0300646ba670f12a4b78 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sat, 21 Mar 2020 15:17:26 -0700 Subject: [PATCH 4/4] move misplaced NaT test --- pandas/tests/scalar/period/test_period.py | 34 --------------------- pandas/tests/scalar/test_nat.py | 36 +++++++++++++++++++++++ 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py index d821b5b74520e..1fee40c2a902b 100644 --- a/pandas/tests/scalar/period/test_period.py +++ b/pandas/tests/scalar/period/test_period.py @@ -1278,40 +1278,6 @@ def test_add_offset(self): with pytest.raises(IncompatibleFrequency): o + p - # TODO: this is really testing NaT and offsets, not Period - def test_add_offset_nat(self): - # freq is DateOffset - - for o in [ - offsets.YearEnd(2), - offsets.YearBegin(2), - offsets.MonthBegin(1), - offsets.MonthEnd(2), - offsets.MonthEnd(12), - offsets.Day(2), - offsets.Day(5), - offsets.Hour(24), - offsets.Hour(3), - offsets.Minute(), - np.timedelta64(3, "h"), - np.timedelta64(4, "h"), - np.timedelta64(3200, "s"), - np.timedelta64(3600, "s"), - np.timedelta64(3600 * 24, "s"), - np.timedelta64(2, "D"), - np.timedelta64(365, "D"), - timedelta(-2), - timedelta(365), - timedelta(minutes=120), - timedelta(days=4, minutes=180), - timedelta(hours=23), - timedelta(hours=23, minutes=30), - timedelta(hours=48), - ]: - assert NaT + o is NaT - assert o + NaT is NaT - assert NaT - o is NaT - def test_sub_offset(self): # freq is DateOffset for freq in ["A", "2A", "3A"]: diff --git a/pandas/tests/scalar/test_nat.py b/pandas/tests/scalar/test_nat.py index a537f000959e3..f94b96b47fc05 100644 --- a/pandas/tests/scalar/test_nat.py +++ b/pandas/tests/scalar/test_nat.py @@ -20,6 +20,7 @@ TimedeltaIndex, Timestamp, isna, + offsets, ) import pandas._testing as tm from pandas.core.arrays import DatetimeArray, PeriodArray, TimedeltaArray @@ -508,3 +509,38 @@ def test_nat_comparisons(compare_operators_no_eq_ne, other): # GH 26039 assert getattr(NaT, compare_operators_no_eq_ne)(other) is False assert getattr(other, compare_operators_no_eq_ne)(NaT) is False + + +@pytest.mark.parametrize( + "obj", + [ + offsets.YearEnd(2), + offsets.YearBegin(2), + offsets.MonthBegin(1), + offsets.MonthEnd(2), + offsets.MonthEnd(12), + offsets.Day(2), + offsets.Day(5), + offsets.Hour(24), + offsets.Hour(3), + offsets.Minute(), + np.timedelta64(3, "h"), + np.timedelta64(4, "h"), + np.timedelta64(3200, "s"), + np.timedelta64(3600, "s"), + np.timedelta64(3600 * 24, "s"), + np.timedelta64(2, "D"), + np.timedelta64(365, "D"), + timedelta(-2), + timedelta(365), + timedelta(minutes=120), + timedelta(days=4, minutes=180), + timedelta(hours=23), + timedelta(hours=23, minutes=30), + timedelta(hours=48), + ], +) +def test_nat_addsub_tdlike_scalar(obj): + assert NaT + obj is NaT + assert obj + NaT is NaT + assert NaT - obj is NaT