From bda37e8be10f0452a28f5b2c9c6a3afe34d5f5db Mon Sep 17 00:00:00 2001 From: arthurlw Date: Mon, 1 Sep 2025 17:08:26 -0700 Subject: [PATCH 01/10] Updated _infer_matches and _maybe_downcast_for_indexing --- pandas/core/arrays/datetimes.py | 2 +- pandas/core/indexes/base.py | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 67ee16fd3a34e..15f9647ae05a6 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -228,7 +228,7 @@ class DatetimeArray(dtl.TimelikeOps, dtl.DatelikeOps): # type: ignore[misc] _is_recognized_dtype = lambda x: lib.is_np_dtype(x, "M") or isinstance( x, DatetimeTZDtype ) - _infer_matches = ("datetime", "datetime64", "date") + _infer_matches = ("datetime", "datetime64") @property def _scalar_type(self) -> type[Timestamp]: diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 2ec774af15934..07eaafb3e1ef6 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -6205,11 +6205,6 @@ def _maybe_downcast_for_indexing(self, other: Index) -> tuple[Index, Index]: # standardize on UTC return self.tz_convert("UTC"), other.tz_convert("UTC") - elif self.inferred_type == "date" and isinstance(other, ABCDatetimeIndex): - try: - return type(other)(self), other - except OutOfBoundsDatetime: - return self, other elif self.inferred_type == "timedelta" and isinstance(other, ABCTimedeltaIndex): # TODO: we dont have tests that get here return type(other)(self), other @@ -6232,7 +6227,6 @@ def _maybe_downcast_for_indexing(self, other: Index) -> tuple[Index, Index]: if not is_object_dtype(self.dtype) and is_object_dtype(other.dtype): # Reverse op so we dont need to re-implement on the subclasses other, self = other._maybe_downcast_for_indexing(self) - return self, other @final From 2712fd7db99eeefe5be88db058952c879fd70883 Mon Sep 17 00:00:00 2001 From: arthurlw Date: Fri, 5 Sep 2025 15:29:10 -0700 Subject: [PATCH 02/10] Deprecated tests --- pandas/core/indexes/base.py | 2 +- pandas/tests/frame/methods/test_asfreq.py | 11 ---------- .../tests/indexes/datetimes/test_indexing.py | 21 ------------------- pandas/tests/series/test_arithmetic.py | 15 ------------- 4 files changed, 1 insertion(+), 48 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index a9e6921536477..b9d59e7431f27 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -39,7 +39,6 @@ no_default, ) from pandas._libs.tslibs import ( - OutOfBoundsDatetime, Timestamp, tz_compare, ) @@ -6228,6 +6227,7 @@ def _maybe_downcast_for_indexing(self, other: Index) -> tuple[Index, Index]: if not is_object_dtype(self.dtype) and is_object_dtype(other.dtype): # Reverse op so we dont need to re-implement on the subclasses other, self = other._maybe_downcast_for_indexing(self) + return self, other @final diff --git a/pandas/tests/frame/methods/test_asfreq.py b/pandas/tests/frame/methods/test_asfreq.py index 1c3c41e2e0299..734df90050b4f 100644 --- a/pandas/tests/frame/methods/test_asfreq.py +++ b/pandas/tests/frame/methods/test_asfreq.py @@ -185,17 +185,6 @@ def test_asfreq_fillvalue(self): actual_series = ts.asfreq(freq="1s", fill_value=9.0) tm.assert_series_equal(expected_series, actual_series) - def test_asfreq_with_date_object_index(self, frame_or_series): - rng = date_range("1/1/2000", periods=20) - ts = frame_or_series(np.random.default_rng(2).standard_normal(20), index=rng) - - ts2 = ts.copy() - ts2.index = [x.date() for x in ts2.index] - - result = ts2.asfreq("4h", method="ffill") - expected = ts.asfreq("4h", method="ffill") - tm.assert_equal(result, expected) - def test_asfreq_with_unsorted_index(self, frame_or_series): # GH#39805 # Test that rows are not dropped when the datetime index is out of order diff --git a/pandas/tests/indexes/datetimes/test_indexing.py b/pandas/tests/indexes/datetimes/test_indexing.py index c44345273466c..31dbab645c633 100644 --- a/pandas/tests/indexes/datetimes/test_indexing.py +++ b/pandas/tests/indexes/datetimes/test_indexing.py @@ -513,13 +513,6 @@ def test_contains_nonunique(self, vals): class TestGetIndexer: - def test_get_indexer_date_objs(self): - rng = date_range("1/1/2000", periods=20) - - result = rng.get_indexer(rng.map(lambda x: x.date())) - expected = rng.get_indexer(rng) - tm.assert_numpy_array_equal(result, expected) - def test_get_indexer(self): idx = date_range("2000-01-01", periods=3) exp = np.array([0, 1, 2], dtype=np.intp) @@ -561,20 +554,6 @@ def test_get_indexer(self): with pytest.raises(ValueError, match="abbreviation w/o a number"): idx.get_indexer(idx[[0]], method="nearest", tolerance="foo") - @pytest.mark.parametrize( - "target", - [ - [date(2020, 1, 1), Timestamp("2020-01-02")], - [Timestamp("2020-01-01"), date(2020, 1, 2)], - ], - ) - def test_get_indexer_mixed_dtypes(self, target): - # https://github.com/pandas-dev/pandas/issues/33741 - values = DatetimeIndex([Timestamp("2020-01-01"), Timestamp("2020-01-02")]) - result = values.get_indexer(target) - expected = np.array([0, 1], dtype=np.intp) - tm.assert_numpy_array_equal(result, expected) - @pytest.mark.parametrize( "target, positions", [ diff --git a/pandas/tests/series/test_arithmetic.py b/pandas/tests/series/test_arithmetic.py index 35a9742d653db..d22e6809ae97c 100644 --- a/pandas/tests/series/test_arithmetic.py +++ b/pandas/tests/series/test_arithmetic.py @@ -757,21 +757,6 @@ def test_datetime_understood(self, unit): expected = Series(exp_dti) tm.assert_series_equal(result, expected) - def test_align_date_objects_with_datetimeindex(self): - rng = date_range("1/1/2000", periods=20) - ts = Series(np.random.default_rng(2).standard_normal(20), index=rng) - - ts_slice = ts[5:] - ts2 = ts_slice.copy() - ts2.index = [x.date() for x in ts2.index] - - result = ts + ts2 - result2 = ts2 + ts - expected = ts + ts[5:] - expected.index = expected.index._with_freq(None) - tm.assert_series_equal(result, expected) - tm.assert_series_equal(result2, expected) - class TestNamePreservation: @pytest.mark.parametrize("box", [list, tuple, np.array, Index, Series, pd.array]) From 8b1ab371adae87687fad49cba8abaf49bcae03f8 Mon Sep 17 00:00:00 2001 From: arthurlw Date: Wed, 10 Sep 2025 10:54:49 -0700 Subject: [PATCH 03/10] Deprecate categorical datetime coercion test --- pandas/tests/io/parser/dtypes/test_categorical.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/pandas/tests/io/parser/dtypes/test_categorical.py b/pandas/tests/io/parser/dtypes/test_categorical.py index 15cbac54ff8d9..427ebe5d0650f 100644 --- a/pandas/tests/io/parser/dtypes/test_categorical.py +++ b/pandas/tests/io/parser/dtypes/test_categorical.py @@ -271,18 +271,6 @@ def test_categorical_coerces_numeric(all_parsers): tm.assert_frame_equal(result, expected) -def test_categorical_coerces_datetime(all_parsers): - parser = all_parsers - dti = pd.DatetimeIndex(["2017-01-01", "2018-01-01", "2019-01-01"], freq=None) - dtype = {"b": CategoricalDtype(dti)} - - data = "b\n2017-01-01\n2018-01-01\n2019-01-01" - expected = DataFrame({"b": Categorical(dtype["b"].categories)}) - - result = parser.read_csv(StringIO(data), dtype=dtype) - tm.assert_frame_equal(result, expected) - - def test_categorical_coerces_timestamp(all_parsers): parser = all_parsers dtype = {"b": CategoricalDtype([Timestamp("2014")])} From 418dc4a59f6621818b85f896f478555487528626 Mon Sep 17 00:00:00 2001 From: arthurlw Date: Wed, 10 Sep 2025 11:15:42 -0700 Subject: [PATCH 04/10] Deprecate get_indexer date coercion test --- pandas/tests/indexes/datetimes/test_indexing.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pandas/tests/indexes/datetimes/test_indexing.py b/pandas/tests/indexes/datetimes/test_indexing.py index d5a9be38b9663..06758206948bd 100644 --- a/pandas/tests/indexes/datetimes/test_indexing.py +++ b/pandas/tests/indexes/datetimes/test_indexing.py @@ -534,13 +534,6 @@ def test_get_indexer_pyarrow(self, as_td): result2 = target.get_indexer(index) tm.assert_numpy_array_equal(result2, expected) - def test_get_indexer_date_objs(self): - rng = date_range("1/1/2000", periods=20) - - result = rng.get_indexer(rng.map(lambda x: x.date())) - expected = rng.get_indexer(rng) - tm.assert_numpy_array_equal(result, expected) - def test_get_indexer(self): idx = date_range("2000-01-01", periods=3) exp = np.array([0, 1, 2], dtype=np.intp) From b60c74468901ae018f3df09303d6411d0f823c87 Mon Sep 17 00:00:00 2001 From: arthurlw Date: Wed, 10 Sep 2025 13:48:07 -0700 Subject: [PATCH 05/10] Update timestamp values in test_categorical_coerces_timestamp --- pandas/tests/io/parser/dtypes/test_categorical.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/tests/io/parser/dtypes/test_categorical.py b/pandas/tests/io/parser/dtypes/test_categorical.py index d24a6d43d4048..4c4767b1ab49b 100644 --- a/pandas/tests/io/parser/dtypes/test_categorical.py +++ b/pandas/tests/io/parser/dtypes/test_categorical.py @@ -274,10 +274,10 @@ def test_categorical_coerces_numeric(all_parsers): def test_categorical_coerces_timestamp(all_parsers): parser = all_parsers - dtype = {"b": CategoricalDtype([Timestamp("2014")])} + dtype = {"b": CategoricalDtype([Timestamp("2014-01-01 12:00:00")])} - data = "b\n2014-01-01\n2014-01-01" - expected = DataFrame({"b": Categorical([Timestamp("2014")] * 2)}) + data = "b\n2014-01-01 12:00:00\n2014-01-01 12:00:00" + expected = DataFrame({"b": Categorical([Timestamp("2014-01-01 12:00:00")] * 2)}) result = parser.read_csv(StringIO(data), dtype=dtype) tm.assert_frame_equal(result, expected) From 2e11d26f9bf15a952ea84174eeb25892ecb32c25 Mon Sep 17 00:00:00 2001 From: arthurlw Date: Sun, 14 Sep 2025 11:01:27 -0700 Subject: [PATCH 06/10] Updated deprecated test behavior --- pandas/tests/frame/methods/test_asfreq.py | 9 ++++++++ .../tests/indexes/datetimes/test_indexing.py | 22 +++++++++++++++++++ pandas/tests/series/test_arithmetic.py | 14 ++++++++++++ 3 files changed, 45 insertions(+) diff --git a/pandas/tests/frame/methods/test_asfreq.py b/pandas/tests/frame/methods/test_asfreq.py index 734df90050b4f..4a1091bbd8469 100644 --- a/pandas/tests/frame/methods/test_asfreq.py +++ b/pandas/tests/frame/methods/test_asfreq.py @@ -185,6 +185,15 @@ def test_asfreq_fillvalue(self): actual_series = ts.asfreq(freq="1s", fill_value=9.0) tm.assert_series_equal(expected_series, actual_series) + def test_asfreq_with_date_object_index(self, frame_or_series): + # GH#62158 date objects lose indexing special case + rng = date_range("1/1/2000", periods=20) + ts = frame_or_series(np.random.default_rng(2).standard_normal(20), index=rng) + ts.index = [x.date() for x in ts.index] + + with pytest.raises(TypeError, match="Cannot compare Timestamp with datetime.date"): + ts.asfreq("4h", method="ffill") + def test_asfreq_with_unsorted_index(self, frame_or_series): # GH#39805 # Test that rows are not dropped when the datetime index is out of order diff --git a/pandas/tests/indexes/datetimes/test_indexing.py b/pandas/tests/indexes/datetimes/test_indexing.py index 06758206948bd..57724a6ccd741 100644 --- a/pandas/tests/indexes/datetimes/test_indexing.py +++ b/pandas/tests/indexes/datetimes/test_indexing.py @@ -534,6 +534,14 @@ def test_get_indexer_pyarrow(self, as_td): result2 = target.get_indexer(index) tm.assert_numpy_array_equal(result2, expected) + def test_get_indexer_date_objs(self): + # GH#62158 date objects lose indexing special case + rng = date_range("1/1/2000", periods=20) + result = rng.get_indexer(rng.map(lambda x: x.date())) + + expected = np.full(len(rng), -1, dtype=np.intp) + tm.assert_numpy_array_equal(result, expected) + def test_get_indexer(self): idx = date_range("2000-01-01", periods=3) exp = np.array([0, 1, 2], dtype=np.intp) @@ -575,6 +583,20 @@ def test_get_indexer(self): with pytest.raises(ValueError, match="abbreviation w/o a number"): idx.get_indexer(idx[[0]], method="nearest", tolerance="foo") + @pytest.mark.parametrize( + "target, expected", + [ + ([date(2020, 1, 1), Timestamp("2020-01-02")], np.array([-1, 1], dtype=np.intp)), + ([Timestamp("2020-01-01"), date(2020, 1, 2)], np.array([0, -1], dtype=np.intp)), + ], + ) + def test_get_indexer_mixed_dtypes(self, target, expected): + # GH#33741 regression test: mixed dtypes should not error + # GH#62158 date objects lose indexing special case + values = DatetimeIndex([Timestamp("2020-01-01"), Timestamp("2020-01-02")]) + result = values.get_indexer(target) + tm.assert_numpy_array_equal(result, expected) + @pytest.mark.parametrize( "target, positions", [ diff --git a/pandas/tests/series/test_arithmetic.py b/pandas/tests/series/test_arithmetic.py index d22e6809ae97c..0991586918499 100644 --- a/pandas/tests/series/test_arithmetic.py +++ b/pandas/tests/series/test_arithmetic.py @@ -757,6 +757,20 @@ def test_datetime_understood(self, unit): expected = Series(exp_dti) tm.assert_series_equal(result, expected) + def test_align_date_objects_with_datetimeindex_coerced(self): + # GH#62158: datetime.date objects no longer auto-align with Timestamps + rng = date_range("1/1/2000", periods=20) + ts = Series(np.random.default_rng(2).standard_normal(20), index=rng) + + ts_slice = ts[5:] + ts2 = ts_slice.copy() + ts2.index = pd.to_datetime([x.date() for x in ts2.index]) + + result = ts + ts2 + expected = ts + ts[5:] + expected.index = expected.index._with_freq(None) + tm.assert_series_equal(result, expected) + class TestNamePreservation: @pytest.mark.parametrize("box", [list, tuple, np.array, Index, Series, pd.array]) From b7272501630b05d3b53793bcf7f80da0fedeab8f Mon Sep 17 00:00:00 2001 From: arthurlw Date: Sun, 14 Sep 2025 14:30:54 -0700 Subject: [PATCH 07/10] precommit --- pandas/tests/frame/methods/test_asfreq.py | 4 +++- pandas/tests/indexes/datetimes/test_indexing.py | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/pandas/tests/frame/methods/test_asfreq.py b/pandas/tests/frame/methods/test_asfreq.py index 4a1091bbd8469..5975f5501e6f6 100644 --- a/pandas/tests/frame/methods/test_asfreq.py +++ b/pandas/tests/frame/methods/test_asfreq.py @@ -191,7 +191,9 @@ def test_asfreq_with_date_object_index(self, frame_or_series): ts = frame_or_series(np.random.default_rng(2).standard_normal(20), index=rng) ts.index = [x.date() for x in ts.index] - with pytest.raises(TypeError, match="Cannot compare Timestamp with datetime.date"): + with pytest.raises( + TypeError, match="Cannot compare Timestamp with datetime.date" + ): ts.asfreq("4h", method="ffill") def test_asfreq_with_unsorted_index(self, frame_or_series): diff --git a/pandas/tests/indexes/datetimes/test_indexing.py b/pandas/tests/indexes/datetimes/test_indexing.py index 57724a6ccd741..51468550f030d 100644 --- a/pandas/tests/indexes/datetimes/test_indexing.py +++ b/pandas/tests/indexes/datetimes/test_indexing.py @@ -586,8 +586,14 @@ def test_get_indexer(self): @pytest.mark.parametrize( "target, expected", [ - ([date(2020, 1, 1), Timestamp("2020-01-02")], np.array([-1, 1], dtype=np.intp)), - ([Timestamp("2020-01-01"), date(2020, 1, 2)], np.array([0, -1], dtype=np.intp)), + ( + [date(2020, 1, 1), Timestamp("2020-01-02")], + np.array([-1, 1], dtype=np.intp), + ), + ( + [Timestamp("2020-01-01"), date(2020, 1, 2)], + np.array([0, -1], dtype=np.intp), + ), ], ) def test_get_indexer_mixed_dtypes(self, target, expected): From 9083e84d370c92d633a010dbf689a80893b802fc Mon Sep 17 00:00:00 2001 From: arthurlw Date: Thu, 9 Oct 2025 11:33:19 -0700 Subject: [PATCH 08/10] Updated tests according to feedback --- .../io/parser/dtypes/test_categorical.py | 41 ++++++++++++++++--- pandas/tests/series/test_arithmetic.py | 11 +++-- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/pandas/tests/io/parser/dtypes/test_categorical.py b/pandas/tests/io/parser/dtypes/test_categorical.py index 4c4767b1ab49b..910edcd837878 100644 --- a/pandas/tests/io/parser/dtypes/test_categorical.py +++ b/pandas/tests/io/parser/dtypes/test_categorical.py @@ -272,15 +272,46 @@ def test_categorical_coerces_numeric(all_parsers): tm.assert_frame_equal(result, expected) +def test_categorical_coerces_datetime(all_parsers): + parser = all_parsers + dti = pd.DatetimeIndex(["2017-01-01", "2018-01-01", "2019-01-01"], freq=None) + + dtype = {"b": CategoricalDtype(dti)} + + data = "b\n2017-01-01\n2018-01-01\n2019-01-01" + expected = DataFrame({"b": Categorical(dtype["b"].categories)}) + + if parser.engine == "pyarrow": + msg = "Constructing a Categorical with a dtype and values containing" + with tm.assert_produces_warning( + Pandas4Warning, match=msg, check_stacklevel=False + ): + result = parser.read_csv(StringIO(data), dtype=dtype) + tm.assert_series_equal( + result["b"].isna(), pd.Series([True, True, True], name="b") + ) + else: + result = parser.read_csv(StringIO(data), dtype=dtype) + tm.assert_frame_equal(result, expected) + + def test_categorical_coerces_timestamp(all_parsers): parser = all_parsers - dtype = {"b": CategoricalDtype([Timestamp("2014-01-01 12:00:00")])} + dtype = {"b": CategoricalDtype([Timestamp("2014")])} - data = "b\n2014-01-01 12:00:00\n2014-01-01 12:00:00" - expected = DataFrame({"b": Categorical([Timestamp("2014-01-01 12:00:00")] * 2)}) + data = "b\n2014-01-01\n2014-01-01" + expected = DataFrame({"b": Categorical([Timestamp("2014")] * 2)}) - result = parser.read_csv(StringIO(data), dtype=dtype) - tm.assert_frame_equal(result, expected) + if parser.engine == "pyarrow": + msg = "Constructing a Categorical with a dtype and values containing" + with tm.assert_produces_warning( + Pandas4Warning, match=msg, check_stacklevel=False + ): + result = parser.read_csv(StringIO(data), dtype=dtype) + tm.assert_series_equal(result["b"].isna(), pd.Series([True, True], name="b")) + else: + result = parser.read_csv(StringIO(data), dtype=dtype) + tm.assert_frame_equal(result, expected) def test_categorical_coerces_timedelta(all_parsers): diff --git a/pandas/tests/series/test_arithmetic.py b/pandas/tests/series/test_arithmetic.py index 0991586918499..2f3a04af88189 100644 --- a/pandas/tests/series/test_arithmetic.py +++ b/pandas/tests/series/test_arithmetic.py @@ -757,19 +757,22 @@ def test_datetime_understood(self, unit): expected = Series(exp_dti) tm.assert_series_equal(result, expected) - def test_align_date_objects_with_datetimeindex_coerced(self): + def test_align_date_objects_with_datetimeindex(self): # GH#62158: datetime.date objects no longer auto-align with Timestamps rng = date_range("1/1/2000", periods=20) ts = Series(np.random.default_rng(2).standard_normal(20), index=rng) ts_slice = ts[5:] ts2 = ts_slice.copy() - ts2.index = pd.to_datetime([x.date() for x in ts2.index]) + ts2.index = [x.date() for x in ts2.index] result = ts + ts2 - expected = ts + ts[5:] - expected.index = expected.index._with_freq(None) + result2 = ts2 + ts + expected = Series(dtype=float, index=result.index) + expected2 = Series(dtype=float, index=result2.index) + tm.assert_series_equal(result, expected) + tm.assert_series_equal(result2, expected2) class TestNamePreservation: From f87ffab003244a60db88a6fde4c3be3afda9115c Mon Sep 17 00:00:00 2001 From: arthurlw Date: Fri, 17 Oct 2025 17:11:40 -0700 Subject: [PATCH 09/10] whatsnew --- doc/source/whatsnew/v3.0.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 6e475acc5d971..c556a0031d6a1 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -606,6 +606,7 @@ Other API changes - :meth:`ExtensionDtype.construct_array_type` is now a regular method instead of a ``classmethod`` (:issue:`58663`) - Comparison operations between :class:`Index` and :class:`Series` now consistently return :class:`Series` regardless of which object is on the left or right (:issue:`36759`) - Numpy functions like ``np.isinf`` that return a bool dtype when called on a :class:`Index` object now return a bool-dtype :class:`Index` instead of ``np.ndarray`` (:issue:`52676`) +- Removed special handling of ``datetime.date`` sequences in :meth:`Index._maybe_downcast_for_indexing` and removed ``"date"`` from ``_infer_matches``. (:issue:`62158`) .. --------------------------------------------------------------------------- .. _whatsnew_300.deprecations: From ad7509ae2a2a1dd083aca0f65bbb6bd7836f44e5 Mon Sep 17 00:00:00 2001 From: arthurlw Date: Mon, 3 Nov 2025 23:30:00 -0800 Subject: [PATCH 10/10] user facing whatsnew note --- doc/source/whatsnew/v3.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index ade87f5996670..61d429208458d 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -659,8 +659,8 @@ Other API changes - :meth:`CategoricalIndex.append` no longer attempts to cast different-dtype indexes to the caller's dtype (:issue:`41626`) - :meth:`ExtensionDtype.construct_array_type` is now a regular method instead of a ``classmethod`` (:issue:`58663`) - Comparison operations between :class:`Index` and :class:`Series` now consistently return :class:`Series` regardless of which object is on the left or right (:issue:`36759`) +- Indexing and comparison with sequences of ``datetime.date`` objects are now consistent with scalar ``datetime.date`` behavior in :class:`DatetimeIndex` (:issue:`62158`) - Numpy functions like ``np.isinf`` that return a bool dtype when called on a :class:`Index` object now return a bool-dtype :class:`Index` instead of ``np.ndarray`` (:issue:`52676`) -- Removed special handling of ``datetime.date`` sequences in :meth:`Index._maybe_downcast_for_indexing` and removed ``"date"`` from ``_infer_matches``. (:issue:`62158`) .. --------------------------------------------------------------------------- .. _whatsnew_300.deprecations: