From b62d68785d52e27337b5d6dc0635bdd523ac8af9 Mon Sep 17 00:00:00 2001 From: Raghavendranath Kandula Date: Tue, 4 Nov 2025 21:46:31 -0500 Subject: [PATCH 01/12] DEPR: Deprecate non-ISO date string formats in DatetimeIndex.loc --- doc/source/whatsnew/v3.0.0.rst | 2 +- pandas/core/indexes/datetimes.py | 50 ++++++++++ .../indexes/datetimes/test_partial_slicing.py | 95 +++++++++++++++++++ 3 files changed, 146 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index d11ab82294be1..102045c2427ca 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -739,13 +739,13 @@ Other Deprecations - Deprecated allowing ``fill_value`` that cannot be held in the original dtype (excepting NA values for integer and bool dtypes) in :meth:`Series.shift` and :meth:`DataFrame.shift` (:issue:`53802`) - Deprecated allowing strings representing full dates in :meth:`DataFrame.at_time` and :meth:`Series.at_time` (:issue:`50839`) - Deprecated backward-compatibility behavior for :meth:`DataFrame.select_dtypes` matching "str" dtype when ``np.object_`` is specified (:issue:`61916`) +- Deprecated non-ISO date string formats in :meth:`DatetimeIndex.__getitem__` with string labels. Use ISO format (YYYY-MM-DD) instead. (:issue:`58302`) - Deprecated option "future.no_silent_downcasting", as it is no longer used. In a future version accessing this option will raise (:issue:`59502`) - Deprecated passing non-Index types to :meth:`Index.join`; explicitly convert to Index first (:issue:`62897`) - Deprecated silent casting of non-datetime 'other' to datetime in :meth:`Series.combine_first` (:issue:`62931`) - Deprecated slicing on a :class:`Series` or :class:`DataFrame` with a :class:`DatetimeIndex` using a ``datetime.date`` object, explicitly cast to :class:`Timestamp` instead (:issue:`35830`) - Deprecated support for the Dataframe Interchange Protocol (:issue:`56732`) - Deprecated the 'inplace' keyword from :meth:`Resampler.interpolate`, as passing ``True`` raises ``AttributeError`` (:issue:`58690`) - .. --------------------------------------------------------------------------- .. _whatsnew_300.prior_deprecations: diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 382b3678da75b..98e8a340cf60c 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -2,6 +2,7 @@ import datetime as dt import operator +import re from typing import ( TYPE_CHECKING, Self, @@ -110,6 +111,28 @@ def _new_DatetimeIndex(cls, d): return result +def _is_iso_format_string(date_str: str) -> bool: + """ + Check if a date string follows ISO8601 format. + + ISO format must start with a 4-digit year (YYYY), optionally followed by + month and day with consistent separators. + + Examples of ISO format (True): + - 2024-01-10 + - 2024/01/10 + - 2024 01 10 + - 2024-01-10T00:00:00 + + Examples of non-ISO format (False): + - 01/10/2024 (MM/DD/YYYY) + - 10/01/2024 (DD/MM/YYYY) + - 01-10-2024 (MM-DD-YYYY) + """ + # ISO format must start with 4-digit year followed by separator (-, /, ., or space) + return re.match(r"^\d{4}[-/. ]", date_str) is not None + + @inherit_names( DatetimeArray._field_ops + [ @@ -566,6 +589,15 @@ def _parsed_string_to_bounds( return start, end def _parse_with_reso(self, label: str) -> tuple[Timestamp, Resolution]: + # GH#58302 - Deprecate non-ISO string formats in .loc indexing + if isinstance(label, str) and not _is_iso_format_string(label): + msg = ( + "Parsing non-ISO datetime strings in .loc is deprecated and will be " + "removed in a future version. Use ISO format (YYYY-MM-DD) instead. " + f"Got '{label}'." + ) + warnings.warn(msg, Pandas4Warning, stacklevel=find_stack_level()) + parsed, reso = super()._parse_with_reso(label) parsed = Timestamp(parsed) @@ -701,11 +733,29 @@ def check_str_or_none(point) -> bool: mask = np.array(True) in_index = True if start is not None: + # GH#58302 - Deprecate non-ISO string formats in .loc indexing + if isinstance(start, str) and not _is_iso_format_string(start): + msg = ( + "Parsing non-ISO datetime strings in .loc is deprecated " + "and will be removed in a future version. Use ISO format " + f"(YYYY-MM-DD) instead. Got '{start}'." + ) + warnings.warn(msg, Pandas4Warning, stacklevel=find_stack_level()) + start_casted = self._maybe_cast_slice_bound(start, "left") mask = start_casted <= self in_index &= (start_casted == self).any() if end is not None: + # GH#58302 - Deprecate non-ISO string formats in .loc indexing + if isinstance(end, str) and not _is_iso_format_string(end): + msg = ( + "Parsing non-ISO datetime strings in .loc is deprecated " + "and will be removed in a future version. Use ISO format " + f"(YYYY-MM-DD) instead. Got '{end}'." + ) + warnings.warn(msg, Pandas4Warning, stacklevel=find_stack_level()) + end_casted = self._maybe_cast_slice_bound(end, "right") mask = (self <= end_casted) & mask in_index &= (end_casted == self).any() diff --git a/pandas/tests/indexes/datetimes/test_partial_slicing.py b/pandas/tests/indexes/datetimes/test_partial_slicing.py index 94175a56f1c4a..2643c3a5b0d34 100644 --- a/pandas/tests/indexes/datetimes/test_partial_slicing.py +++ b/pandas/tests/indexes/datetimes/test_partial_slicing.py @@ -5,6 +5,8 @@ import numpy as np import pytest +from pandas.errors import Pandas4Warning + from pandas import ( DataFrame, DatetimeIndex, @@ -464,3 +466,96 @@ def test_slice_reduce_to_series(self): ) result = df.loc["2000", "A"] tm.assert_series_equal(result, expected) + + +class TestDatetimeIndexNonISODeprecation: + """Tests for deprecation of non-ISO string formats in .loc indexing. GH#58302""" + + @pytest.fixture + def ser_daily(self): + """Create a Series with daily DatetimeIndex for testing.""" + return Series( + range(15), + index=DatetimeIndex(date_range(start="2024-01-01", freq="D", periods=15)), + ) + + @pytest.mark.parametrize( + "date_string", + [ + "1/10/2024", # MM/DD/YYYY format + "01/10/2024", # MM/DD/YYYY format with leading zero + ], + ) + def test_loc_indexing_non_iso_single_key_deprecation(self, ser_daily, date_string): + # GH#58302 + msg = "Parsing non-ISO datetime strings in .loc is deprecated" + + with tm.assert_produces_warning(Pandas4Warning, match=msg): + result = ser_daily.loc[date_string] + assert result == 9 + + @pytest.mark.parametrize( + "date_string,expected", + [ + ("2024-01-10", 9), # YYYY-MM-DD (dash) + ("2024/01/10", 9), # YYYY/MM/DD (slash) + ("2024 01 10", 9), # YYYY MM DD (space) + ], + ) + def test_loc_indexing_iso_format_no_warning(self, ser_daily, date_string, expected): + # GH#58302 - ISO formats should NOT warn + with tm.assert_produces_warning(None): + result = ser_daily.loc[date_string] + assert result == expected + + @pytest.mark.parametrize( + "start_string", + [ + "1/10/2024", # MM/DD/YYYY format + "01/10/2024", # MM/DD/YYYY format with leading zero + ], + ) + def test_loc_slicing_non_iso_start_deprecation(self, ser_daily, start_string): + # GH#58302 - Non-ISO start in slice should warn + msg = "Parsing non-ISO datetime strings in .loc is deprecated" + + with tm.assert_produces_warning(Pandas4Warning, match=msg): + result = ser_daily.loc[start_string:"2024-01-15"] + assert len(result) > 0 + + @pytest.mark.parametrize( + "end_string", + [ + "5-01-2024", # DD-MM-YYYY format + "05-01-2024", # DD-MM-YYYY format with leading zero + ], + ) + def test_loc_slicing_non_iso_end_deprecation(self, ser_daily, end_string): + # GH#58302 - Non-ISO end in slice should warn + msg = "Parsing non-ISO datetime strings in .loc is deprecated" + + with tm.assert_produces_warning(Pandas4Warning, match=msg): + result = ser_daily.loc["2024-01-01":end_string] + assert len(result) > 0 + + def test_loc_slicing_both_non_iso_deprecation(self, ser_daily): + # GH#58302 - Both non-ISO should warn (twice) + msg = "Parsing non-ISO datetime strings in .loc is deprecated" + + with tm.assert_produces_warning( + Pandas4Warning, match=msg, check_stacklevel=False + ): + result = ser_daily.loc["1/10/2024":"5-01-2024"] + assert len(result) > 0 + + def test_loc_slicing_iso_formats_no_warning(self, ser_daily): + # GH#58302 - ISO slice formats should NOT warn + with tm.assert_produces_warning(None): + result = ser_daily.loc["2024-01-05":"2024-01-10"] + assert len(result) == 6 + + def test_loc_non_string_keys_no_warning(self, ser_daily): + # GH#58302 - Non-string keys should not warn + with tm.assert_produces_warning(None): + result = ser_daily.loc[Timestamp("2024-01-10")] + assert result == 9 From dda23cc8f63607968a1cafa7a71030e0d28aa3a2 Mon Sep 17 00:00:00 2001 From: Raghavendranath Kandula Date: Tue, 4 Nov 2025 22:36:45 -0500 Subject: [PATCH 02/12] added a new line back to docs --- 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 102045c2427ca..b25a66bd2a69f 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -746,6 +746,7 @@ Other Deprecations - Deprecated slicing on a :class:`Series` or :class:`DataFrame` with a :class:`DatetimeIndex` using a ``datetime.date`` object, explicitly cast to :class:`Timestamp` instead (:issue:`35830`) - Deprecated support for the Dataframe Interchange Protocol (:issue:`56732`) - Deprecated the 'inplace' keyword from :meth:`Resampler.interpolate`, as passing ``True`` raises ``AttributeError`` (:issue:`58690`) + .. --------------------------------------------------------------------------- .. _whatsnew_300.prior_deprecations: From 6877feceea38f1054dd8f31a9615407d260d8955 Mon Sep 17 00:00:00 2001 From: Raghavendranath Kandula Date: Tue, 4 Nov 2025 23:49:43 -0500 Subject: [PATCH 03/12] moved the warnings after parsing --- pandas/core/indexes/datetimes.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 98e8a340cf60c..cf60f4d9edfe3 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -589,6 +589,8 @@ def _parsed_string_to_bounds( return start, end def _parse_with_reso(self, label: str) -> tuple[Timestamp, Resolution]: + parsed, reso = super()._parse_with_reso(label) + # GH#58302 - Deprecate non-ISO string formats in .loc indexing if isinstance(label, str) and not _is_iso_format_string(label): msg = ( @@ -598,8 +600,6 @@ def _parse_with_reso(self, label: str) -> tuple[Timestamp, Resolution]: ) warnings.warn(msg, Pandas4Warning, stacklevel=find_stack_level()) - parsed, reso = super()._parse_with_reso(label) - parsed = Timestamp(parsed) if self.tz is not None and parsed.tzinfo is None: @@ -733,6 +733,8 @@ def check_str_or_none(point) -> bool: mask = np.array(True) in_index = True if start is not None: + start_casted = self._maybe_cast_slice_bound(start, "left") + # GH#58302 - Deprecate non-ISO string formats in .loc indexing if isinstance(start, str) and not _is_iso_format_string(start): msg = ( @@ -742,11 +744,12 @@ def check_str_or_none(point) -> bool: ) warnings.warn(msg, Pandas4Warning, stacklevel=find_stack_level()) - start_casted = self._maybe_cast_slice_bound(start, "left") mask = start_casted <= self in_index &= (start_casted == self).any() if end is not None: + end_casted = self._maybe_cast_slice_bound(end, "right") + # GH#58302 - Deprecate non-ISO string formats in .loc indexing if isinstance(end, str) and not _is_iso_format_string(end): msg = ( @@ -756,7 +759,6 @@ def check_str_or_none(point) -> bool: ) warnings.warn(msg, Pandas4Warning, stacklevel=find_stack_level()) - end_casted = self._maybe_cast_slice_bound(end, "right") mask = (self <= end_casted) & mask in_index &= (end_casted == self).any() From c0bda6e8c035e500dd96d8da366b24b9c591a7f3 Mon Sep 17 00:00:00 2001 From: Raghavendranath Kandula Date: Wed, 5 Nov 2025 00:44:09 -0500 Subject: [PATCH 04/12] fix: only warn on non-ISO formats in .loc indexing paths --- pandas/core/indexes/datetimes.py | 17 ++++++++--------- pandas/tests/groupby/test_groupby.py | 7 ++++++- pandas/tests/indexes/datetimes/test_indexing.py | 4 ++++ .../indexes/datetimes/test_partial_slicing.py | 4 ++++ .../indexes/multi/test_partial_indexing.py | 4 ++++ pandas/tests/indexes/period/test_indexing.py | 4 ++++ .../indexes/period/test_partial_slicing.py | 4 ++++ pandas/tests/indexing/multiindex/test_slice.py | 4 ++++ pandas/tests/indexing/test_loc.py | 4 ++++ pandas/tests/resample/test_datetime_index.py | 4 ++++ pandas/tests/resample/test_resampler_grouper.py | 4 ++++ pandas/tests/series/indexing/test_datetime.py | 4 ++++ pandas/tests/series/indexing/test_getitem.py | 4 ++++ pandas/tests/series/indexing/test_xs.py | 4 ++++ 14 files changed, 62 insertions(+), 10 deletions(-) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index cf60f4d9edfe3..21ab81ab133dd 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -591,15 +591,6 @@ def _parsed_string_to_bounds( def _parse_with_reso(self, label: str) -> tuple[Timestamp, Resolution]: parsed, reso = super()._parse_with_reso(label) - # GH#58302 - Deprecate non-ISO string formats in .loc indexing - if isinstance(label, str) and not _is_iso_format_string(label): - msg = ( - "Parsing non-ISO datetime strings in .loc is deprecated and will be " - "removed in a future version. Use ISO format (YYYY-MM-DD) instead. " - f"Got '{label}'." - ) - warnings.warn(msg, Pandas4Warning, stacklevel=find_stack_level()) - parsed = Timestamp(parsed) if self.tz is not None and parsed.tzinfo is None: @@ -645,6 +636,14 @@ def get_loc(self, key): parsed, reso = self._parse_with_reso(key) except ValueError as err: raise KeyError(key) from err + # GH#58302 - Deprecate non-ISO string formats in .loc indexing + if not _is_iso_format_string(key): + msg = ( + "Parsing non-ISO datetime strings in .loc is deprecated " + "and will be removed in a future version. Use ISO format " + f"(YYYY-MM-DD) instead. Got '{key}'." + ) + warnings.warn(msg, Pandas4Warning, stacklevel=find_stack_level()) self._disallow_mismatched_indexing(parsed) if self._can_partial_date_slice(reso): diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index 4955b1fe0da54..2ba1126a64d63 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -28,7 +28,12 @@ from pandas.core.arrays import BooleanArray import pandas.core.common as com -pytestmark = pytest.mark.filterwarnings("ignore:Mean of empty slice:RuntimeWarning") +pytestmark = [ + pytest.mark.filterwarnings("ignore:Mean of empty slice:RuntimeWarning"), + pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" + ), +] def test_repr(): diff --git a/pandas/tests/indexes/datetimes/test_indexing.py b/pandas/tests/indexes/datetimes/test_indexing.py index 11877024e7be0..e0557fca6dfc0 100644 --- a/pandas/tests/indexes/datetimes/test_indexing.py +++ b/pandas/tests/indexes/datetimes/test_indexing.py @@ -26,6 +26,10 @@ from pandas.tseries.frequencies import to_offset +pytestmark = pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) + START, END = datetime(2009, 1, 1), datetime(2010, 1, 1) diff --git a/pandas/tests/indexes/datetimes/test_partial_slicing.py b/pandas/tests/indexes/datetimes/test_partial_slicing.py index 2643c3a5b0d34..a8a965d41f55d 100644 --- a/pandas/tests/indexes/datetimes/test_partial_slicing.py +++ b/pandas/tests/indexes/datetimes/test_partial_slicing.py @@ -19,6 +19,10 @@ ) import pandas._testing as tm +pytestmark = pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) + class TestSlicing: def test_string_index_series_name_converted(self): diff --git a/pandas/tests/indexes/multi/test_partial_indexing.py b/pandas/tests/indexes/multi/test_partial_indexing.py index 64cc1fa621b31..0d9b3b36eb955 100644 --- a/pandas/tests/indexes/multi/test_partial_indexing.py +++ b/pandas/tests/indexes/multi/test_partial_indexing.py @@ -9,6 +9,10 @@ ) import pandas._testing as tm +pytestmark = pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) + @pytest.fixture def df(): diff --git a/pandas/tests/indexes/period/test_indexing.py b/pandas/tests/indexes/period/test_indexing.py index 75382cb735288..7c147875ed796 100644 --- a/pandas/tests/indexes/period/test_indexing.py +++ b/pandas/tests/indexes/period/test_indexing.py @@ -21,6 +21,10 @@ ) import pandas._testing as tm +pytestmark = pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) + dti4 = date_range("2016-01-01", periods=4) dti = dti4[:-1] rng = pd.Index(range(3)) diff --git a/pandas/tests/indexes/period/test_partial_slicing.py b/pandas/tests/indexes/period/test_partial_slicing.py index 8d173d850583f..36b0720f59d83 100644 --- a/pandas/tests/indexes/period/test_partial_slicing.py +++ b/pandas/tests/indexes/period/test_partial_slicing.py @@ -10,6 +10,10 @@ ) import pandas._testing as tm +pytestmark = pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) + class TestPeriodIndex: def test_getitem_periodindex_duplicates_string_slice(self): diff --git a/pandas/tests/indexing/multiindex/test_slice.py b/pandas/tests/indexing/multiindex/test_slice.py index 7f298e9bdd375..f8ff922f06f55 100644 --- a/pandas/tests/indexing/multiindex/test_slice.py +++ b/pandas/tests/indexing/multiindex/test_slice.py @@ -19,6 +19,10 @@ import pandas._testing as tm from pandas.tests.indexing.common import _mklbl +pytestmark = pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) + class TestMultiIndexSlicers: def test_per_axis_per_level_getitem(self): diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index de2d914aab229..3144a80c9178a 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -44,6 +44,10 @@ from pandas.core.indexing import _one_ellipsis_message from pandas.tests.indexing.common import check_indexing_smoketest_or_raises +pytestmark = pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) + @pytest.mark.parametrize( "series, new_series, expected_ser", diff --git a/pandas/tests/resample/test_datetime_index.py b/pandas/tests/resample/test_datetime_index.py index 3cd7f6c336956..f10f43944bd9b 100644 --- a/pandas/tests/resample/test_datetime_index.py +++ b/pandas/tests/resample/test_datetime_index.py @@ -38,6 +38,10 @@ from pandas.tseries.frequencies import to_offset from pandas.tseries.offsets import Minute +pytestmark = pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) + @pytest.fixture def simple_date_range_series(): diff --git a/pandas/tests/resample/test_resampler_grouper.py b/pandas/tests/resample/test_resampler_grouper.py index f3c52a674cf66..e05a6c8550ab6 100644 --- a/pandas/tests/resample/test_resampler_grouper.py +++ b/pandas/tests/resample/test_resampler_grouper.py @@ -16,6 +16,10 @@ import pandas._testing as tm from pandas.core.indexes.datetimes import date_range +pytestmark = pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) + @pytest.fixture def test_frame(): diff --git a/pandas/tests/series/indexing/test_datetime.py b/pandas/tests/series/indexing/test_datetime.py index 97cafc33611ed..3a753983c663b 100644 --- a/pandas/tests/series/indexing/test_datetime.py +++ b/pandas/tests/series/indexing/test_datetime.py @@ -27,6 +27,10 @@ ) import pandas._testing as tm +pytestmark = pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) + def test_fancy_getitem(): dti = date_range( diff --git a/pandas/tests/series/indexing/test_getitem.py b/pandas/tests/series/indexing/test_getitem.py index 37d6c9b42e003..857cc99befa78 100644 --- a/pandas/tests/series/indexing/test_getitem.py +++ b/pandas/tests/series/indexing/test_getitem.py @@ -37,6 +37,10 @@ from pandas.tseries.offsets import BDay +pytestmark = pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) + class TestSeriesGetitemScalars: def test_getitem_object_index_float_string(self): diff --git a/pandas/tests/series/indexing/test_xs.py b/pandas/tests/series/indexing/test_xs.py index a67f3ec708f24..7120fae1a7a86 100644 --- a/pandas/tests/series/indexing/test_xs.py +++ b/pandas/tests/series/indexing/test_xs.py @@ -8,6 +8,10 @@ ) import pandas._testing as tm +pytestmark = pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) + def test_xs_datetimelike_wrapping(): # GH#31630 a case where we shouldn't wrap datetime64 in Timestamp From a627889bbedfda13974274f3ca4dace3094328c6 Mon Sep 17 00:00:00 2001 From: Raghavendranath Kandula Date: Wed, 5 Nov 2025 08:14:33 -0500 Subject: [PATCH 05/12] removed pytestmark in test_partial_slicing --- pandas/tests/indexes/datetimes/test_partial_slicing.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pandas/tests/indexes/datetimes/test_partial_slicing.py b/pandas/tests/indexes/datetimes/test_partial_slicing.py index a8a965d41f55d..01dc6c44e50b9 100644 --- a/pandas/tests/indexes/datetimes/test_partial_slicing.py +++ b/pandas/tests/indexes/datetimes/test_partial_slicing.py @@ -19,12 +19,12 @@ ) import pandas._testing as tm -pytestmark = pytest.mark.filterwarnings( - "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" -) - class TestSlicing: + pytestmark = pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" + ) + def test_string_index_series_name_converted(self): # GH#1644 df = DataFrame( From a14868e6e04d4be4ed6ee836aabd0d9d92e97988 Mon Sep 17 00:00:00 2001 From: Raghavendranath Kandula Date: Thu, 6 Nov 2025 00:22:48 -0500 Subject: [PATCH 06/12] Fix: Ensure non-ISO deprecation warnings trigger in slice_indexer and add test suppressions --- pandas/core/indexes/datetimes.py | 47 +++++++++---------- pandas/tests/groupby/test_groupby.py | 7 +-- .../tests/indexes/datetimes/test_indexing.py | 7 ++- .../indexes/datetimes/test_partial_slicing.py | 6 +-- .../indexes/multi/test_partial_indexing.py | 4 -- pandas/tests/indexes/period/test_indexing.py | 10 ++-- .../indexes/period/test_partial_slicing.py | 8 ++-- .../tests/indexing/multiindex/test_slice.py | 4 -- pandas/tests/indexing/test_loc.py | 4 -- pandas/tests/resample/test_datetime_index.py | 16 +++++-- .../tests/resample/test_resampler_grouper.py | 7 ++- pandas/tests/series/indexing/test_datetime.py | 8 ++-- pandas/tests/series/indexing/test_getitem.py | 10 ++-- pandas/tests/series/indexing/test_xs.py | 7 ++- 14 files changed, 68 insertions(+), 77 deletions(-) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 21ab81ab133dd..05a88198e9fbc 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -116,21 +116,22 @@ def _is_iso_format_string(date_str: str) -> bool: Check if a date string follows ISO8601 format. ISO format must start with a 4-digit year (YYYY), optionally followed by - month and day with consistent separators. + hyphen-separated month and day or 'T' for time component. Examples of ISO format (True): + - 2024 + - 2024-01 - 2024-01-10 - - 2024/01/10 - - 2024 01 10 - 2024-01-10T00:00:00 Examples of non-ISO format (False): + - 2024/01/10 (/ separator) + - 2024 01 10 (space separator) - 01/10/2024 (MM/DD/YYYY) - 10/01/2024 (DD/MM/YYYY) - 01-10-2024 (MM-DD-YYYY) """ - # ISO format must start with 4-digit year followed by separator (-, /, ., or space) - return re.match(r"^\d{4}[-/. ]", date_str) is not None + return re.match(r"^\d{4}(?:-|T|$)", date_str) is not None @inherit_names( @@ -722,6 +723,23 @@ def check_str_or_none(point) -> bool: # GH#33146 if start and end are combinations of str and None and Index is not # monotonic, we can not use Index.slice_indexer because it does not honor the # actual elements, is only searching for start and end + # GH#58302 - Deprecate non-ISO string formats in .loc indexing + if isinstance(start, str) and not _is_iso_format_string(start): + msg = ( + "Parsing non-ISO datetime strings in .loc is deprecated " + "and will be removed in a future version. Use ISO format " + f"(YYYY-MM-DD) instead. Got '{start}'." + ) + warnings.warn(msg, Pandas4Warning, stacklevel=find_stack_level()) + + if isinstance(end, str) and not _is_iso_format_string(end): + msg = ( + "Parsing non-ISO datetime strings in .loc is deprecated " + "and will be removed in a future version. Use ISO format " + f"(YYYY-MM-DD) instead. Got '{end}'." + ) + warnings.warn(msg, Pandas4Warning, stacklevel=find_stack_level()) + if ( check_str_or_none(start) or check_str_or_none(end) @@ -733,31 +751,12 @@ def check_str_or_none(point) -> bool: in_index = True if start is not None: start_casted = self._maybe_cast_slice_bound(start, "left") - - # GH#58302 - Deprecate non-ISO string formats in .loc indexing - if isinstance(start, str) and not _is_iso_format_string(start): - msg = ( - "Parsing non-ISO datetime strings in .loc is deprecated " - "and will be removed in a future version. Use ISO format " - f"(YYYY-MM-DD) instead. Got '{start}'." - ) - warnings.warn(msg, Pandas4Warning, stacklevel=find_stack_level()) - mask = start_casted <= self in_index &= (start_casted == self).any() if end is not None: end_casted = self._maybe_cast_slice_bound(end, "right") - # GH#58302 - Deprecate non-ISO string formats in .loc indexing - if isinstance(end, str) and not _is_iso_format_string(end): - msg = ( - "Parsing non-ISO datetime strings in .loc is deprecated " - "and will be removed in a future version. Use ISO format " - f"(YYYY-MM-DD) instead. Got '{end}'." - ) - warnings.warn(msg, Pandas4Warning, stacklevel=find_stack_level()) - mask = (self <= end_casted) & mask in_index &= (end_casted == self).any() diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index 2ba1126a64d63..4955b1fe0da54 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -28,12 +28,7 @@ from pandas.core.arrays import BooleanArray import pandas.core.common as com -pytestmark = [ - pytest.mark.filterwarnings("ignore:Mean of empty slice:RuntimeWarning"), - pytest.mark.filterwarnings( - "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" - ), -] +pytestmark = pytest.mark.filterwarnings("ignore:Mean of empty slice:RuntimeWarning") def test_repr(): diff --git a/pandas/tests/indexes/datetimes/test_indexing.py b/pandas/tests/indexes/datetimes/test_indexing.py index e0557fca6dfc0..fd0765dc3964f 100644 --- a/pandas/tests/indexes/datetimes/test_indexing.py +++ b/pandas/tests/indexes/datetimes/test_indexing.py @@ -26,10 +26,6 @@ from pandas.tseries.frequencies import to_offset -pytestmark = pytest.mark.filterwarnings( - "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" -) - START, END = datetime(2009, 1, 1), datetime(2010, 1, 1) @@ -493,6 +489,9 @@ def test_get_loc_timedelta_invalid_key(self, key): with pytest.raises(TypeError, match=msg): dti.get_loc(key) + @pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" + ) def test_get_loc_reasonable_key_error(self): # GH#1062 index = DatetimeIndex(["1/3/2000"]) diff --git a/pandas/tests/indexes/datetimes/test_partial_slicing.py b/pandas/tests/indexes/datetimes/test_partial_slicing.py index 01dc6c44e50b9..f12c958d22269 100644 --- a/pandas/tests/indexes/datetimes/test_partial_slicing.py +++ b/pandas/tests/indexes/datetimes/test_partial_slicing.py @@ -501,13 +501,11 @@ def test_loc_indexing_non_iso_single_key_deprecation(self, ser_daily, date_strin @pytest.mark.parametrize( "date_string,expected", [ - ("2024-01-10", 9), # YYYY-MM-DD (dash) - ("2024/01/10", 9), # YYYY/MM/DD (slash) - ("2024 01 10", 9), # YYYY MM DD (space) + ("2024-01-10", 9), # YYYY-MM-DD (ISO format) ], ) def test_loc_indexing_iso_format_no_warning(self, ser_daily, date_string, expected): - # GH#58302 - ISO formats should NOT warn + # GH#58302 - ISO format (YYYY-MM-DD) should NOT warn with tm.assert_produces_warning(None): result = ser_daily.loc[date_string] assert result == expected diff --git a/pandas/tests/indexes/multi/test_partial_indexing.py b/pandas/tests/indexes/multi/test_partial_indexing.py index 0d9b3b36eb955..64cc1fa621b31 100644 --- a/pandas/tests/indexes/multi/test_partial_indexing.py +++ b/pandas/tests/indexes/multi/test_partial_indexing.py @@ -9,10 +9,6 @@ ) import pandas._testing as tm -pytestmark = pytest.mark.filterwarnings( - "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" -) - @pytest.fixture def df(): diff --git a/pandas/tests/indexes/period/test_indexing.py b/pandas/tests/indexes/period/test_indexing.py index 7c147875ed796..7eaafd1bb8d72 100644 --- a/pandas/tests/indexes/period/test_indexing.py +++ b/pandas/tests/indexes/period/test_indexing.py @@ -21,10 +21,6 @@ ) import pandas._testing as tm -pytestmark = pytest.mark.filterwarnings( - "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" -) - dti4 = date_range("2016-01-01", periods=4) dti = dti4[:-1] rng = pd.Index(range(3)) @@ -176,6 +172,9 @@ def test_getitem_list_periods(self): tm.assert_series_equal(ts[[Period("2012-01-02", freq="D")]], exp) @pytest.mark.arm_slow + @pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" + ) def test_getitem_seconds(self): # GH#6716 didx = date_range(start="2013/01/01 09:00:00", freq="s", periods=4000) @@ -210,6 +209,9 @@ def test_getitem_seconds(self): period_range, ], ) + @pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" + ) def test_getitem_day(self, idx_range): # GH#6716 # Confirm DatetimeIndex and PeriodIndex works identically diff --git a/pandas/tests/indexes/period/test_partial_slicing.py b/pandas/tests/indexes/period/test_partial_slicing.py index 36b0720f59d83..58a6b3c2feef4 100644 --- a/pandas/tests/indexes/period/test_partial_slicing.py +++ b/pandas/tests/indexes/period/test_partial_slicing.py @@ -10,12 +10,12 @@ ) import pandas._testing as tm -pytestmark = pytest.mark.filterwarnings( - "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" -) - class TestPeriodIndex: + pytestmark = pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" + ) + def test_getitem_periodindex_duplicates_string_slice(self): # monotonic idx = PeriodIndex([2000, 2007, 2007, 2009, 2009], freq="Y-JUN") diff --git a/pandas/tests/indexing/multiindex/test_slice.py b/pandas/tests/indexing/multiindex/test_slice.py index f8ff922f06f55..7f298e9bdd375 100644 --- a/pandas/tests/indexing/multiindex/test_slice.py +++ b/pandas/tests/indexing/multiindex/test_slice.py @@ -19,10 +19,6 @@ import pandas._testing as tm from pandas.tests.indexing.common import _mklbl -pytestmark = pytest.mark.filterwarnings( - "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" -) - class TestMultiIndexSlicers: def test_per_axis_per_level_getitem(self): diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 3144a80c9178a..de2d914aab229 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -44,10 +44,6 @@ from pandas.core.indexing import _one_ellipsis_message from pandas.tests.indexing.common import check_indexing_smoketest_or_raises -pytestmark = pytest.mark.filterwarnings( - "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" -) - @pytest.mark.parametrize( "series, new_series, expected_ser", diff --git a/pandas/tests/resample/test_datetime_index.py b/pandas/tests/resample/test_datetime_index.py index f10f43944bd9b..ae3ff0adc6046 100644 --- a/pandas/tests/resample/test_datetime_index.py +++ b/pandas/tests/resample/test_datetime_index.py @@ -38,10 +38,6 @@ from pandas.tseries.frequencies import to_offset from pandas.tseries.offsets import Minute -pytestmark = pytest.mark.filterwarnings( - "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" -) - @pytest.fixture def simple_date_range_series(): @@ -331,6 +327,9 @@ def test_resample_rounding(unit): tm.assert_frame_equal(result, expected) +@pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) def test_resample_basic_from_daily(unit): # from daily dti = date_range( @@ -555,6 +554,9 @@ def test_resample_ohlc(unit): assert xs["close"] == s.iloc[4] +@pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) def test_resample_ohlc_result(unit): # GH 12332 index = date_range("1-1-2000", "2-15-2000", freq="h").as_unit(unit) @@ -666,6 +668,9 @@ def test_resample_timestamp_to_period( tm.assert_series_equal(result, expected) +@pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) def test_ohlc_5min(unit): def _ohlc(group): if isna(group).all(): @@ -1580,6 +1585,9 @@ def test_resample_dst_anchor(unit): ) +@pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) def test_resample_dst_anchor2(unit): dti = date_range( "2013-09-30", "2013-11-02", freq="30Min", tz="Europe/Paris" diff --git a/pandas/tests/resample/test_resampler_grouper.py b/pandas/tests/resample/test_resampler_grouper.py index e05a6c8550ab6..73be113cd1a15 100644 --- a/pandas/tests/resample/test_resampler_grouper.py +++ b/pandas/tests/resample/test_resampler_grouper.py @@ -16,10 +16,6 @@ import pandas._testing as tm from pandas.core.indexes.datetimes import date_range -pytestmark = pytest.mark.filterwarnings( - "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" -) - @pytest.fixture def test_frame(): @@ -138,6 +134,9 @@ def test_groupby_resample_on_api_with_getitem(): tm.assert_series_equal(result, exp) +@pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) def test_groupby_with_origin(): # GH 31809 diff --git a/pandas/tests/series/indexing/test_datetime.py b/pandas/tests/series/indexing/test_datetime.py index 3a753983c663b..be60633a5b051 100644 --- a/pandas/tests/series/indexing/test_datetime.py +++ b/pandas/tests/series/indexing/test_datetime.py @@ -27,11 +27,10 @@ ) import pandas._testing as tm -pytestmark = pytest.mark.filterwarnings( + +@pytest.mark.filterwarnings( "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" ) - - def test_fancy_getitem(): dti = date_range( freq="WOM-1FRI", start=datetime(2005, 1, 1), end=datetime(2010, 1, 1) @@ -50,6 +49,9 @@ def test_fancy_getitem(): ) +@pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) def test_fancy_setitem(): dti = date_range( freq="WOM-1FRI", start=datetime(2005, 1, 1), end=datetime(2010, 1, 1) diff --git a/pandas/tests/series/indexing/test_getitem.py b/pandas/tests/series/indexing/test_getitem.py index 857cc99befa78..300365f887661 100644 --- a/pandas/tests/series/indexing/test_getitem.py +++ b/pandas/tests/series/indexing/test_getitem.py @@ -37,10 +37,6 @@ from pandas.tseries.offsets import BDay -pytestmark = pytest.mark.filterwarnings( - "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" -) - class TestSeriesGetitemScalars: def test_getitem_object_index_float_string(self): @@ -151,6 +147,9 @@ def test_getitem_pydatetime_tz(self, tzstr): assert ts[time_pandas] == ts[time_datetime] @pytest.mark.parametrize("tz", ["US/Eastern", "dateutil/US/Eastern"]) + @pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" + ) def test_string_index_alias_tz_aware(self, tz): rng = date_range("1/1/2000", periods=10, tz=tz) ser = Series(np.random.default_rng(2).standard_normal(len(rng)), index=rng) @@ -237,6 +236,9 @@ def test_getitem_partial_str_slice_with_datetimeindex(self): tm.assert_series_equal(result, expected) + @pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" + ) def test_getitem_slice_strings_with_datetimeindex(self): idx = DatetimeIndex( ["1/1/2000", "1/2/2000", "1/2/2000", "1/3/2000", "1/4/2000"] diff --git a/pandas/tests/series/indexing/test_xs.py b/pandas/tests/series/indexing/test_xs.py index 7120fae1a7a86..780b3b0345fa3 100644 --- a/pandas/tests/series/indexing/test_xs.py +++ b/pandas/tests/series/indexing/test_xs.py @@ -8,10 +8,6 @@ ) import pandas._testing as tm -pytestmark = pytest.mark.filterwarnings( - "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" -) - def test_xs_datetimelike_wrapping(): # GH#31630 a case where we shouldn't wrap datetime64 in Timestamp @@ -50,6 +46,9 @@ def test_series_getitem_multiindex_xs_by_label(self): result = ser.xs("one", level="L2") tm.assert_series_equal(result, expected) + @pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" + ) def test_series_getitem_multiindex_xs(self): # GH#6258 dt = list(date_range("20130903", periods=3)) From 714f65d16b6d65eceaed50e8e6305d9c93477102 Mon Sep 17 00:00:00 2001 From: Raghavendranath Kandula Date: Thu, 6 Nov 2025 00:39:35 -0500 Subject: [PATCH 07/12] updated comments --- pandas/core/indexes/datetimes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 05a88198e9fbc..f1055d3393aef 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -720,9 +720,6 @@ def slice_indexer(self, start=None, end=None, step=None): def check_str_or_none(point) -> bool: return point is not None and not isinstance(point, str) - # GH#33146 if start and end are combinations of str and None and Index is not - # monotonic, we can not use Index.slice_indexer because it does not honor the - # actual elements, is only searching for start and end # GH#58302 - Deprecate non-ISO string formats in .loc indexing if isinstance(start, str) and not _is_iso_format_string(start): msg = ( @@ -740,6 +737,9 @@ def check_str_or_none(point) -> bool: ) warnings.warn(msg, Pandas4Warning, stacklevel=find_stack_level()) + # GH#33146 if start and end are combinations of str and None and Index is not + # monotonic, we can not use Index.slice_indexer because it does not honor the + # actual elements, is only searching for start and end if ( check_str_or_none(start) or check_str_or_none(end) From 3421823f357f4d89914c36251d6d72e70caa6381 Mon Sep 17 00:00:00 2001 From: Raghavendranath Kandula Date: Thu, 6 Nov 2025 00:51:07 -0500 Subject: [PATCH 08/12] Fix: Use ISO format date strings in documentation example --- doc/source/user_guide/10min.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/user_guide/10min.rst b/doc/source/user_guide/10min.rst index 438306f01772a..5fde35b3f29f8 100644 --- a/doc/source/user_guide/10min.rst +++ b/doc/source/user_guide/10min.rst @@ -226,7 +226,7 @@ For label slicing, both endpoints are *included*: .. ipython:: python - df.loc["20130102":"20130104", ["A", "B"]] + df.loc["2013-01-02":"2013-01-04", ["A", "B"]] Selecting a single row and column label returns a scalar: From 42c889add5ffb72c1f20fb2d691dd74d4c563e60 Mon Sep 17 00:00:00 2001 From: Raghavendranath Kandula Date: Thu, 6 Nov 2025 00:56:03 -0500 Subject: [PATCH 09/12] Fix: Add additional filter warnings to the failing tests --- pandas/tests/groupby/test_groupby.py | 3 +++ pandas/tests/indexing/multiindex/test_slice.py | 3 +++ pandas/tests/indexing/test_loc.py | 9 +++++++++ 3 files changed, 15 insertions(+) diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index 4955b1fe0da54..f5201dc4e94dc 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -2851,6 +2851,9 @@ def test_groupby_with_Time_Grouper(unit): tm.assert_frame_equal(result, expected_output) +@pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) def test_groupby_series_with_datetimeindex_month_name(): # GH 48509 s = Series([0, 1, 0], index=date_range("2022-01-01", periods=3), name="jan") diff --git a/pandas/tests/indexing/multiindex/test_slice.py b/pandas/tests/indexing/multiindex/test_slice.py index 7f298e9bdd375..14702891e5fd3 100644 --- a/pandas/tests/indexing/multiindex/test_slice.py +++ b/pandas/tests/indexing/multiindex/test_slice.py @@ -308,6 +308,9 @@ def test_multiindex_slicers_datetimelike(self): ] tm.assert_frame_equal(result, expected) + @pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" + ) def test_multiindex_slicers_edges(self): # GH 8132 # various edge cases diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index de2d914aab229..3d1131ffd57bc 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -261,6 +261,9 @@ def test_loc_getitem_single_boolean_arg(self, obj, key, exp): class TestLocBaseIndependent: # Tests for loc that do not depend on subclassing Base + @pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" + ) def test_loc_npstr(self): # GH#45580 df = DataFrame(index=date_range("2021", "2022")) @@ -1262,6 +1265,9 @@ def test_loc_setitem_str_to_small_float_conversion_type(self, using_infer_string expected = DataFrame(col_data, columns=["A"], dtype=float) tm.assert_frame_equal(result, expected) + @pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" + ) def test_loc_getitem_time_object(self, frame_or_series): rng = date_range("1/1/2000", "1/5/2000", freq="5min") mask = (rng.hour == 9) & (rng.minute == 30) @@ -2415,6 +2421,9 @@ def test_loc_getitem_partial_slice_non_monotonicity( class TestLabelSlicing: + @pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" + ) def test_loc_getitem_slicing_datetimes_frame(self): # GH#7523 From b35ec26fffa25aca13e90a6ca10f2e904e17178d Mon Sep 17 00:00:00 2001 From: Raghavendranath Kandula Date: Thu, 6 Nov 2025 02:14:56 -0500 Subject: [PATCH 10/12] Fix: Add filterwarnings to test_series_groupby_value_counts --- pandas/tests/groupby/methods/test_value_counts.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandas/tests/groupby/methods/test_value_counts.py b/pandas/tests/groupby/methods/test_value_counts.py index 519c2c3064e59..7ba0c0cd6bf46 100644 --- a/pandas/tests/groupby/methods/test_value_counts.py +++ b/pandas/tests/groupby/methods/test_value_counts.py @@ -72,6 +72,9 @@ def seed_df(seed_nans, n, m): @pytest.mark.parametrize("bins", [None, [0, 5]], ids=repr) @pytest.mark.parametrize("isort", [True, False]) @pytest.mark.parametrize("normalize, name", [(True, "proportion"), (False, "count")]) +@pytest.mark.filterwarnings( + "ignore:Parsing non-ISO datetime strings:pandas.errors.Pandas4Warning" +) def test_series_groupby_value_counts( seed_nans, num_rows, From f8c72a8a8493d695b64b9572b038852100f6c47d Mon Sep 17 00:00:00 2001 From: Raghavendranath Kandula Date: Thu, 6 Nov 2025 08:14:59 -0500 Subject: [PATCH 11/12] fixing the doc upload warnings --- doc/source/user_guide/10min.rst | 2 +- doc/source/user_guide/indexing.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/user_guide/10min.rst b/doc/source/user_guide/10min.rst index 5fde35b3f29f8..cb6dc84be896c 100644 --- a/doc/source/user_guide/10min.rst +++ b/doc/source/user_guide/10min.rst @@ -203,7 +203,7 @@ For a :class:`DataFrame`, passing a slice ``:`` selects matching rows: .. ipython:: python df[0:3] - df["20130102":"20130104"] + df["2013-01-02":"2013-01-04"] Selection by label ~~~~~~~~~~~~~~~~~~ diff --git a/doc/source/user_guide/indexing.rst b/doc/source/user_guide/indexing.rst index ebd1791c0f4ad..c2251f0f94191 100644 --- a/doc/source/user_guide/indexing.rst +++ b/doc/source/user_guide/indexing.rst @@ -314,7 +314,7 @@ Selection by label .. ipython:: python - dfl.loc['20130102':'20130104'] + dfl.loc['2013-01-02':'2013-01-04'] pandas provides a suite of methods in order to have **purely label based indexing**. This is a strict inclusion based protocol. Every label asked for must be in the index, or a ``KeyError`` will be raised. From 415367c6bb5c2c4fceab4ffccf2d802af15644d6 Mon Sep 17 00:00:00 2001 From: Raghavendranath Kandula Date: Thu, 6 Nov 2025 08:16:54 -0500 Subject: [PATCH 12/12] removed extra line in datetimes.py --- pandas/core/indexes/datetimes.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index f1055d3393aef..14a7af2143fd2 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -756,7 +756,6 @@ def check_str_or_none(point) -> bool: if end is not None: end_casted = self._maybe_cast_slice_bound(end, "right") - mask = (self <= end_casted) & mask in_index &= (end_casted == self).any()