From c3cf9a136e41cbac78730e1a0cbda4bd586696db Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Mon, 25 Mar 2024 23:51:06 +0100 Subject: [PATCH 01/11] cln-remove-unnecessary-check-needs_i8_conversion --- pandas/core/indexes/base.py | 9 ++------- pandas/tests/indexes/test_base.py | 19 +++++++++++-------- pandas/tests/indexes/test_old_base.py | 16 ++++++++++++---- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 9a537c71f3cd0..2c220802c87e6 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -6960,14 +6960,9 @@ def _maybe_disable_logical_methods(self, opname: str_t) -> None: """ raise if this Index subclass does not support any or all. """ - if ( - isinstance(self, ABCMultiIndex) - # TODO(3.0): PeriodArray and DatetimeArray any/all will raise, - # so checking needs_i8_conversion will be unnecessary - or (needs_i8_conversion(self.dtype) and self.dtype.kind != "m") - ): - # This call will raise + if isinstance(self, ABCMultiIndex) or self.dtype.kind != "m": make_invalid_op(opname)(self) + raise TypeError("cannot perform all with this index type: Index") @Appender(IndexOpsMixin.argmin.__doc__) def argmin(self, axis=None, skipna: bool = True, *args, **kwargs) -> int: diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index beee14197bfb8..0e726a5f47731 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -688,12 +688,12 @@ def test_summary(self, index): def test_logical_compat(self, all_boolean_reductions, simple_index): index = simple_index - left = getattr(index, all_boolean_reductions)() - assert left == getattr(index.values, all_boolean_reductions)() - right = getattr(index.to_series(), all_boolean_reductions)() - # left might not match right exactly in e.g. string cases where the - # because we use np.any/all instead of .any/all - assert bool(left) == bool(right) + msg = f"cannot perform {all_boolean_reductions} with this index type: Index" + + with pytest.raises(TypeError, match=msg): + getattr(index, all_boolean_reductions)() + getattr(index.values, all_boolean_reductions)() + getattr(index.to_series(), all_boolean_reductions)() @pytest.mark.parametrize( "index", ["string", "int64", "int32", "float64", "float32"], indirect=True @@ -1393,8 +1393,11 @@ def test_unique_na(self): def test_logical_compat(self, simple_index): index = simple_index - assert index.all() == index.values.all() - assert index.any() == index.values.any() + msg = "cannot perform all with this index type: Index" + + with pytest.raises(TypeError, match=msg): + assert index.all() == index.values.all() + assert index.any() == index.values.any() @pytest.mark.parametrize("how", ["any", "all"]) @pytest.mark.parametrize("dtype", [None, object, "category"]) diff --git a/pandas/tests/indexes/test_old_base.py b/pandas/tests/indexes/test_old_base.py index 85eec7b7c018d..8f0846d8e0557 100644 --- a/pandas/tests/indexes/test_old_base.py +++ b/pandas/tests/indexes/test_old_base.py @@ -216,11 +216,19 @@ def test_logical_compat(self, simple_index): if simple_index.dtype in (object, "string"): pytest.skip("Tested elsewhere.") idx = simple_index + if idx.dtype.kind in "iufcbm": - assert idx.all() == idx._values.all() - assert idx.all() == idx.to_series().all() - assert idx.any() == idx._values.any() - assert idx.any() == idx.to_series().any() + msg = "cannot perform all with this index type: Index" + + with pytest.raises(TypeError, match=msg): + assert idx.all() == idx._values.all() + assert idx.all() == idx.to_series().all() + + msg = "cannot perform any with this index type: Index" + + with pytest.raises(TypeError, match=msg): + assert idx.any() == idx._values.any() + assert idx.any() == idx.to_series().any() else: msg = "cannot perform (any|all)" if isinstance(idx, IntervalIndex): From 54983c5517a66d49e204a1f773fdfd09eb0aa162 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Tue, 26 Mar 2024 01:23:56 +0100 Subject: [PATCH 02/11] fix tests --- pandas/core/indexes/base.py | 2 -- pandas/tests/indexes/numeric/test_numeric.py | 21 ++++++++++----- pandas/tests/indexes/test_base.py | 4 +-- pandas/tests/indexes/test_old_base.py | 28 ++++++++------------ 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 2c220802c87e6..5ad508d9bd226 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -179,7 +179,6 @@ ) from pandas.core.missing import clean_reindex_fill_method from pandas.core.ops import get_op_result_name -from pandas.core.ops.invalid import make_invalid_op from pandas.core.sorting import ( ensure_key_mapped, get_group_index_sorter, @@ -6961,7 +6960,6 @@ def _maybe_disable_logical_methods(self, opname: str_t) -> None: raise if this Index subclass does not support any or all. """ if isinstance(self, ABCMultiIndex) or self.dtype.kind != "m": - make_invalid_op(opname)(self) raise TypeError("cannot perform all with this index type: Index") @Appender(IndexOpsMixin.argmin.__doc__) diff --git a/pandas/tests/indexes/numeric/test_numeric.py b/pandas/tests/indexes/numeric/test_numeric.py index 4416034795463..128539983c33d 100644 --- a/pandas/tests/indexes/numeric/test_numeric.py +++ b/pandas/tests/indexes/numeric/test_numeric.py @@ -223,11 +223,14 @@ def test_fillna_float64(self): def test_logical_compat(self, dtype): idx = Index(np.arange(5, dtype=dtype)) - assert idx.all() == idx.values.all() - assert idx.any() == idx.values.any() + msg = "cannot perform all with this index type: Index" - assert idx.all() == idx.to_series().all() - assert idx.any() == idx.to_series().any() + with pytest.raises(TypeError, match=msg): + assert idx.all() == idx.values.all() + assert idx.any() == idx.values.any() + + assert idx.all() == idx.to_series().all() + assert idx.any() == idx.to_series().any() class TestNumericInt: @@ -278,10 +281,14 @@ def test_is_strictly_monotonic(self): assert not index._is_strictly_monotonic_increasing assert not index._is_strictly_monotonic_decreasing - def test_logical_compat(self, simple_index): + def test_logical_compat(self, simple_index, request): idx = simple_index - assert idx.all() == idx.values.all() - assert idx.any() == idx.values.any() + msg = "cannot perform all with this index type: Index" + + if request.node.callspec.id not in ["int", "int64"]: + with pytest.raises(TypeError, match=msg): + assert idx.all() == idx.values.all() + assert idx.any() == idx.values.any() def test_identical(self, simple_index, dtype): index = simple_index diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index 0e726a5f47731..f0c67111a8a0c 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -688,7 +688,7 @@ def test_summary(self, index): def test_logical_compat(self, all_boolean_reductions, simple_index): index = simple_index - msg = f"cannot perform {all_boolean_reductions} with this index type: Index" + msg = "cannot perform (any|all) with this index type: Index" with pytest.raises(TypeError, match=msg): getattr(index, all_boolean_reductions)() @@ -1393,7 +1393,7 @@ def test_unique_na(self): def test_logical_compat(self, simple_index): index = simple_index - msg = "cannot perform all with this index type: Index" + msg = "cannot perform (any|all) with this index type: Index" with pytest.raises(TypeError, match=msg): assert index.all() == index.values.all() diff --git a/pandas/tests/indexes/test_old_base.py b/pandas/tests/indexes/test_old_base.py index 8f0846d8e0557..ce8345bc50eb7 100644 --- a/pandas/tests/indexes/test_old_base.py +++ b/pandas/tests/indexes/test_old_base.py @@ -212,30 +212,24 @@ def test_numeric_compat(self, simple_index): with pytest.raises(TypeError, match=floordiv_err): 1 // idx - def test_logical_compat(self, simple_index): + def test_logical_compat(self, simple_index, request): if simple_index.dtype in (object, "string"): pytest.skip("Tested elsewhere.") idx = simple_index if idx.dtype.kind in "iufcbm": - msg = "cannot perform all with this index type: Index" - - with pytest.raises(TypeError, match=msg): - assert idx.all() == idx._values.all() - assert idx.all() == idx.to_series().all() - - msg = "cannot perform any with this index type: Index" - - with pytest.raises(TypeError, match=msg): - assert idx.any() == idx._values.any() - assert idx.any() == idx.to_series().any() + msg = "cannot perform (any|all) with this index type: Index" + + if request.node.callspec.id in [ + "".join(["simple_index", t]) for t in ["1", "2", "3", "5", "6", "7"] + ]: + with pytest.raises(TypeError, match=msg): + assert idx.all() == idx._values.all() + assert idx.all() == idx.to_series().all() + assert idx.any() == idx._values.any() + assert idx.any() == idx.to_series().any() else: msg = "cannot perform (any|all)" - if isinstance(idx, IntervalIndex): - msg = ( - r"'IntervalArray' with dtype interval\[.*\] does " - "not support reduction '(any|all)'" - ) with pytest.raises(TypeError, match=msg): idx.all() with pytest.raises(TypeError, match=msg): From 3b2242fe2ad9d754dba0764e99e6d14f43eb88d5 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Tue, 26 Mar 2024 15:02:39 +0100 Subject: [PATCH 03/11] remove the check self.dtype.kind, fix tests --- pandas/core/indexes/base.py | 4 +-- pandas/tests/indexes/numeric/test_numeric.py | 21 +++++--------- pandas/tests/indexes/test_base.py | 19 ++++++------- pandas/tests/indexes/test_old_base.py | 29 ++++++++++++-------- 4 files changed, 34 insertions(+), 39 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 5ad508d9bd226..7d32b299530db 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -6959,8 +6959,8 @@ def _maybe_disable_logical_methods(self, opname: str_t) -> None: """ raise if this Index subclass does not support any or all. """ - if isinstance(self, ABCMultiIndex) or self.dtype.kind != "m": - raise TypeError("cannot perform all with this index type: Index") + if isinstance(self, ABCMultiIndex): + raise TypeError(f"cannot perform {opname} with this index type: Index") @Appender(IndexOpsMixin.argmin.__doc__) def argmin(self, axis=None, skipna: bool = True, *args, **kwargs) -> int: diff --git a/pandas/tests/indexes/numeric/test_numeric.py b/pandas/tests/indexes/numeric/test_numeric.py index 128539983c33d..4416034795463 100644 --- a/pandas/tests/indexes/numeric/test_numeric.py +++ b/pandas/tests/indexes/numeric/test_numeric.py @@ -223,14 +223,11 @@ def test_fillna_float64(self): def test_logical_compat(self, dtype): idx = Index(np.arange(5, dtype=dtype)) - msg = "cannot perform all with this index type: Index" + assert idx.all() == idx.values.all() + assert idx.any() == idx.values.any() - with pytest.raises(TypeError, match=msg): - assert idx.all() == idx.values.all() - assert idx.any() == idx.values.any() - - assert idx.all() == idx.to_series().all() - assert idx.any() == idx.to_series().any() + assert idx.all() == idx.to_series().all() + assert idx.any() == idx.to_series().any() class TestNumericInt: @@ -281,14 +278,10 @@ def test_is_strictly_monotonic(self): assert not index._is_strictly_monotonic_increasing assert not index._is_strictly_monotonic_decreasing - def test_logical_compat(self, simple_index, request): + def test_logical_compat(self, simple_index): idx = simple_index - msg = "cannot perform all with this index type: Index" - - if request.node.callspec.id not in ["int", "int64"]: - with pytest.raises(TypeError, match=msg): - assert idx.all() == idx.values.all() - assert idx.any() == idx.values.any() + assert idx.all() == idx.values.all() + assert idx.any() == idx.values.any() def test_identical(self, simple_index, dtype): index = simple_index diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index f0c67111a8a0c..beee14197bfb8 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -688,12 +688,12 @@ def test_summary(self, index): def test_logical_compat(self, all_boolean_reductions, simple_index): index = simple_index - msg = "cannot perform (any|all) with this index type: Index" - - with pytest.raises(TypeError, match=msg): - getattr(index, all_boolean_reductions)() - getattr(index.values, all_boolean_reductions)() - getattr(index.to_series(), all_boolean_reductions)() + left = getattr(index, all_boolean_reductions)() + assert left == getattr(index.values, all_boolean_reductions)() + right = getattr(index.to_series(), all_boolean_reductions)() + # left might not match right exactly in e.g. string cases where the + # because we use np.any/all instead of .any/all + assert bool(left) == bool(right) @pytest.mark.parametrize( "index", ["string", "int64", "int32", "float64", "float32"], indirect=True @@ -1393,11 +1393,8 @@ def test_unique_na(self): def test_logical_compat(self, simple_index): index = simple_index - msg = "cannot perform (any|all) with this index type: Index" - - with pytest.raises(TypeError, match=msg): - assert index.all() == index.values.all() - assert index.any() == index.values.any() + assert index.all() == index.values.all() + assert index.any() == index.values.any() @pytest.mark.parametrize("how", ["any", "all"]) @pytest.mark.parametrize("dtype", [None, object, "category"]) diff --git a/pandas/tests/indexes/test_old_base.py b/pandas/tests/indexes/test_old_base.py index ce8345bc50eb7..1e6e563fda3b5 100644 --- a/pandas/tests/indexes/test_old_base.py +++ b/pandas/tests/indexes/test_old_base.py @@ -212,24 +212,29 @@ def test_numeric_compat(self, simple_index): with pytest.raises(TypeError, match=floordiv_err): 1 // idx - def test_logical_compat(self, simple_index, request): + def test_logical_compat(self, simple_index): if simple_index.dtype in (object, "string"): pytest.skip("Tested elsewhere.") idx = simple_index - if idx.dtype.kind in "iufcbm": - msg = "cannot perform (any|all) with this index type: Index" - - if request.node.callspec.id in [ - "".join(["simple_index", t]) for t in ["1", "2", "3", "5", "6", "7"] - ]: - with pytest.raises(TypeError, match=msg): - assert idx.all() == idx._values.all() - assert idx.all() == idx.to_series().all() - assert idx.any() == idx._values.any() - assert idx.any() == idx.to_series().any() + if isinstance(idx, DatetimeIndex): + msg = "'(any|all)' with datetime64 dtypes is deprecated" + with tm.assert_produces_warning(FutureWarning, match=msg): + idx.all() + elif idx.dtype.kind in "iufcbm": + assert idx.all() == idx._values.all() + assert idx.all() == idx.to_series().all() + assert idx.any() == idx._values.any() + assert idx.any() == idx.to_series().any() else: msg = "cannot perform (any|all)" + if isinstance(idx, IntervalIndex): + msg = ( + r"'IntervalArray' with dtype interval\[.*\] does " + "not support reduction '(any|all)'" + ) + if isinstance(idx, PeriodIndex): + msg = "does not support reduction '(any|all)'" with pytest.raises(TypeError, match=msg): idx.all() with pytest.raises(TypeError, match=msg): From c2535330079354fe018f3c6eab737872225fbd48 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva <91160475+natmokval@users.noreply.github.com> Date: Tue, 26 Mar 2024 23:21:28 +0100 Subject: [PATCH 04/11] Update pandas/core/indexes/base.py Co-authored-by: Matthew Roeschke <10647082+mroeschke@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 7d32b299530db..06ea4b87b35d8 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -6960,7 +6960,7 @@ def _maybe_disable_logical_methods(self, opname: str_t) -> None: raise if this Index subclass does not support any or all. """ if isinstance(self, ABCMultiIndex): - raise TypeError(f"cannot perform {opname} with this index type: Index") + raise TypeError(f"cannot perform {opname} with {type(self).__name__}") @Appender(IndexOpsMixin.argmin.__doc__) def argmin(self, axis=None, skipna: bool = True, *args, **kwargs) -> int: From 0b71ac1adc1ff175ed5f7b15524f02f1ef7fe17e Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Fri, 29 Mar 2024 21:28:57 +0100 Subject: [PATCH 05/11] combine two branches in test_logical_compat --- pandas/tests/indexes/test_old_base.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pandas/tests/indexes/test_old_base.py b/pandas/tests/indexes/test_old_base.py index 1e6e563fda3b5..e1860c3213fde 100644 --- a/pandas/tests/indexes/test_old_base.py +++ b/pandas/tests/indexes/test_old_base.py @@ -228,12 +228,7 @@ def test_logical_compat(self, simple_index): assert idx.any() == idx.to_series().any() else: msg = "cannot perform (any|all)" - if isinstance(idx, IntervalIndex): - msg = ( - r"'IntervalArray' with dtype interval\[.*\] does " - "not support reduction '(any|all)'" - ) - if isinstance(idx, PeriodIndex): + if isinstance(idx, IntervalIndex | PeriodIndex): msg = "does not support reduction '(any|all)'" with pytest.raises(TypeError, match=msg): idx.all() From add58c074091c5c4bdf782cd27fb98397c145c7a Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Fri, 29 Mar 2024 21:56:06 +0100 Subject: [PATCH 06/11] correct test_logical_compat --- pandas/tests/indexes/test_old_base.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pandas/tests/indexes/test_old_base.py b/pandas/tests/indexes/test_old_base.py index 185d1de5fb103..6790510f72a9f 100644 --- a/pandas/tests/indexes/test_old_base.py +++ b/pandas/tests/indexes/test_old_base.py @@ -217,11 +217,7 @@ def test_logical_compat(self, simple_index): pytest.skip("Tested elsewhere.") idx = simple_index - if isinstance(idx, DatetimeIndex): - msg = "'(any|all)' with datetime64 dtypes is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - idx.all() - elif idx.dtype.kind in "iufcbm": + if idx.dtype.kind in "iufcbm": assert idx.all() == idx._values.all() assert idx.all() == idx.to_series().all() assert idx.any() == idx._values.any() @@ -230,6 +226,8 @@ def test_logical_compat(self, simple_index): msg = "cannot perform (any|all)" if isinstance(idx, IntervalIndex | PeriodIndex): msg = "does not support reduction '(any|all)'" + if isinstance(idx, DatetimeIndex): + msg = "datetime64 type does not support operation: '(any|all)'" with pytest.raises(TypeError, match=msg): idx.all() with pytest.raises(TypeError, match=msg): From 18fab28276c13baf577ebe3ae76bbbf8bd1792f9 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Fri, 29 Mar 2024 23:17:36 +0100 Subject: [PATCH 07/11] correct test_logical_compat --- pandas/tests/indexes/test_old_base.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pandas/tests/indexes/test_old_base.py b/pandas/tests/indexes/test_old_base.py index 6790510f72a9f..1f7fdbc0f992c 100644 --- a/pandas/tests/indexes/test_old_base.py +++ b/pandas/tests/indexes/test_old_base.py @@ -216,7 +216,6 @@ def test_logical_compat(self, simple_index): if simple_index.dtype in (object, "string"): pytest.skip("Tested elsewhere.") idx = simple_index - if idx.dtype.kind in "iufcbm": assert idx.all() == idx._values.all() assert idx.all() == idx.to_series().all() @@ -224,10 +223,10 @@ def test_logical_compat(self, simple_index): assert idx.any() == idx.to_series().any() else: msg = "cannot perform (any|all)" - if isinstance(idx, IntervalIndex | PeriodIndex): - msg = "does not support reduction '(any|all)'" if isinstance(idx, DatetimeIndex): msg = "datetime64 type does not support operation: '(any|all)'" + else: + msg = "does not support reduction '(any|all)'" with pytest.raises(TypeError, match=msg): idx.all() with pytest.raises(TypeError, match=msg): From c887a859d936bb03288a6918d9b9e44fb84f1b10 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Mon, 1 Apr 2024 22:49:58 +0200 Subject: [PATCH 08/11] correct test_logical_compat --- pandas/tests/indexes/test_old_base.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pandas/tests/indexes/test_old_base.py b/pandas/tests/indexes/test_old_base.py index 1f7fdbc0f992c..cd6ddfdccd596 100644 --- a/pandas/tests/indexes/test_old_base.py +++ b/pandas/tests/indexes/test_old_base.py @@ -213,7 +213,7 @@ def test_numeric_compat(self, simple_index): 1 // idx def test_logical_compat(self, simple_index): - if simple_index.dtype in (object, "string"): + if simple_index.dtype in (object, "string", "datetime64[ns]"): pytest.skip("Tested elsewhere.") idx = simple_index if idx.dtype.kind in "iufcbm": @@ -222,11 +222,7 @@ def test_logical_compat(self, simple_index): assert idx.any() == idx._values.any() assert idx.any() == idx.to_series().any() else: - msg = "cannot perform (any|all)" - if isinstance(idx, DatetimeIndex): - msg = "datetime64 type does not support operation: '(any|all)'" - else: - msg = "does not support reduction '(any|all)'" + msg = "does not support reduction '(any|all)'" with pytest.raises(TypeError, match=msg): idx.all() with pytest.raises(TypeError, match=msg): From bac52c54fc983695e2224d99291720ea2bc33d1d Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Tue, 2 Apr 2024 18:26:00 +0200 Subject: [PATCH 09/11] roll back the check for datetime64 in test_logical_compat --- pandas/tests/indexes/test_old_base.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pandas/tests/indexes/test_old_base.py b/pandas/tests/indexes/test_old_base.py index cd6ddfdccd596..1f7fdbc0f992c 100644 --- a/pandas/tests/indexes/test_old_base.py +++ b/pandas/tests/indexes/test_old_base.py @@ -213,7 +213,7 @@ def test_numeric_compat(self, simple_index): 1 // idx def test_logical_compat(self, simple_index): - if simple_index.dtype in (object, "string", "datetime64[ns]"): + if simple_index.dtype in (object, "string"): pytest.skip("Tested elsewhere.") idx = simple_index if idx.dtype.kind in "iufcbm": @@ -222,7 +222,11 @@ def test_logical_compat(self, simple_index): assert idx.any() == idx._values.any() assert idx.any() == idx.to_series().any() else: - msg = "does not support reduction '(any|all)'" + msg = "cannot perform (any|all)" + if isinstance(idx, DatetimeIndex): + msg = "datetime64 type does not support operation: '(any|all)'" + else: + msg = "does not support reduction '(any|all)'" with pytest.raises(TypeError, match=msg): idx.all() with pytest.raises(TypeError, match=msg): From 6efebb874529ffd611d6ad5fcf81ba059f896201 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Thu, 4 Apr 2024 01:10:25 +0200 Subject: [PATCH 10/11] replace reduction with operation to unify err msg --- pandas/core/arrays/arrow/array.py | 2 +- pandas/core/arrays/base.py | 4 +- pandas/core/arrays/datetimelike.py | 2 +- pandas/core/nanops.py | 4 +- pandas/tests/apply/test_frame_apply.py | 6 +-- .../arrays/categorical/test_operators.py | 4 +- pandas/tests/arrays/test_datetimelike.py | 2 +- pandas/tests/extension/base/groupby.py | 2 +- pandas/tests/extension/base/reduce.py | 4 +- pandas/tests/extension/test_datetime.py | 2 +- pandas/tests/frame/test_reductions.py | 32 +++++++------- pandas/tests/groupby/test_groupby.py | 4 +- pandas/tests/groupby/test_raises.py | 44 +++++++++---------- pandas/tests/indexes/test_old_base.py | 5 +-- pandas/tests/reductions/test_reductions.py | 6 +-- .../tests/reductions/test_stat_reductions.py | 2 +- pandas/tests/resample/test_resample_api.py | 2 +- pandas/tests/series/test_ufunc.py | 4 +- 18 files changed, 64 insertions(+), 67 deletions(-) diff --git a/pandas/core/arrays/arrow/array.py b/pandas/core/arrays/arrow/array.py index 84b62563605ac..34ca81e36cbc5 100644 --- a/pandas/core/arrays/arrow/array.py +++ b/pandas/core/arrays/arrow/array.py @@ -1697,7 +1697,7 @@ def pyarrow_meth(data, skip_nulls, **kwargs): except (AttributeError, NotImplementedError, TypeError) as err: msg = ( f"'{type(self).__name__}' with dtype {self.dtype} " - f"does not support reduction '{name}' with pyarrow " + f"does not support operation '{name}' with pyarrow " f"version {pa.__version__}. '{name}' may be supported by " f"upgrading pyarrow." ) diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index 76615704f2e33..f37d96bd37614 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -1886,7 +1886,7 @@ def _reduce( Raises ------ - TypeError : subclass does not define reductions + TypeError : subclass does not define operations Examples -------- @@ -1897,7 +1897,7 @@ def _reduce( if meth is None: raise TypeError( f"'{type(self).__name__}' with dtype {self.dtype} " - f"does not support reduction '{name}'" + f"does not support operation '{name}'" ) result = meth(skipna=skipna, **kwargs) if keepdims: diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 52cb175ca79a2..d46810e6ebbdd 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -1662,7 +1662,7 @@ def _groupby_op( if dtype.kind == "M": # Adding/multiplying datetimes is not valid if how in ["any", "all", "sum", "prod", "cumsum", "cumprod", "var", "skew"]: - raise TypeError(f"datetime64 type does not support operation: '{how}'") + raise TypeError(f"datetime64 type does not support operation '{how}'") elif isinstance(dtype, PeriodDtype): # Adding/multiplying Periods is not valid diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index a124e8679ae8e..d0c8d17042741 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -520,7 +520,7 @@ def nanany( if values.dtype.kind == "M": # GH#34479 - raise TypeError("datetime64 type does not support operation: 'any'") + raise TypeError("datetime64 type does not support operation 'any'") values, _ = _get_values(values, skipna, fill_value=False, mask=mask) @@ -576,7 +576,7 @@ def nanall( if values.dtype.kind == "M": # GH#34479 - raise TypeError("datetime64 type does not support operation: 'all'") + raise TypeError("datetime64 type does not support operation 'all'") values, _ = _get_values(values, skipna, fill_value=True, mask=mask) diff --git a/pandas/tests/apply/test_frame_apply.py b/pandas/tests/apply/test_frame_apply.py index 9f3fee686a056..de5f5cac1282c 100644 --- a/pandas/tests/apply/test_frame_apply.py +++ b/pandas/tests/apply/test_frame_apply.py @@ -1209,7 +1209,7 @@ def test_agg_multiple_mixed_raises(): ) # sorted index - msg = "does not support reduction" + msg = "does not support operation" with pytest.raises(TypeError, match=msg): mdf.agg(["min", "sum"]) @@ -1309,7 +1309,7 @@ def test_nuiscance_columns(): ) tm.assert_frame_equal(result, expected) - msg = "does not support reduction" + msg = "does not support operation" with pytest.raises(TypeError, match=msg): df.agg("sum") @@ -1317,7 +1317,7 @@ def test_nuiscance_columns(): expected = Series([6, 6.0, "foobarbaz"], index=["A", "B", "C"]) tm.assert_series_equal(result, expected) - msg = "does not support reduction" + msg = "does not support operation" with pytest.raises(TypeError, match=msg): df.agg(["sum"]) diff --git a/pandas/tests/arrays/categorical/test_operators.py b/pandas/tests/arrays/categorical/test_operators.py index 8778df832d4d7..dbc6cc7715744 100644 --- a/pandas/tests/arrays/categorical/test_operators.py +++ b/pandas/tests/arrays/categorical/test_operators.py @@ -374,14 +374,14 @@ def test_numeric_like_ops(self): # min/max) s = df["value_group"] for op in ["kurt", "skew", "var", "std", "mean", "sum", "median"]: - msg = f"does not support reduction '{op}'" + msg = f"does not support operation '{op}'" with pytest.raises(TypeError, match=msg): getattr(s, op)(numeric_only=False) def test_numeric_like_ops_series(self): # numpy ops s = Series(Categorical([1, 2, 3, 4])) - with pytest.raises(TypeError, match="does not support reduction 'sum'"): + with pytest.raises(TypeError, match="does not support operation 'sum'"): np.sum(s) @pytest.mark.parametrize( diff --git a/pandas/tests/arrays/test_datetimelike.py b/pandas/tests/arrays/test_datetimelike.py index 971c5bf487104..cfc04b5c91354 100644 --- a/pandas/tests/arrays/test_datetimelike.py +++ b/pandas/tests/arrays/test_datetimelike.py @@ -247,7 +247,7 @@ def test_scalar_from_string(self, arr1d): assert result == arr1d[0] def test_reduce_invalid(self, arr1d): - msg = "does not support reduction 'not a method'" + msg = "does not support operation 'not a method'" with pytest.raises(TypeError, match=msg): arr1d._reduce("not a method") diff --git a/pandas/tests/extension/base/groupby.py b/pandas/tests/extension/base/groupby.py index dcbbac44d083a..bab8566a06dc2 100644 --- a/pandas/tests/extension/base/groupby.py +++ b/pandas/tests/extension/base/groupby.py @@ -165,7 +165,7 @@ def test_in_numeric_groupby(self, data_for_grouping): # period "does not support sum operations", # datetime - "does not support operation: 'sum'", + "does not support operation 'sum'", # all others re.escape(f"agg function failed [how->sum,dtype->{dtype}"), ] diff --git a/pandas/tests/extension/base/reduce.py b/pandas/tests/extension/base/reduce.py index 03952d87f0ac6..c3a6daee2dd54 100644 --- a/pandas/tests/extension/base/reduce.py +++ b/pandas/tests/extension/base/reduce.py @@ -86,7 +86,7 @@ def test_reduce_series_boolean(self, data, all_boolean_reductions, skipna): # TODO: the message being checked here isn't actually checking anything msg = ( "[Cc]annot perform|Categorical is not ordered for operation|" - "does not support reduction|" + "does not support operation|" ) with pytest.raises(TypeError, match=msg): @@ -105,7 +105,7 @@ def test_reduce_series_numeric(self, data, all_numeric_reductions, skipna): # TODO: the message being checked here isn't actually checking anything msg = ( "[Cc]annot perform|Categorical is not ordered for operation|" - "does not support reduction|" + "does not support operation|" ) with pytest.raises(TypeError, match=msg): diff --git a/pandas/tests/extension/test_datetime.py b/pandas/tests/extension/test_datetime.py index 5de4865feb6f9..a42fa6088d9c8 100644 --- a/pandas/tests/extension/test_datetime.py +++ b/pandas/tests/extension/test_datetime.py @@ -104,7 +104,7 @@ def _supports_reduction(self, obj, op_name: str) -> bool: @pytest.mark.parametrize("skipna", [True, False]) def test_reduce_series_boolean(self, data, all_boolean_reductions, skipna): meth = all_boolean_reductions - msg = f"datetime64 type does not support operation: '{meth}'" + msg = f"datetime64 type does not support operation '{meth}'" with pytest.raises(TypeError, match=msg): super().test_reduce_series_boolean(data, all_boolean_reductions, skipna) diff --git a/pandas/tests/frame/test_reductions.py b/pandas/tests/frame/test_reductions.py index fd3dad37da1f9..c1161a258aaa4 100644 --- a/pandas/tests/frame/test_reductions.py +++ b/pandas/tests/frame/test_reductions.py @@ -975,7 +975,7 @@ def test_sum_mixed_datetime(self): df = DataFrame({"A": date_range("2000", periods=4), "B": [1, 2, 3, 4]}).reindex( [2, 3, 4] ) - with pytest.raises(TypeError, match="does not support reduction 'sum'"): + with pytest.raises(TypeError, match="does not support operation 'sum'"): df.sum() def test_mean_corner(self, float_frame, float_string_frame): @@ -1381,7 +1381,7 @@ def test_any_datetime(self): ] df = DataFrame({"A": float_data, "B": datetime_data}) - msg = "datetime64 type does not support operation: 'any'" + msg = "datetime64 type does not support operation 'any'" with pytest.raises(TypeError, match=msg): df.any(axis=1) @@ -1466,18 +1466,18 @@ def test_any_all_np_func(self, func, data, expected): if any(isinstance(x, CategoricalDtype) for x in data.dtypes): with pytest.raises( - TypeError, match="dtype category does not support reduction" + TypeError, match=".* dtype category does not support operation" ): func(data) # method version with pytest.raises( - TypeError, match="dtype category does not support reduction" + TypeError, match=".* dtype category does not support operation" ): getattr(DataFrame(data), func.__name__)(axis=None) if data.dtypes.apply(lambda x: x.kind == "M").any(): # GH#34479 - msg = "datetime64 type does not support operation: '(any|all)'" + msg = "datetime64 type does not support operation '(any|all)'" with pytest.raises(TypeError, match=msg): func(data) @@ -1734,19 +1734,19 @@ def test_any_all_categorical_dtype_nuisance_column(self, all_boolean_reductions) df = ser.to_frame() # Double-check the Series behavior is to raise - with pytest.raises(TypeError, match="does not support reduction"): + with pytest.raises(TypeError, match="does not support operation"): getattr(ser, all_boolean_reductions)() - with pytest.raises(TypeError, match="does not support reduction"): + with pytest.raises(TypeError, match="does not support operation"): getattr(np, all_boolean_reductions)(ser) - with pytest.raises(TypeError, match="does not support reduction"): + with pytest.raises(TypeError, match="does not support operation"): getattr(df, all_boolean_reductions)(bool_only=False) - with pytest.raises(TypeError, match="does not support reduction"): + with pytest.raises(TypeError, match="does not support operation"): getattr(df, all_boolean_reductions)(bool_only=None) - with pytest.raises(TypeError, match="does not support reduction"): + with pytest.raises(TypeError, match="does not support operation"): getattr(np, all_boolean_reductions)(df, axis=0) def test_median_categorical_dtype_nuisance_column(self): @@ -1755,22 +1755,22 @@ def test_median_categorical_dtype_nuisance_column(self): ser = df["A"] # Double-check the Series behavior is to raise - with pytest.raises(TypeError, match="does not support reduction"): + with pytest.raises(TypeError, match="does not support operation"): ser.median() - with pytest.raises(TypeError, match="does not support reduction"): + with pytest.raises(TypeError, match="does not support operation"): df.median(numeric_only=False) - with pytest.raises(TypeError, match="does not support reduction"): + with pytest.raises(TypeError, match="does not support operation"): df.median() # same thing, but with an additional non-categorical column df["B"] = df["A"].astype(int) - with pytest.raises(TypeError, match="does not support reduction"): + with pytest.raises(TypeError, match="does not support operation"): df.median(numeric_only=False) - with pytest.raises(TypeError, match="does not support reduction"): + with pytest.raises(TypeError, match="does not support operation"): df.median() # TODO: np.median(df, axis=0) gives np.array([2.0, 2.0]) instead @@ -1964,7 +1964,7 @@ def test_minmax_extensionarray(method, numeric_only): def test_frame_mixed_numeric_object_with_timestamp(ts_value): # GH 13912 df = DataFrame({"a": [1], "b": [1.1], "c": ["foo"], "d": [ts_value]}) - with pytest.raises(TypeError, match="does not support reduction"): + with pytest.raises(TypeError, match="does not support operation"): df.sum() diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index be8f5d73fe7e8..54d7895691f3f 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -671,7 +671,7 @@ def test_raises_on_nuisance(df): df = df.loc[:, ["A", "C", "D"]] df["E"] = datetime.now() grouped = df.groupby("A") - msg = "datetime64 type does not support operation: 'sum'" + msg = "datetime64 type does not support operation 'sum'" with pytest.raises(TypeError, match=msg): grouped.agg("sum") with pytest.raises(TypeError, match=msg): @@ -1794,7 +1794,7 @@ def get_categorical_invalid_expected(): else: msg = "category type does not support" if op == "skew": - msg = "|".join([msg, "does not support reduction 'skew'"]) + msg = "|".join([msg, "does not support operation 'skew'"]) with pytest.raises(TypeError, match=msg): get_result() diff --git a/pandas/tests/groupby/test_raises.py b/pandas/tests/groupby/test_raises.py index 7af27d7227035..70be98af1289f 100644 --- a/pandas/tests/groupby/test_raises.py +++ b/pandas/tests/groupby/test_raises.py @@ -241,16 +241,16 @@ def test_groupby_raises_datetime( return klass, msg = { - "all": (TypeError, "datetime64 type does not support operation: 'all'"), - "any": (TypeError, "datetime64 type does not support operation: 'any'"), + "all": (TypeError, "datetime64 type does not support operation 'all'"), + "any": (TypeError, "datetime64 type does not support operation 'any'"), "bfill": (None, ""), "corrwith": (TypeError, "cannot perform __mul__ with this index type"), "count": (None, ""), "cumcount": (None, ""), "cummax": (None, ""), "cummin": (None, ""), - "cumprod": (TypeError, "datetime64 type does not support operation: 'cumprod'"), - "cumsum": (TypeError, "datetime64 type does not support operation: 'cumsum'"), + "cumprod": (TypeError, "datetime64 type does not support operation 'cumprod'"), + "cumsum": (TypeError, "datetime64 type does not support operation 'cumsum'"), "diff": (None, ""), "ffill": (None, ""), "fillna": (None, ""), @@ -265,7 +265,7 @@ def test_groupby_raises_datetime( "ngroup": (None, ""), "nunique": (None, ""), "pct_change": (TypeError, "cannot perform __truediv__ with this index type"), - "prod": (TypeError, "datetime64 type does not support operation: 'prod'"), + "prod": (TypeError, "datetime64 type does not support operation 'prod'"), "quantile": (None, ""), "rank": (None, ""), "sem": (None, ""), @@ -275,14 +275,14 @@ def test_groupby_raises_datetime( TypeError, "|".join( [ - r"dtype datetime64\[ns\] does not support reduction", - "datetime64 type does not support operation: 'skew'", + r"dtype datetime64\[ns\] does not support operation", + "datetime64 type does not support operation 'skew'", ] ), ), "std": (None, ""), - "sum": (TypeError, "datetime64 type does not support operation: 'sum"), - "var": (TypeError, "datetime64 type does not support operation: 'var'"), + "sum": (TypeError, "datetime64 type does not support operation 'sum"), + "var": (TypeError, "datetime64 type does not support operation 'var'"), }[groupby_func] if groupby_func == "fillna": @@ -323,7 +323,7 @@ def test_groupby_raises_datetime_np( klass, msg = { np.sum: ( TypeError, - re.escape("datetime64[us] does not support reduction 'sum'"), + re.escape("datetime64[us] does not support operation 'sum'"), ), np.mean: (None, ""), }[groupby_func_np] @@ -417,7 +417,7 @@ def test_groupby_raises_category( TypeError, "|".join( [ - "'Categorical' .* does not support reduction 'mean'", + "'Categorical' .* does not support operation 'mean'", "category dtype does not support aggregation 'mean'", ] ), @@ -426,7 +426,7 @@ def test_groupby_raises_category( TypeError, "|".join( [ - "'Categorical' .* does not support reduction 'median'", + "'Categorical' .* does not support operation 'median'", "category dtype does not support aggregation 'median'", ] ), @@ -445,7 +445,7 @@ def test_groupby_raises_category( TypeError, "|".join( [ - "'Categorical' .* does not support reduction 'sem'", + "'Categorical' .* does not support operation 'sem'", "category dtype does not support aggregation 'sem'", ] ), @@ -456,7 +456,7 @@ def test_groupby_raises_category( TypeError, "|".join( [ - "dtype category does not support reduction 'skew'", + "dtype category does not support operation 'skew'", "category type does not support skew operations", ] ), @@ -465,7 +465,7 @@ def test_groupby_raises_category( TypeError, "|".join( [ - "'Categorical' .* does not support reduction 'std'", + "'Categorical' .* does not support operation 'std'", "category dtype does not support aggregation 'std'", ] ), @@ -475,7 +475,7 @@ def test_groupby_raises_category( TypeError, "|".join( [ - "'Categorical' .* does not support reduction 'var'", + "'Categorical' .* does not support operation 'var'", "category dtype does not support aggregation 'var'", ] ), @@ -519,10 +519,10 @@ def test_groupby_raises_category_np( gb = gb["d"] klass, msg = { - np.sum: (TypeError, "dtype category does not support reduction 'sum'"), + np.sum: (TypeError, "dtype category does not support operation 'sum'"), np.mean: ( TypeError, - "dtype category does not support reduction 'mean'", + "dtype category does not support operation 'mean'", ), }[groupby_func_np] _call_and_check(klass, msg, how, gb, groupby_func_np, ()) @@ -618,7 +618,7 @@ def test_groupby_raises_category_on_category( TypeError, "|".join( [ - "'Categorical' .* does not support reduction 'sem'", + "'Categorical' .* does not support operation 'sem'", "category dtype does not support aggregation 'sem'", ] ), @@ -630,7 +630,7 @@ def test_groupby_raises_category_on_category( "|".join( [ "category type does not support skew operations", - "dtype category does not support reduction 'skew'", + "dtype category does not support operation 'skew'", ] ), ), @@ -638,7 +638,7 @@ def test_groupby_raises_category_on_category( TypeError, "|".join( [ - "'Categorical' .* does not support reduction 'std'", + "'Categorical' .* does not support operation 'std'", "category dtype does not support aggregation 'std'", ] ), @@ -648,7 +648,7 @@ def test_groupby_raises_category_on_category( TypeError, "|".join( [ - "'Categorical' .* does not support reduction 'var'", + "'Categorical' .* does not support operation 'var'", "category dtype does not support aggregation 'var'", ] ), diff --git a/pandas/tests/indexes/test_old_base.py b/pandas/tests/indexes/test_old_base.py index 1f7fdbc0f992c..efb28fadeb293 100644 --- a/pandas/tests/indexes/test_old_base.py +++ b/pandas/tests/indexes/test_old_base.py @@ -223,10 +223,7 @@ def test_logical_compat(self, simple_index): assert idx.any() == idx.to_series().any() else: msg = "cannot perform (any|all)" - if isinstance(idx, DatetimeIndex): - msg = "datetime64 type does not support operation: '(any|all)'" - else: - msg = "does not support reduction '(any|all)'" + msg = "does not support operation '(any|all)'" with pytest.raises(TypeError, match=msg): idx.all() with pytest.raises(TypeError, match=msg): diff --git a/pandas/tests/reductions/test_reductions.py b/pandas/tests/reductions/test_reductions.py index 048553330c1ce..5547b716b2670 100644 --- a/pandas/tests/reductions/test_reductions.py +++ b/pandas/tests/reductions/test_reductions.py @@ -378,7 +378,7 @@ def test_invalid_td64_reductions(self, opname): [ f"reduction operation '{opname}' not allowed for this dtype", rf"cannot perform {opname} with type timedelta64\[ns\]", - f"does not support reduction '{opname}'", + f"does not support operation '{opname}'", ] ) @@ -714,7 +714,7 @@ def test_ops_consistency_on_empty(self, method): [ "operation 'var' not allowed", r"cannot perform var with type timedelta64\[ns\]", - "does not support reduction 'var'", + "does not support operation 'var'", ] ) with pytest.raises(TypeError, match=msg): @@ -1010,7 +1010,7 @@ def test_any_all_datetimelike(self): df = DataFrame(ser) # GH#34479 - msg = "datetime64 type does not support operation: '(any|all)'" + msg = "datetime64 type does not support operation '(any|all)'" with pytest.raises(TypeError, match=msg): dta.all() with pytest.raises(TypeError, match=msg): diff --git a/pandas/tests/reductions/test_stat_reductions.py b/pandas/tests/reductions/test_stat_reductions.py index 60fcf8cbc142c..4af1ca1d4800a 100644 --- a/pandas/tests/reductions/test_stat_reductions.py +++ b/pandas/tests/reductions/test_stat_reductions.py @@ -99,7 +99,7 @@ def _check_stat_op( # mean, idxmax, idxmin, min, and max are valid for dates if name not in ["max", "min", "mean", "median", "std"]: ds = Series(date_range("1/1/2001", periods=10)) - msg = f"does not support reduction '{name}'" + msg = f"does not support operation '{name}'" with pytest.raises(TypeError, match=msg): f(ds) diff --git a/pandas/tests/resample/test_resample_api.py b/pandas/tests/resample/test_resample_api.py index 9b442fa7dbd07..a77097fd5ce61 100644 --- a/pandas/tests/resample/test_resample_api.py +++ b/pandas/tests/resample/test_resample_api.py @@ -709,7 +709,7 @@ def test_selection_api_validation(): exp.index.name = "d" with pytest.raises( - TypeError, match="datetime64 type does not support operation: 'sum'" + TypeError, match="datetime64 type does not support operation 'sum'" ): df.resample("2D", level="d").sum() result = df.resample("2D", level="d").sum(numeric_only=True) diff --git a/pandas/tests/series/test_ufunc.py b/pandas/tests/series/test_ufunc.py index 94a6910509e2d..36a2afb2162c2 100644 --- a/pandas/tests/series/test_ufunc.py +++ b/pandas/tests/series/test_ufunc.py @@ -289,7 +289,7 @@ def test_multiply(self, values_for_np_reduce, box_with_array, request): else: msg = "|".join( [ - "does not support reduction", + "does not support operation", "unsupported operand type", "ufunc 'multiply' cannot use operands", ] @@ -319,7 +319,7 @@ def test_add(self, values_for_np_reduce, box_with_array): else: msg = "|".join( [ - "does not support reduction", + "does not support operation", "unsupported operand type", "ufunc 'add' cannot use operands", ] From 4ff9cea864e24df040b6e392edf813aa61ac9bcb Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Thu, 4 Apr 2024 14:10:26 +0200 Subject: [PATCH 11/11] delete unused line --- pandas/tests/indexes/test_old_base.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/tests/indexes/test_old_base.py b/pandas/tests/indexes/test_old_base.py index efb28fadeb293..871e7cdda4102 100644 --- a/pandas/tests/indexes/test_old_base.py +++ b/pandas/tests/indexes/test_old_base.py @@ -222,7 +222,6 @@ def test_logical_compat(self, simple_index): assert idx.any() == idx._values.any() assert idx.any() == idx.to_series().any() else: - msg = "cannot perform (any|all)" msg = "does not support operation '(any|all)'" with pytest.raises(TypeError, match=msg): idx.all()