From 7c3337ae84c03fb9090927127ebd9c11d4d59fb7 Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Wed, 2 Dec 2020 10:49:04 +0000 Subject: [PATCH 01/15] match message using the generate_error_message method --- pandas/tests/extension/base/reduce.py | 50 +++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/pandas/tests/extension/base/reduce.py b/pandas/tests/extension/base/reduce.py index 6f433d659575a..c4f210fcc1f93 100644 --- a/pandas/tests/extension/base/reduce.py +++ b/pandas/tests/extension/base/reduce.py @@ -2,12 +2,54 @@ import pytest +import re + import pandas as pd import pandas._testing as tm from .base import BaseExtensionTests +def generate_error_message(dtype, op_name): + """ + Generate an error message returned by the following + + getattr(s, op_name)(skipna=skipna) + + where `s` is an object with datatype `dtype`, `op_name` is an operation + to be performed on `s`, and `skipna` is a boolean flag. + + Parameters + ---------- + dtype : str + Datatype of the object `s` + op_name : str + Name of operation to perform on `s` + + Returns + ------- + str + Error message caused by performing the operation + """ + if dtype == "category": + if op_name in ["min", "max"]: + return re.escape( + f"Categorical is not ordered for operation {op_name}\n" + "you can use .as_ordered() to change the Categorical to an " + "ordered one\n" + ) + else: + return f"'Categorical' does not implement reduction '{op_name}'" + elif dtype in ["string", "arrow_string"]: + return f"Cannot perform reduction '{op_name}' with string dtype" + elif dtype == "interval": + return rf"cannot perform {op_name} with type interval\[float64\]" + elif dtype == "json": + return f"cannot perform {op_name} with type json" + elif dtype == "arrow_bool": + return "" + + class BaseReduceTests(BaseExtensionTests): """ Reduction specific tests. Generally these only @@ -28,7 +70,9 @@ def test_reduce_series_numeric(self, data, all_numeric_reductions, skipna): op_name = all_numeric_reductions s = pd.Series(data) - with pytest.raises(TypeError): + msg = generate_error_message(s.dtype.name, op_name) + + with pytest.raises(TypeError, match=msg): getattr(s, op_name)(skipna=skipna) @pytest.mark.parametrize("skipna", [True, False]) @@ -36,7 +80,9 @@ def test_reduce_series_boolean(self, data, all_boolean_reductions, skipna): op_name = all_boolean_reductions s = pd.Series(data) - with pytest.raises(TypeError): + msg = generate_error_message(s.dtype.name, op_name) + + with pytest.raises(TypeError, match=msg): getattr(s, op_name)(skipna=skipna) From a34501d1d03aa55f615c4be67d6ca5c02b5563b0 Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Wed, 2 Dec 2020 10:49:29 +0000 Subject: [PATCH 02/15] match error messages --- pandas/tests/extension/base/getitem.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index 251376798efc3..95d1770d5d3bb 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -160,11 +160,19 @@ def test_getitem_mask(self, data): def test_getitem_mask_raises(self, data): mask = np.array([True, False]) - with pytest.raises(IndexError): + msg = ( + "boolean index did not match indexed array along dimension 0; " + f"dimension is {len(data)} but corresponding boolean dimension is 2" + ) + with pytest.raises(IndexError, match=msg): data[mask] mask = pd.array(mask, dtype="boolean") - with pytest.raises(IndexError): + msg = ( + "only integers, slices (`:`), ellipsis (`...`), numpy.newaxis" + " (`None`) and integer or boolean arrays are valid indices" + ) + with pytest.raises(IndexError, match=msg): data[mask] def test_getitem_boolean_array_mask(self, data): @@ -305,7 +313,8 @@ def test_take_empty(self, data, na_value, na_cmp): result = empty.take([-1], allow_fill=True) assert na_cmp(result[0], na_value) - with pytest.raises(IndexError): + msg = "cannot do a non-empty take from an empty axes." + with pytest.raises(IndexError, match=msg): empty.take([-1]) with pytest.raises(IndexError, match="cannot do a non-empty take"): @@ -330,13 +339,14 @@ def test_take_non_na_fill_value(self, data_missing): self.assert_extension_array_equal(result, expected) def test_take_pandas_style_negative_raises(self, data, na_value): - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=""): data.take([0, -2], fill_value=na_value, allow_fill=True) @pytest.mark.parametrize("allow_fill", [True, False]) def test_take_out_of_bounds_raises(self, data, allow_fill): arr = data[:3] - with pytest.raises(IndexError): + msg = "index 3 is out of bounds for axis 0 with size 3" + with pytest.raises(IndexError, match=msg): arr.take(np.asarray([0, 3]), allow_fill=allow_fill) def test_take_series(self, data): From 5df082bd6903c8255ce08dd781367342c592fef3 Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Wed, 2 Dec 2020 15:00:04 +0000 Subject: [PATCH 03/15] amend messages --- pandas/tests/extension/base/getitem.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index 95d1770d5d3bb..e0e4ba861f62e 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -160,10 +160,7 @@ def test_getitem_mask(self, data): def test_getitem_mask_raises(self, data): mask = np.array([True, False]) - msg = ( - "boolean index did not match indexed array along dimension 0; " - f"dimension is {len(data)} but corresponding boolean dimension is 2" - ) + msg = f"Boolean index has wrong length: 2 instead of {len(data)}" with pytest.raises(IndexError, match=msg): data[mask] @@ -345,7 +342,11 @@ def test_take_pandas_style_negative_raises(self, data, na_value): @pytest.mark.parametrize("allow_fill", [True, False]) def test_take_out_of_bounds_raises(self, data, allow_fill): arr = data[:3] - msg = "index 3 is out of bounds for axis 0 with size 3" + msg = ( + "indices are out-of-bounds" + if allow_fill + else "index 3 is out of bounds with size 3" + ) with pytest.raises(IndexError, match=msg): arr.take(np.asarray([0, 3]), allow_fill=allow_fill) From 69226b69b6213aa1c5bd2bdc70997963eb09d19e Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Wed, 2 Dec 2020 18:20:17 +0000 Subject: [PATCH 04/15] remove error message --- pandas/tests/extension/base/getitem.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index e0e4ba861f62e..5064707b51365 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -165,10 +165,6 @@ def test_getitem_mask_raises(self, data): data[mask] mask = pd.array(mask, dtype="boolean") - msg = ( - "only integers, slices (`:`), ellipsis (`...`), numpy.newaxis" - " (`None`) and integer or boolean arrays are valid indices" - ) with pytest.raises(IndexError, match=msg): data[mask] From 51785f43bdb05edb5fa37d37ff3909567145ac03 Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Thu, 3 Dec 2020 10:20:52 +0000 Subject: [PATCH 05/15] change message based on if dtype is float --- pandas/tests/extension/base/getitem.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index 5064707b51365..069927b107b07 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -338,11 +338,14 @@ def test_take_pandas_style_negative_raises(self, data, na_value): @pytest.mark.parametrize("allow_fill", [True, False]) def test_take_out_of_bounds_raises(self, data, allow_fill): arr = data[:3] - msg = ( - "indices are out-of-bounds" - if allow_fill - else "index 3 is out of bounds with size 3" - ) + if allow_fill: + msg = "indices are out-of-bounds" + else: + if arr.dtype.name[:5] == 'float': + msg = "index 3 is out of bounds for size 3" + else: + msg = "index 3 is out of bounds for axis 0 with size 3" + with pytest.raises(IndexError, match=msg): arr.take(np.asarray([0, 3]), allow_fill=allow_fill) From f1d8437f50d5dadc7df9f6067c224891c3abfd72 Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Thu, 3 Dec 2020 10:50:20 +0000 Subject: [PATCH 06/15] add object dtype to check --- pandas/tests/extension/base/getitem.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index 069927b107b07..88de6be86e600 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -341,10 +341,12 @@ def test_take_out_of_bounds_raises(self, data, allow_fill): if allow_fill: msg = "indices are out-of-bounds" else: - if arr.dtype.name[:5] == 'float': - msg = "index 3 is out of bounds for size 3" - else: + if ("numpy" not in str(type(arr))) | ( + arr.dtype.name in ["float32", "float64", "object"] + ): msg = "index 3 is out of bounds for axis 0 with size 3" + else: + msg = "index 3 is out of bounds for size 3" with pytest.raises(IndexError, match=msg): arr.take(np.asarray([0, 3]), allow_fill=allow_fill) From 15969058b4c08ea39ec1132b32e76b301b5a7485 Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Thu, 3 Dec 2020 11:02:25 +0000 Subject: [PATCH 07/15] add msgs for dtypes --- pandas/tests/extension/base/getitem.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index 88de6be86e600..2faa9793f587d 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -338,15 +338,20 @@ def test_take_pandas_style_negative_raises(self, data, na_value): @pytest.mark.parametrize("allow_fill", [True, False]) def test_take_out_of_bounds_raises(self, data, allow_fill): arr = data[:3] - if allow_fill: - msg = "indices are out-of-bounds" + if (arr.dtype.name == 'arrow_string') | ('Sparse' in arr.dtype.name): + msg = "out of bounds value in 'indices'." + elif arr.dtype.name == 'json': + msg = 'Index is out of bounds or cannot do a non-empty take from an empty array.' else: - if ("numpy" not in str(type(arr))) | ( - arr.dtype.name in ["float32", "float64", "object"] - ): - msg = "index 3 is out of bounds for axis 0 with size 3" + if allow_fill: + msg = "indices are out-of-bounds" else: - msg = "index 3 is out of bounds for size 3" + if ("numpy" not in str(type(arr))) | ( + arr.dtype.name in ["float32", "float64", "object"] + ): + msg = "index 3 is out of bounds for axis 0 with size 3" + else: + msg = "index 3 is out of bounds for size 3" with pytest.raises(IndexError, match=msg): arr.take(np.asarray([0, 3]), allow_fill=allow_fill) From 700620177ed2e7fb0281c4cdcb64cea9dba39b5c Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Thu, 3 Dec 2020 11:12:49 +0000 Subject: [PATCH 08/15] make test pass by adding msgs for arrow_string and json dtypes --- pandas/tests/extension/base/getitem.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index 2faa9793f587d..89a479121dd72 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -306,7 +306,13 @@ def test_take_empty(self, data, na_value, na_cmp): result = empty.take([-1], allow_fill=True) assert na_cmp(result[0], na_value) - msg = "cannot do a non-empty take from an empty axes." + if empty.dtype.name == 'arrow_string': + msg = 'Index -1 out of bounds' + elif empty.dtype.name == 'json': + msg = 'Index is out of bounds or cannot do a non-empty take from an empty array.' + else: + msg = "cannot do a non-empty take from an empty axes." + with pytest.raises(IndexError, match=msg): empty.take([-1]) From 3c9b6bbac04db921e20ae5b5b1119c818dede36b Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Thu, 3 Dec 2020 11:13:19 +0000 Subject: [PATCH 09/15] black-ify --- pandas/tests/extension/base/getitem.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index 89a479121dd72..777c85245bcc4 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -306,10 +306,10 @@ def test_take_empty(self, data, na_value, na_cmp): result = empty.take([-1], allow_fill=True) assert na_cmp(result[0], na_value) - if empty.dtype.name == 'arrow_string': - msg = 'Index -1 out of bounds' - elif empty.dtype.name == 'json': - msg = 'Index is out of bounds or cannot do a non-empty take from an empty array.' + if empty.dtype.name == "arrow_string": + msg = "Index -1 out of bounds" + elif empty.dtype.name == "json": + msg = "Index is out of bounds or cannot do a non-empty take from an empty array." else: msg = "cannot do a non-empty take from an empty axes." @@ -344,10 +344,10 @@ def test_take_pandas_style_negative_raises(self, data, na_value): @pytest.mark.parametrize("allow_fill", [True, False]) def test_take_out_of_bounds_raises(self, data, allow_fill): arr = data[:3] - if (arr.dtype.name == 'arrow_string') | ('Sparse' in arr.dtype.name): + if (arr.dtype.name == "arrow_string") | ("Sparse" in arr.dtype.name): msg = "out of bounds value in 'indices'." - elif arr.dtype.name == 'json': - msg = 'Index is out of bounds or cannot do a non-empty take from an empty array.' + elif arr.dtype.name == "json": + msg = "Index is out of bounds or cannot do a non-empty take from an empty array." else: if allow_fill: msg = "indices are out-of-bounds" From ce3a18be1d25c5baa858fbfc13bbd3bd231980ac Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Thu, 3 Dec 2020 11:15:38 +0000 Subject: [PATCH 10/15] split line to pass pep8 --- pandas/tests/extension/base/getitem.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index 777c85245bcc4..3c0fae73835a0 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -309,7 +309,10 @@ def test_take_empty(self, data, na_value, na_cmp): if empty.dtype.name == "arrow_string": msg = "Index -1 out of bounds" elif empty.dtype.name == "json": - msg = "Index is out of bounds or cannot do a non-empty take from an empty array." + msg = ( + "Index is out of bounds or cannot do a non-empty take " + "from an empty array." + ) else: msg = "cannot do a non-empty take from an empty axes." @@ -347,7 +350,10 @@ def test_take_out_of_bounds_raises(self, data, allow_fill): if (arr.dtype.name == "arrow_string") | ("Sparse" in arr.dtype.name): msg = "out of bounds value in 'indices'." elif arr.dtype.name == "json": - msg = "Index is out of bounds or cannot do a non-empty take from an empty array." + msg = ( + "Index is out of bounds or cannot do a non-empty take " + "from an empty array." + ) else: if allow_fill: msg = "indices are out-of-bounds" From 2abad47e2c099b58ec4452873fe739037d4f8e75 Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Thu, 3 Dec 2020 11:28:48 +0000 Subject: [PATCH 11/15] move import to pass pre-commit --- pandas/tests/extension/base/reduce.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pandas/tests/extension/base/reduce.py b/pandas/tests/extension/base/reduce.py index c4f210fcc1f93..2cd6a2b2a2a5b 100644 --- a/pandas/tests/extension/base/reduce.py +++ b/pandas/tests/extension/base/reduce.py @@ -1,9 +1,8 @@ +import re import warnings import pytest -import re - import pandas as pd import pandas._testing as tm From e5e42da2472fa4a08d4ea5fef8ca51a41e8ca42c Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Thu, 3 Dec 2020 12:51:05 +0000 Subject: [PATCH 12/15] check if name not in list of dtypes --- pandas/tests/extension/base/getitem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index 3c0fae73835a0..6a29e9113661e 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -359,7 +359,7 @@ def test_take_out_of_bounds_raises(self, data, allow_fill): msg = "indices are out-of-bounds" else: if ("numpy" not in str(type(arr))) | ( - arr.dtype.name in ["float32", "float64", "object"] + arr.dtype.name not in ["string"] ): msg = "index 3 is out of bounds for axis 0 with size 3" else: From 82f03840ff0fc6ec8ba47994a2016ad7c54e281e Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Fri, 11 Dec 2020 14:52:57 +0000 Subject: [PATCH 13/15] simplify matching (thanks to Marco's suggestions) --- pandas/tests/extension/base/getitem.py | 29 ++------------- pandas/tests/extension/base/reduce.py | 50 +++++--------------------- 2 files changed, 10 insertions(+), 69 deletions(-) diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index 6a29e9113661e..bfd6da0fc864d 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -306,15 +306,7 @@ def test_take_empty(self, data, na_value, na_cmp): result = empty.take([-1], allow_fill=True) assert na_cmp(result[0], na_value) - if empty.dtype.name == "arrow_string": - msg = "Index -1 out of bounds" - elif empty.dtype.name == "json": - msg = ( - "Index is out of bounds or cannot do a non-empty take " - "from an empty array." - ) - else: - msg = "cannot do a non-empty take from an empty axes." + msg = "cannot do a non-empty take from an empty axes|out of bounds" with pytest.raises(IndexError, match=msg): empty.take([-1]) @@ -347,25 +339,8 @@ def test_take_pandas_style_negative_raises(self, data, na_value): @pytest.mark.parametrize("allow_fill", [True, False]) def test_take_out_of_bounds_raises(self, data, allow_fill): arr = data[:3] - if (arr.dtype.name == "arrow_string") | ("Sparse" in arr.dtype.name): - msg = "out of bounds value in 'indices'." - elif arr.dtype.name == "json": - msg = ( - "Index is out of bounds or cannot do a non-empty take " - "from an empty array." - ) - else: - if allow_fill: - msg = "indices are out-of-bounds" - else: - if ("numpy" not in str(type(arr))) | ( - arr.dtype.name not in ["string"] - ): - msg = "index 3 is out of bounds for axis 0 with size 3" - else: - msg = "index 3 is out of bounds for size 3" - with pytest.raises(IndexError, match=msg): + with pytest.raises(IndexError, match="out of bounds|out-of-bounds"): arr.take(np.asarray([0, 3]), allow_fill=allow_fill) def test_take_series(self, data): diff --git a/pandas/tests/extension/base/reduce.py b/pandas/tests/extension/base/reduce.py index 2cd6a2b2a2a5b..e2b1143ca26c5 100644 --- a/pandas/tests/extension/base/reduce.py +++ b/pandas/tests/extension/base/reduce.py @@ -9,46 +9,6 @@ from .base import BaseExtensionTests -def generate_error_message(dtype, op_name): - """ - Generate an error message returned by the following - - getattr(s, op_name)(skipna=skipna) - - where `s` is an object with datatype `dtype`, `op_name` is an operation - to be performed on `s`, and `skipna` is a boolean flag. - - Parameters - ---------- - dtype : str - Datatype of the object `s` - op_name : str - Name of operation to perform on `s` - - Returns - ------- - str - Error message caused by performing the operation - """ - if dtype == "category": - if op_name in ["min", "max"]: - return re.escape( - f"Categorical is not ordered for operation {op_name}\n" - "you can use .as_ordered() to change the Categorical to an " - "ordered one\n" - ) - else: - return f"'Categorical' does not implement reduction '{op_name}'" - elif dtype in ["string", "arrow_string"]: - return f"Cannot perform reduction '{op_name}' with string dtype" - elif dtype == "interval": - return rf"cannot perform {op_name} with type interval\[float64\]" - elif dtype == "json": - return f"cannot perform {op_name} with type json" - elif dtype == "arrow_bool": - return "" - - class BaseReduceTests(BaseExtensionTests): """ Reduction specific tests. Generally these only @@ -69,7 +29,10 @@ def test_reduce_series_numeric(self, data, all_numeric_reductions, skipna): op_name = all_numeric_reductions s = pd.Series(data) - msg = generate_error_message(s.dtype.name, op_name) + msg = ( + "[Cc]annot perform|Categorical is not ordered for operation|" + "'Categorical' does not implement reduction" + ) with pytest.raises(TypeError, match=msg): getattr(s, op_name)(skipna=skipna) @@ -79,7 +42,10 @@ def test_reduce_series_boolean(self, data, all_boolean_reductions, skipna): op_name = all_boolean_reductions s = pd.Series(data) - msg = generate_error_message(s.dtype.name, op_name) + msg = ( + "[Cc]annot perform|Categorical is not ordered for operation|" + "'Categorical' does not implement reduction" + ) with pytest.raises(TypeError, match=msg): getattr(s, op_name)(skipna=skipna) From bef81ee710469bf1aaef9c901ee603d35524712d Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Fri, 11 Dec 2020 14:55:42 +0000 Subject: [PATCH 14/15] remove import --- pandas/tests/extension/base/reduce.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/tests/extension/base/reduce.py b/pandas/tests/extension/base/reduce.py index e2b1143ca26c5..cc78d965156f2 100644 --- a/pandas/tests/extension/base/reduce.py +++ b/pandas/tests/extension/base/reduce.py @@ -1,4 +1,3 @@ -import re import warnings import pytest From da6ed3fc617f6492581d86184ea4fc7325672c2d Mon Sep 17 00:00:00 2001 From: Mark Graham Date: Fri, 11 Dec 2020 16:26:51 +0000 Subject: [PATCH 15/15] add check for empty error message --- pandas/tests/extension/base/reduce.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/tests/extension/base/reduce.py b/pandas/tests/extension/base/reduce.py index cc78d965156f2..55f8aca1b8ae0 100644 --- a/pandas/tests/extension/base/reduce.py +++ b/pandas/tests/extension/base/reduce.py @@ -30,7 +30,7 @@ def test_reduce_series_numeric(self, data, all_numeric_reductions, skipna): msg = ( "[Cc]annot perform|Categorical is not ordered for operation|" - "'Categorical' does not implement reduction" + "'Categorical' does not implement reduction|" ) with pytest.raises(TypeError, match=msg): @@ -43,7 +43,7 @@ def test_reduce_series_boolean(self, data, all_boolean_reductions, skipna): msg = ( "[Cc]annot perform|Categorical is not ordered for operation|" - "'Categorical' does not implement reduction" + "'Categorical' does not implement reduction|" ) with pytest.raises(TypeError, match=msg):