diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 2737e619fb7077..2d8fda0c4f6ca1 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -339,8 +339,8 @@ def __init__(self, values, categories=None, ordered=None, dtype=None, msg = "Unknown `dtype` {dtype}" raise ValueError(msg.format(dtype=dtype)) elif categories is not None or ordered is not None: - raise ValueError("Cannot specify both `dtype` and `categories`" - " or `ordered`.") + raise ValueError("Cannot specify `categories` or `ordered` " + "together with `dtype`.") categories = dtype.categories @@ -673,8 +673,8 @@ def from_codes(cls, codes, categories=None, ordered=None, dtype=None): """ if dtype is not None: if categories is not None or ordered is not None: - raise ValueError("Cannot specify both `dtype` and `categories`" - " or `ordered`.") + raise ValueError("Cannot specify `categories` or `ordered` " + "together with `dtype`.") else: dtype = CategoricalDtype(categories, ordered) diff --git a/pandas/tests/arrays/categorical/test_constructors.py b/pandas/tests/arrays/categorical/test_constructors.py index ab99b30f1cbbf1..1806f7d7f4da7e 100644 --- a/pandas/tests/arrays/categorical/test_constructors.py +++ b/pandas/tests/arrays/categorical/test_constructors.py @@ -77,7 +77,9 @@ def test_constructor_unsortable(self): assert not factor.ordered # this however will raise as cannot be sorted - with pytest.raises(TypeError): + msg = ("'values' is not ordered, please explicitly specify the " + "categories order by passing in a categories argument.") + with pytest.raises(TypeError, match=msg): Categorical(arr, ordered=True) def test_constructor_interval(self): @@ -99,10 +101,11 @@ def test_constructor(self): tm.assert_numpy_array_equal(c2.__array__(), exp_arr) # categories must be unique - with pytest.raises(ValueError): + msg = "Categorical categories must be unique" + with pytest.raises(ValueError, match=msg): Categorical([1, 2], [1, 2, 2]) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=msg): Categorical(["a", "b"], ["a", "b", "b"]) # The default should be unordered @@ -211,21 +214,23 @@ def test_constructor(self): def test_constructor_not_sequence(self): # https://github.com/pandas-dev/pandas/issues/16022 - with pytest.raises(TypeError): + msg = r"^Index\(\.\.\.\) must be called with a collection of some kind" + with pytest.raises(TypeError, match=msg): Categorical(['a', 'b'], categories='a') def test_constructor_with_null(self): # Cannot have NaN in categories - with pytest.raises(ValueError): + msg = "Categorial categories cannot be null" + with pytest.raises(ValueError, match=msg): Categorical([np.nan, "a", "b", "c"], categories=[np.nan, "a", "b", "c"]) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=msg): Categorical([None, "a", "b", "c"], categories=[None, "a", "b", "c"]) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=msg): Categorical(DatetimeIndex(['nat', '20160101']), categories=[NaT, Timestamp('20160101')]) @@ -347,13 +352,14 @@ def test_constructor_with_dtype(self, ordered): def test_constructor_dtype_and_others_raises(self): dtype = CategoricalDtype(['a', 'b'], ordered=True) - with pytest.raises(ValueError, match="Cannot"): + msg = "Cannot specify `categories` or `ordered` together with `dtype`." + with pytest.raises(ValueError, match=msg): Categorical(['a', 'b'], categories=['a', 'b'], dtype=dtype) - with pytest.raises(ValueError, match="Cannot"): + with pytest.raises(ValueError, match=msg): Categorical(['a', 'b'], ordered=True, dtype=dtype) - with pytest.raises(ValueError, match="Cannot"): + with pytest.raises(ValueError, match=msg): Categorical(['a', 'b'], ordered=False, dtype=dtype) @pytest.mark.parametrize('categories', [ @@ -418,30 +424,35 @@ def test_from_codes(self): # too few categories dtype = CategoricalDtype(categories=[1, 2]) - with pytest.raises(ValueError): + msg = "codes need to be between " + with pytest.raises(ValueError, match=msg): Categorical.from_codes([1, 2], categories=dtype.categories) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=msg): Categorical.from_codes([1, 2], dtype=dtype) # no int codes - with pytest.raises(ValueError): + msg = "codes need to be array-like integers" + with pytest.raises(ValueError, match=msg): Categorical.from_codes(["a"], categories=dtype.categories) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=msg): Categorical.from_codes(["a"], dtype=dtype) # no unique categories - with pytest.raises(ValueError): + with pytest.raises(ValueError, + match="Categorical categories must be unique"): Categorical.from_codes([0, 1, 2], categories=["a", "a", "b"]) # NaN categories included - with pytest.raises(ValueError): + with pytest.raises(ValueError, + match="Categorial categories cannot be null"): Categorical.from_codes([0, 1, 2], categories=["a", "b", np.nan]) # too negative dtype = CategoricalDtype(categories=["a", "b", "c"]) - with pytest.raises(ValueError): + msg = r"codes need to be between -1 and len\(categories\)-1" + with pytest.raises(ValueError, match=msg): Categorical.from_codes([-2, 1, 2], categories=dtype.categories) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=msg): Categorical.from_codes([-2, 1, 2], dtype=dtype) exp = Categorical(["a", "b", "c"], ordered=False) @@ -469,16 +480,19 @@ def test_from_codes_with_categorical_categories(self): tm.assert_categorical_equal(result, expected) # non-unique Categorical still raises - with pytest.raises(ValueError): + with pytest.raises(ValueError, + match="Categorical categories must be unique"): Categorical.from_codes([0, 1], Categorical(['a', 'b', 'a'])) def test_from_codes_with_nan_code(self): # GH21767 codes = [1, 2, np.nan] dtype = CategoricalDtype(categories=['a', 'b', 'c']) - with pytest.raises(ValueError): + with pytest.raises(ValueError, + match="codes need to be array-like integers"): Categorical.from_codes(codes, categories=dtype.categories) - with pytest.raises(ValueError): + with pytest.raises(ValueError, + match="codes need to be array-like integers"): Categorical.from_codes(codes, dtype=dtype) def test_from_codes_with_float(self): @@ -495,9 +509,11 @@ def test_from_codes_with_float(self): tm.assert_numpy_array_equal(cat.codes, np.array([1, 2, 0], dtype='i1')) codes = [1.1, 2.0, 0] # non-integer - with pytest.raises(ValueError): + with pytest.raises(ValueError, + match="codes need to be array-like integers"): Categorical.from_codes(codes, dtype.categories) - with pytest.raises(ValueError): + with pytest.raises(ValueError, + match="codes need to be array-like integers"): Categorical.from_codes(codes, dtype=dtype) @pytest.mark.parametrize('dtype', [None, 'category']) diff --git a/pandas/tests/indexes/test_category.py b/pandas/tests/indexes/test_category.py index bb537f30821e49..6b0aa67ab25431 100644 --- a/pandas/tests/indexes/test_category.py +++ b/pandas/tests/indexes/test_category.py @@ -156,7 +156,7 @@ def test_construction_with_categorical_dtype(self): tm.assert_index_equal(result, expected, exact=True) # error when combining categories/ordered and dtype kwargs - msg = 'Cannot specify both `dtype` and `categories` or `ordered`.' + msg = "Cannot specify `categories` or `ordered` together with `dtype`." with pytest.raises(ValueError, match=msg): CategoricalIndex(data, categories=cats, dtype=dtype)