diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 2b2be214428d2..58345aa22eac1 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -2077,7 +2077,7 @@ def objects_to_datetime64ns( require_iso8601=require_iso8601, ) result = result.reshape(data.shape, order=order) - except ValueError as e: + except ValueError as err: try: values, tz_parsed = conversion.datetime_to_datetime64(data.ravel("K")) # If tzaware, these values represent unix timestamps, so we @@ -2085,7 +2085,7 @@ def objects_to_datetime64ns( values = values.reshape(data.shape, order=order) return values.view("i8"), tz_parsed except (ValueError, TypeError): - raise e + raise err if tz_parsed is not None: # We can take a shortcut since the datetime64 numpy array diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index 4d7a06b691fa3..b7113669a1905 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -231,6 +231,7 @@ def maybe_downcast_to_dtype(result, dtype: Union[str, np.dtype]): # convert to datetime and change timezone i8values = result.astype("i8", copy=False) cls = dtype.construct_array_type() + # equiv: DatetimeArray(i8values).tz_localize("UTC").tz_convert(dtype.tz) result = cls._simple_new(i8values, dtype=dtype) else: result = result.astype(dtype) diff --git a/pandas/tests/arithmetic/test_period.py b/pandas/tests/arithmetic/test_period.py index 690d10054f4c4..c7a99fbb5c1a8 100644 --- a/pandas/tests/arithmetic/test_period.py +++ b/pandas/tests/arithmetic/test_period.py @@ -41,7 +41,9 @@ def test_compare_zerodim(self, box_with_array): expected = tm.box_expected(expected, xbox) tm.assert_equal(result, expected) - @pytest.mark.parametrize("scalar", ["foo", Timestamp.now(), Timedelta(days=4)]) + @pytest.mark.parametrize( + "scalar", ["foo", Timestamp.now(), Timedelta(days=4), 9, 9.5] + ) def test_compare_invalid_scalar(self, box_with_array, scalar): # comparison with scalar that cannot be interpreted as a Period pi = pd.period_range("2000", periods=4) diff --git a/pandas/tests/arithmetic/test_timedelta64.py b/pandas/tests/arithmetic/test_timedelta64.py index 110f55a49eea3..5f3d2040b0201 100644 --- a/pandas/tests/arithmetic/test_timedelta64.py +++ b/pandas/tests/arithmetic/test_timedelta64.py @@ -16,6 +16,7 @@ Timedelta, TimedeltaIndex, Timestamp, + offsets, timedelta_range, ) import pandas._testing as tm @@ -70,7 +71,12 @@ def test_compare_timedelta64_zerodim(self, box_with_array): @pytest.mark.parametrize( "td_scalar", - [timedelta(days=1), Timedelta(days=1), Timedelta(days=1).to_timedelta64()], + [ + timedelta(days=1), + Timedelta(days=1), + Timedelta(days=1).to_timedelta64(), + offsets.Hour(24), + ], ) def test_compare_timedeltalike_scalar(self, box_with_array, td_scalar): # regression test for GH#5963 @@ -84,7 +90,18 @@ def test_compare_timedeltalike_scalar(self, box_with_array, td_scalar): expected = tm.box_expected(expected, xbox) tm.assert_equal(actual, expected) - @pytest.mark.parametrize("invalid", [345600000000000, "a"]) + @pytest.mark.parametrize( + "invalid", + [ + 345600000000000, + "a", + Timestamp.now(), + Timestamp.now("UTC"), + Timestamp.now().to_datetime64(), + Timestamp.now().to_pydatetime(), + Timestamp.now().date(), + ], + ) def test_td64_comparisons_invalid(self, box_with_array, invalid): # GH#13624 for str box = box_with_array @@ -261,7 +278,6 @@ def test_ufunc_coercions(self): tm.assert_index_equal(result, exp) assert result.freq == "H" - idx = TimedeltaIndex(["2H", "4H", "6H", "8H", "10H"], freq="2H", name="x") for result in [-idx, np.negative(idx)]: assert isinstance(result, TimedeltaIndex) exp = TimedeltaIndex( @@ -413,10 +429,6 @@ def test_dti_tdi_numeric_ops(self): tdi = TimedeltaIndex(["1 days", pd.NaT, "2 days"], name="foo") dti = pd.date_range("20130101", periods=3, name="bar") - # TODO(wesm): unused? - # td = Timedelta('1 days') - # dt = Timestamp('20130101') - result = tdi - tdi expected = TimedeltaIndex(["0 days", pd.NaT, "0 days"], name="foo") tm.assert_index_equal(result, expected) @@ -543,7 +555,6 @@ def test_tda_add_sub_index(self): expected = tdi - tdi tm.assert_index_equal(result, expected) - @pytest.mark.xfail(reason="GH38630", strict=False) def test_tda_add_dt64_object_array(self, box_with_array, tz_naive_fixture): # Result should be cast back to DatetimeArray box = box_with_array @@ -555,10 +566,7 @@ def test_tda_add_dt64_object_array(self, box_with_array, tz_naive_fixture): obj = tm.box_expected(tdi, box) other = tm.box_expected(dti, box) - warn = None - if box is not pd.DataFrame or tz_naive_fixture is None: - warn = PerformanceWarning - with tm.assert_produces_warning(warn): + with tm.assert_produces_warning(PerformanceWarning): result = obj + other.astype(object) tm.assert_equal(result, other) diff --git a/pandas/tests/extension/base/setitem.py b/pandas/tests/extension/base/setitem.py index e77d2b2633e88..66547930fe9c1 100644 --- a/pandas/tests/extension/base/setitem.py +++ b/pandas/tests/extension/base/setitem.py @@ -40,7 +40,7 @@ def test_setitem_sequence_mismatched_length_raises(self, data, as_array): ser[slice(3)] = value self.assert_series_equal(ser, original) - def test_setitem_empty_indxer(self, data, box_in_series): + def test_setitem_empty_indexer(self, data, box_in_series): if box_in_series: data = pd.Series(data) original = data.copy() diff --git a/pandas/tests/series/test_arithmetic.py b/pandas/tests/series/test_arithmetic.py index b204d92b9122f..a0e0213a6dce5 100644 --- a/pandas/tests/series/test_arithmetic.py +++ b/pandas/tests/series/test_arithmetic.py @@ -267,7 +267,7 @@ def test_sub_datetimelike_align(self): def test_alignment_doesnt_change_tz(self): # GH#33671 - dti = pd.date_range("2016-01-01", periods=10, tz="CET") + dti = date_range("2016-01-01", periods=10, tz="CET") dti_utc = dti.tz_convert("UTC") ser = Series(10, index=dti) ser_utc = Series(10, index=dti_utc) @@ -399,7 +399,7 @@ def test_ser_flex_cmp_return_dtypes_empty(self, opname): ) def test_ser_cmp_result_names(self, names, op): # datetime64 dtype - dti = pd.date_range("1949-06-07 03:00:00", freq="H", periods=5, name=names[0]) + dti = date_range("1949-06-07 03:00:00", freq="H", periods=5, name=names[0]) ser = Series(dti).rename(names[1]) result = op(ser, dti) assert result.name == names[2] @@ -624,9 +624,13 @@ def test_ne(self): ), ], ) - def test_comp_ops_df_compat(self, left, right): + def test_comp_ops_df_compat(self, left, right, frame_or_series): # GH 1134 - msg = "Can only compare identically-labeled Series objects" + msg = f"Can only compare identically-labeled {frame_or_series.__name__} objects" + if frame_or_series is not Series: + left = left.to_frame() + right = right.to_frame() + with pytest.raises(ValueError, match=msg): left == right with pytest.raises(ValueError, match=msg): @@ -642,22 +646,6 @@ def test_comp_ops_df_compat(self, left, right): with pytest.raises(ValueError, match=msg): right < left - msg = "Can only compare identically-labeled DataFrame objects" - with pytest.raises(ValueError, match=msg): - left.to_frame() == right.to_frame() - with pytest.raises(ValueError, match=msg): - right.to_frame() == left.to_frame() - - with pytest.raises(ValueError, match=msg): - left.to_frame() != right.to_frame() - with pytest.raises(ValueError, match=msg): - right.to_frame() != left.to_frame() - - with pytest.raises(ValueError, match=msg): - left.to_frame() < right.to_frame() - with pytest.raises(ValueError, match=msg): - right.to_frame() < left.to_frame() - def test_compare_series_interval_keyword(self): # GH#25338 s = Series(["IntervalA", "IntervalB", "IntervalC"]) @@ -724,7 +712,7 @@ def test_series_add_aware_naive_raises(self): def test_datetime_understood(self): # Ensures it doesn't fail to create the right series # reported in issue#16726 - series = Series(pd.date_range("2012-01-01", periods=3)) + series = Series(date_range("2012-01-01", periods=3)) offset = pd.offsets.DateOffset(days=6) result = series - offset expected = Series(pd.to_datetime(["2011-12-26", "2011-12-27", "2011-12-28"])) @@ -746,58 +734,46 @@ def test_align_date_objects_with_datetimeindex(self): tm.assert_series_equal(result2, expected) -@pytest.mark.parametrize( - "names", - [ - ("foo", None, None), - ("Egon", "Venkman", None), - ("NCC1701D", "NCC1701D", "NCC1701D"), - ], -) -@pytest.mark.parametrize("box", [list, tuple, np.array, pd.Index, pd.Series, pd.array]) -@pytest.mark.parametrize("flex", [True, False]) -def test_series_ops_name_retention(flex, box, names, all_binary_operators, request): - # GH#33930 consistent name retention - op = all_binary_operators - - if op is ops.rfloordiv and box in [list, tuple] and not flex: - mark = pytest.mark.xfail( - reason="op fails because of inconsistent ndarray-wrapping GH#28759" - ) - request.node.add_marker(mark) - - left = Series(range(10), name=names[0]) - right = Series(range(10), name=names[1]) - - name = op.__name__.strip("_") - is_logical = name in ["and", "rand", "xor", "rxor", "or", "ror"] - is_rlogical = is_logical and name.startswith("r") - - right = box(right) - if flex: - if is_logical: - # Series doesn't have these as flex methods +class TestNamePreservation: + @pytest.mark.parametrize("box", [list, tuple, np.array, Index, Series, pd.array]) + @pytest.mark.parametrize("flex", [True, False]) + def test_series_ops_name_retention(self, flex, box, names, all_binary_operators): + # GH#33930 consistent name renteiton + op = all_binary_operators + + if op is ops.rfloordiv and box in [list, tuple]: + pytest.xfail("op fails because of inconsistent ndarray-wrapping GH#28759") + + left = Series(range(10), name=names[0]) + right = Series(range(10), name=names[1]) + + name = op.__name__.strip("_") + is_logical = name in ["and", "rand", "xor", "rxor", "or", "ror"] + is_rlogical = is_logical and name.startswith("r") + + right = box(right) + if flex: + if is_logical: + # Series doesn't have these as flex methods + return + result = getattr(left, name)(right) + else: + # GH#37374 logical ops behaving as set ops deprecated + warn = FutureWarning if is_rlogical and box is Index else None + with tm.assert_produces_warning(warn, check_stacklevel=False): + result = op(left, right) + + if box is Index and is_rlogical: + # Index treats these as set operators, so does not defer + assert isinstance(result, Index) return - result = getattr(left, name)(right) - else: - # GH#37374 logical ops behaving as set ops deprecated - warn = FutureWarning if is_rlogical and box is Index else None - with tm.assert_produces_warning(warn, check_stacklevel=False): - result = op(left, right) - - if box is pd.Index and is_rlogical: - # Index treats these as set operators, so does not defer - assert isinstance(result, pd.Index) - return - - assert isinstance(result, Series) - if box in [pd.Index, pd.Series]: - assert result.name == names[2] - else: - assert result.name == names[0] + assert isinstance(result, Series) + if box in [Index, Series]: + assert result.name == names[2] + else: + assert result.name == names[0] -class TestNamePreservation: def test_binop_maybe_preserve_name(self, datetime_series): # names match, preserve result = datetime_series * datetime_series