From 5a82ab1cf5c8dd19bd2092787dd8e593cc250f31 Mon Sep 17 00:00:00 2001 From: richard Date: Wed, 16 Nov 2022 23:09:29 -0500 Subject: [PATCH 1/2] CLN: Handle no message for NotImplementedError in _cython_transform --- pandas/core/groupby/generic.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index 4ac701952e258..f73f5b2de5033 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -1362,8 +1362,9 @@ def arr_func(bvalues: ArrayLike) -> ArrayLike: arr_func, ignore_failures=numeric_only is lib.no_default ) except NotImplementedError as err: - # For NotImplementedError, args[0] is the error message - raise TypeError(err.args[0]) from err + # For NotImplementedError, args[0] is the error message when available + msg = err.args[0] if len(err.args) > 0 else "" + raise TypeError(msg) from err res_mgr.set_axis(1, mgr.axes[1]) if len(res_mgr) < orig_mgr_len: From 6e8cb2aafb3c1610f0803f9d45dc8bd9e725a506 Mon Sep 17 00:00:00 2001 From: Richard Shadrach Date: Thu, 17 Nov 2022 17:09:05 -0500 Subject: [PATCH 2/2] Raise NotImplementedError --- pandas/core/groupby/generic.py | 11 +++-------- pandas/tests/groupby/test_function.py | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index f73f5b2de5033..32802f6429c4c 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -1357,14 +1357,9 @@ def arr_func(bvalues: ArrayLike) -> ArrayLike: # We could use `mgr.apply` here and not have to set_axis, but # we would have to do shape gymnastics for ArrayManager compat - try: - res_mgr = mgr.grouped_reduce( - arr_func, ignore_failures=numeric_only is lib.no_default - ) - except NotImplementedError as err: - # For NotImplementedError, args[0] is the error message when available - msg = err.args[0] if len(err.args) > 0 else "" - raise TypeError(msg) from err + res_mgr = mgr.grouped_reduce( + arr_func, ignore_failures=numeric_only is lib.no_default + ) res_mgr.set_axis(1, mgr.axes[1]) if len(res_mgr) < orig_mgr_len: diff --git a/pandas/tests/groupby/test_function.py b/pandas/tests/groupby/test_function.py index b848ff81f35ee..b66422836bbbf 100644 --- a/pandas/tests/groupby/test_function.py +++ b/pandas/tests/groupby/test_function.py @@ -250,6 +250,10 @@ def test_cummin_cummax(self, df, method): def _check(self, df, method, expected_columns, expected_columns_numeric): gb = df.groupby("group") + # object dtypes for transformations are not implemented in Cython and + # have no Python fallback + exception = NotImplementedError if method.startswith("cum") else TypeError + if method in ("min", "max", "cummin", "cummax"): # The methods default to numeric_only=False and raise TypeError msg = "|".join( @@ -258,7 +262,7 @@ def _check(self, df, method, expected_columns, expected_columns_numeric): "function is not implemented for this dtype", ] ) - with pytest.raises(TypeError, match=msg): + with pytest.raises(exception, match=msg): getattr(gb, method)() else: result = getattr(gb, method)() @@ -274,7 +278,7 @@ def _check(self, df, method, expected_columns, expected_columns_numeric): "function is not implemented for this dtype", ] ) - with pytest.raises(TypeError, match=msg): + with pytest.raises(exception, match=msg): getattr(gb, method)(numeric_only=False) else: result = getattr(gb, method)(numeric_only=False) @@ -1411,6 +1415,11 @@ def test_deprecate_numeric_only( elif has_arg or kernel in ("idxmax", "idxmin"): assert numeric_only is not True # kernels that are successful on any dtype were above; this will fail + + # object dtypes for transformations are not implemented in Cython and + # have no Python fallback + exception = NotImplementedError if kernel.startswith("cum") else TypeError + msg = "|".join( [ "not allowed for this dtype", @@ -1422,7 +1431,7 @@ def test_deprecate_numeric_only( "function is not implemented for this dtype", ] ) - with pytest.raises(TypeError, match=msg): + with pytest.raises(exception, match=msg): method(*args, **kwargs) elif not has_arg and numeric_only is not lib.no_default: with pytest.raises(