From 715fa9c4ca7b3f0863bef2346dc6e426bbf38574 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Wed, 17 Dec 2025 13:44:31 +0100 Subject: [PATCH 01/10] clarify-error-message-slice-bound-non-monotonic-index-without-specifying-the-label --- pandas/core/indexes/base.py | 7 +++++-- pandas/tests/series/indexing/test_indexing.py | 10 ++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 3239621468c5a..bec0b7d4868a5 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -6868,8 +6868,11 @@ def get_slice_bound(self, label, side: Literal["left", "right"]) -> int: try: return self._searchsorted_monotonic(label, side) except ValueError: - # raise the original KeyError - raise err from None + raise KeyError( + f"Cannot get {side} slice bound for non-monotonic index " + f"with a non-specific label: {original_label!r}. " + "Please specify the label." + ) from err if isinstance(slc, np.ndarray): # get_loc may return a boolean array, which diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py index 32ca3f1ba11c3..bb38632e4ff61 100644 --- a/pandas/tests/series/indexing/test_indexing.py +++ b/pandas/tests/series/indexing/test_indexing.py @@ -404,6 +404,16 @@ def test_setitem_empty_indexer(indexer, val): tm.assert_frame_equal(df, expected) +def test_loc_non_monotonic_index_with_non_specific_label(): + msg = ( + "Cannot get left slice bound for non-monotonic " + "index with a non-specific label: 4" + ) + ser = Series([3, 6, 7, 6], index=[3, 8, 7, 6]) + with pytest.raises(KeyError, match=msg): + ser.loc[4:7] + + class TestDeprecatedIndexers: @pytest.mark.parametrize("key", [{1}, {1: 1}]) def test_getitem_dict_and_set_deprecated(self, key): From efa0017ab1e96844f99c7d06cf3f4a9ca185673f Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Wed, 17 Dec 2025 14:24:22 +0100 Subject: [PATCH 02/10] fix tests: update the error message --- pandas/tests/frame/indexing/test_indexing.py | 5 +++-- pandas/tests/indexes/numeric/test_indexing.py | 5 +++-- pandas/tests/indexing/test_loc.py | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/pandas/tests/frame/indexing/test_indexing.py b/pandas/tests/frame/indexing/test_indexing.py index d11c2ef8a3a3c..7d071dcf7a674 100644 --- a/pandas/tests/frame/indexing/test_indexing.py +++ b/pandas/tests/frame/indexing/test_indexing.py @@ -564,9 +564,10 @@ def test_getitem_setitem_integer_slice_keyerrors(self): # non-monotonic, raise KeyError df2 = df.iloc[list(range(5)) + list(range(5, 10))[::-1]] - with pytest.raises(KeyError, match=r"^3$"): + msg = "non-monotonic index with a non-specific label: 3" + with pytest.raises(KeyError, match=msg): df2.loc[3:11] - with pytest.raises(KeyError, match=r"^3$"): + with pytest.raises(KeyError, match=msg): df2.loc[3:11] = 0 def test_fancy_getitem_slice_mixed(self, float_frame, float_string_frame): diff --git a/pandas/tests/indexes/numeric/test_indexing.py b/pandas/tests/indexes/numeric/test_indexing.py index 2f37b15ca74f5..d5285cc1da51f 100644 --- a/pandas/tests/indexes/numeric/test_indexing.py +++ b/pandas/tests/indexes/numeric/test_indexing.py @@ -600,10 +600,11 @@ def test_slice_locs_na(self): def test_slice_locs_na_raises(self): index = Index([np.nan, 1, 2]) - with pytest.raises(KeyError, match="1.5"): + msg = "non-monotonic index with a non-specific label: 1.5" + with pytest.raises(KeyError, match=msg): index.slice_locs(start=1.5) - with pytest.raises(KeyError, match="1.5"): + with pytest.raises(KeyError, match=msg): index.slice_locs(end=1.5) diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 91111d0b1b0ea..6466039a47e7a 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -3162,9 +3162,10 @@ def test_loc_getitem_setitem_integer_slice_keyerrors(self): # non-monotonic, raise KeyError s2 = ser.iloc[list(range(5)) + list(range(9, 4, -1))] - with pytest.raises(KeyError, match=r"^3$"): + msg = "non-monotonic index with a non-specific label: 3" + with pytest.raises(KeyError, match=msg): s2.loc[3:11] - with pytest.raises(KeyError, match=r"^3$"): + with pytest.raises(KeyError, match=msg): s2.loc[3:11] = 0 def test_loc_getitem_iterator(self, string_series): From f71f627faf71604bd00ced88efebc04d3e17d3cf Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva <91160475+natmokval@users.noreply.github.com> Date: Thu, 18 Dec 2025 01:03:21 +0100 Subject: [PATCH 03/10] Update pandas/core/indexes/base.py Co-authored-by: Richard Shadrach <45562402+rhshadrach@users.noreply.github.com> --- pandas/core/indexes/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index bec0b7d4868a5..ee303d33a61f0 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -6870,8 +6870,8 @@ def get_slice_bound(self, label, side: Literal["left", "right"]) -> int: except ValueError: raise KeyError( f"Cannot get {side} slice bound for non-monotonic index " - f"with a non-specific label: {original_label!r}. " - "Please specify the label." + f"with a missing label {original_label!r}. " + "Either sort the index or specify an existing label." ) from err if isinstance(slc, np.ndarray): From 5e0948dbdfe25462e2ba845dfe4e552532a553f7 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva <91160475+natmokval@users.noreply.github.com> Date: Thu, 18 Dec 2025 01:06:08 +0100 Subject: [PATCH 04/10] Update pandas/core/indexes/base.py Co-authored-by: Richard Shadrach <45562402+rhshadrach@users.noreply.github.com> --- pandas/core/indexes/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index ee303d33a61f0..a13fcfe8f2981 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -6872,7 +6872,7 @@ def get_slice_bound(self, label, side: Literal["left", "right"]) -> int: f"Cannot get {side} slice bound for non-monotonic index " f"with a missing label {original_label!r}. " "Either sort the index or specify an existing label." - ) from err + ) from None if isinstance(slc, np.ndarray): # get_loc may return a boolean array, which From af88c20dd3051dd8ab4f185c0eba6414535d653d Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva <91160475+natmokval@users.noreply.github.com> Date: Thu, 18 Dec 2025 01:24:08 +0100 Subject: [PATCH 05/10] Update the error message in test_indexing.py --- pandas/tests/frame/indexing/test_indexing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/frame/indexing/test_indexing.py b/pandas/tests/frame/indexing/test_indexing.py index 7d071dcf7a674..2293ca375be70 100644 --- a/pandas/tests/frame/indexing/test_indexing.py +++ b/pandas/tests/frame/indexing/test_indexing.py @@ -564,7 +564,7 @@ def test_getitem_setitem_integer_slice_keyerrors(self): # non-monotonic, raise KeyError df2 = df.iloc[list(range(5)) + list(range(5, 10))[::-1]] - msg = "non-monotonic index with a non-specific label: 3" + msg = "non-monotonic index with a missing label 3" with pytest.raises(KeyError, match=msg): df2.loc[3:11] with pytest.raises(KeyError, match=msg): From 60b9e69e5a1d44a184a8e2c9cf08c6e307e45275 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva <91160475+natmokval@users.noreply.github.com> Date: Thu, 18 Dec 2025 01:25:43 +0100 Subject: [PATCH 06/10] Update the error message in test_indexing.py --- pandas/tests/indexes/numeric/test_indexing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/indexes/numeric/test_indexing.py b/pandas/tests/indexes/numeric/test_indexing.py index d5285cc1da51f..0a88f55b06af8 100644 --- a/pandas/tests/indexes/numeric/test_indexing.py +++ b/pandas/tests/indexes/numeric/test_indexing.py @@ -600,7 +600,7 @@ def test_slice_locs_na(self): def test_slice_locs_na_raises(self): index = Index([np.nan, 1, 2]) - msg = "non-monotonic index with a non-specific label: 1.5" + msg = "non-monotonic index with a missing label 1.5" with pytest.raises(KeyError, match=msg): index.slice_locs(start=1.5) From a0e800a7db743866ab78b4e79ed32d576f34a189 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva <91160475+natmokval@users.noreply.github.com> Date: Thu, 18 Dec 2025 01:28:33 +0100 Subject: [PATCH 07/10] Update the error message in test_loc.py --- pandas/tests/indexing/test_loc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 6466039a47e7a..372120362b5d6 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -3162,7 +3162,7 @@ def test_loc_getitem_setitem_integer_slice_keyerrors(self): # non-monotonic, raise KeyError s2 = ser.iloc[list(range(5)) + list(range(9, 4, -1))] - msg = "non-monotonic index with a non-specific label: 3" + msg = "non-monotonic index with a missing label 3" with pytest.raises(KeyError, match=msg): s2.loc[3:11] with pytest.raises(KeyError, match=msg): From 976ea803d5ba58b6e6b51a1cb7d918a9ace67a03 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva <91160475+natmokval@users.noreply.github.com> Date: Thu, 18 Dec 2025 01:30:18 +0100 Subject: [PATCH 08/10] Update the error message in test_indexing.py --- pandas/tests/series/indexing/test_indexing.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py index bb38632e4ff61..35544fe146beb 100644 --- a/pandas/tests/series/indexing/test_indexing.py +++ b/pandas/tests/series/indexing/test_indexing.py @@ -404,11 +404,8 @@ def test_setitem_empty_indexer(indexer, val): tm.assert_frame_equal(df, expected) -def test_loc_non_monotonic_index_with_non_specific_label(): - msg = ( - "Cannot get left slice bound for non-monotonic " - "index with a non-specific label: 4" - ) +def test_loc_non_monotonic_index_with_missing_label(): + msg = "Cannot get left slice bound for non-monotonic index with a missing label 4" ser = Series([3, 6, 7, 6], index=[3, 8, 7, 6]) with pytest.raises(KeyError, match=msg): ser.loc[4:7] From 5a92312800e358682a403a145db78f990ed380a5 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Thu, 18 Dec 2025 02:18:25 +0100 Subject: [PATCH 09/10] rename the test --- pandas/tests/series/indexing/test_indexing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py index 35544fe146beb..bffdae5977c23 100644 --- a/pandas/tests/series/indexing/test_indexing.py +++ b/pandas/tests/series/indexing/test_indexing.py @@ -404,7 +404,7 @@ def test_setitem_empty_indexer(indexer, val): tm.assert_frame_equal(df, expected) -def test_loc_non_monotonic_index_with_missing_label(): +def test_loc_non_monotonic_index_with_a_missing_label(): msg = "Cannot get left slice bound for non-monotonic index with a missing label 4" ser = Series([3, 6, 7, 6], index=[3, 8, 7, 6]) with pytest.raises(KeyError, match=msg): From eb5b148fa66e1e6b9896f284629633fdab6c7a0e Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva <91160475+natmokval@users.noreply.github.com> Date: Thu, 18 Dec 2025 12:57:17 +0100 Subject: [PATCH 10/10] Update pandas/core/indexes/base.py Co-authored-by: Joris Van den Bossche --- pandas/core/indexes/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index fa9f409ff7aab..f73fe77defc26 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -6865,7 +6865,7 @@ def get_slice_bound(self, label, side: Literal["left", "right"]) -> int: # we need to look up the label try: slc = self.get_loc(label) - except KeyError as err: + except KeyError: try: return self._searchsorted_monotonic(label, side) except ValueError: