Skip to content

TST: Add message checks to tests/arrays/categorical/ #30242

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions pandas/tests/arrays/categorical/test_algos.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,21 @@ def test_isin_cats():


@pytest.mark.parametrize(
"to_replace, value, result",
[("b", "c", ["a", "c"]), ("c", "d", ["a", "b"]), ("b", None, ["a", None])],
"to_replace, value, result, expected_error_msg",
[
("b", "c", ["a", "c"], "Categorical.categories are different"),
("c", "d", ["a", "b"], None),
("b", None, ["a", None], "Categorical.categories length are different"),
],
)
def test_replace(to_replace, value, result):
def test_replace(to_replace, value, result, expected_error_msg):
# GH 26988
cat = pd.Categorical(["a", "b"])
expected = pd.Categorical(result)
result = cat.replace(to_replace, value)
tm.assert_categorical_equal(result, expected)
if to_replace == "b": # the "c" test is supposed to be unchanged
with pytest.raises(AssertionError):
with pytest.raises(AssertionError, match=expected_error_msg):
# ensure non-inplace call does not affect original
tm.assert_categorical_equal(cat, expected)
cat.replace(to_replace, value, inplace=True)
Expand Down Expand Up @@ -104,13 +108,21 @@ def test_take_positive_no_warning(self):
def test_take_bounds(self, allow_fill):
# https://github.com/pandas-dev/pandas/issues/20664
cat = pd.Categorical(["a", "b", "a"])
with pytest.raises(IndexError):
if allow_fill:
msg = "indices are out-of-bounds"
else:
msg = "index 4 is out of bounds for size 3"
with pytest.raises(IndexError, match=msg):
cat.take([4, 5], allow_fill=allow_fill)

def test_take_empty(self, allow_fill):
# https://github.com/pandas-dev/pandas/issues/20664
cat = pd.Categorical([], categories=["a", "b"])
with pytest.raises(IndexError):
if allow_fill:
msg = "indices are out-of-bounds"
else:
msg = "cannot do a non-empty take from an empty axes"
with pytest.raises(IndexError, match=msg):
cat.take([0], allow_fill=allow_fill)

def test_positional_take(self, ordered_fixture):
Expand Down
50 changes: 26 additions & 24 deletions pandas/tests/arrays/categorical/test_analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,40 +271,42 @@ def test_map(self):
# GH 12766: Return an index not an array
tm.assert_index_equal(result, Index(np.array([1] * 5, dtype=np.int64)))

def test_validate_inplace(self):
@pytest.mark.parametrize("value", [1, "True", [1, 2, 3], 5.0])
def test_validate_inplace_raises(self, value):
cat = Categorical(["A", "B", "B", "C", "A"])
invalid_values = [1, "True", [1, 2, 3], 5.0]

for value in invalid_values:
with pytest.raises(ValueError):
cat.set_ordered(value=True, inplace=value)
msg = (
'For argument "inplace" expected type bool, '
f"received type {type(value).__name__}"
)
with pytest.raises(ValueError, match=msg):
cat.set_ordered(value=True, inplace=value)

with pytest.raises(ValueError):
cat.as_ordered(inplace=value)
with pytest.raises(ValueError, match=msg):
cat.as_ordered(inplace=value)

with pytest.raises(ValueError):
cat.as_unordered(inplace=value)
with pytest.raises(ValueError, match=msg):
cat.as_unordered(inplace=value)

with pytest.raises(ValueError):
cat.set_categories(["X", "Y", "Z"], rename=True, inplace=value)
with pytest.raises(ValueError, match=msg):
cat.set_categories(["X", "Y", "Z"], rename=True, inplace=value)

with pytest.raises(ValueError):
cat.rename_categories(["X", "Y", "Z"], inplace=value)
with pytest.raises(ValueError, match=msg):
cat.rename_categories(["X", "Y", "Z"], inplace=value)

with pytest.raises(ValueError):
cat.reorder_categories(["X", "Y", "Z"], ordered=True, inplace=value)
with pytest.raises(ValueError, match=msg):
cat.reorder_categories(["X", "Y", "Z"], ordered=True, inplace=value)

with pytest.raises(ValueError):
cat.add_categories(new_categories=["D", "E", "F"], inplace=value)
with pytest.raises(ValueError, match=msg):
cat.add_categories(new_categories=["D", "E", "F"], inplace=value)

with pytest.raises(ValueError):
cat.remove_categories(removals=["D", "E", "F"], inplace=value)
with pytest.raises(ValueError, match=msg):
cat.remove_categories(removals=["D", "E", "F"], inplace=value)

with pytest.raises(ValueError):
cat.remove_unused_categories(inplace=value)
with pytest.raises(ValueError, match=msg):
cat.remove_unused_categories(inplace=value)

with pytest.raises(ValueError):
cat.sort_values(inplace=value)
with pytest.raises(ValueError, match=msg):
cat.sort_values(inplace=value)

def test_isna(self):
exp = np.array([False, False, True])
Expand Down
55 changes: 30 additions & 25 deletions pandas/tests/arrays/categorical/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,15 @@ def test_rename_categories(self):
)
tm.assert_index_equal(cat.categories, Index([1, 2, 3]))

# Lengthen
with pytest.raises(ValueError):
cat.rename_categories([1, 2, 3, 4])

# Shorten
with pytest.raises(ValueError):
cat.rename_categories([1, 2])
@pytest.mark.parametrize("new_categories", [[1, 2, 3, 4], [1, 2]])
def test_rename_categories_wrong_length_raises(self, new_categories):
cat = Categorical(["a", "b", "c", "a"])
msg = (
"new categories need to have the same number of items as the"
" old categories!"
)
with pytest.raises(ValueError, match=msg):
cat.rename_categories(new_categories)

def test_rename_categories_series(self):
# https://github.com/pandas-dev/pandas/issues/17981
Expand Down Expand Up @@ -149,19 +151,19 @@ def test_reorder_categories(self):
assert res is None
tm.assert_categorical_equal(cat, new)

# not all "old" included in "new"
@pytest.mark.parametrize(
"new_categories",
[
["a"], # not all "old" included in "new"
["a", "b", "d"], # still not all "old" in "new"
["a", "b", "c", "d"], # all "old" included in "new", but too long
],
)
def test_reorder_categories_raises(self, new_categories):
cat = Categorical(["a", "b", "c", "a"], ordered=True)

with pytest.raises(ValueError):
cat.reorder_categories(["a"])

# still not all "old" in "new"
with pytest.raises(ValueError):
cat.reorder_categories(["a", "b", "d"])

# all "old" included in "new", but too long
with pytest.raises(ValueError):
cat.reorder_categories(["a", "b", "c", "d"])
msg = "items in new_categories are not the same as in old categories"
with pytest.raises(ValueError, match=msg):
cat.reorder_categories(new_categories)

def test_add_categories(self):
cat = Categorical(["a", "b", "c", "a"], ordered=True)
Expand All @@ -184,10 +186,6 @@ def test_add_categories(self):
tm.assert_categorical_equal(cat, new)
assert res is None

# new is in old categories
with pytest.raises(ValueError):
cat.add_categories(["d"])

# GH 9927
cat = Categorical(list("abc"), ordered=True)
expected = Categorical(list("abc"), categories=list("abcde"), ordered=True)
Expand All @@ -201,6 +199,13 @@ def test_add_categories(self):
res = cat.add_categories(["d", "e"])
tm.assert_categorical_equal(res, expected)

def test_add_categories_existing_raises(self):
# new is in old categories
cat = Categorical(["a", "b", "c", "d"], ordered=True)
msg = re.escape("new categories must not include old categories: {'d'}")
with pytest.raises(ValueError, match=msg):
cat.add_categories(["d"])

def test_set_categories(self):
cat = Categorical(["a", "b", "c", "a"], ordered=True)
exp_categories = Index(["c", "b", "a"])
Expand Down Expand Up @@ -453,13 +458,13 @@ def test_codes_immutable(self):
tm.assert_numpy_array_equal(c.codes, exp)

# Assignments to codes should raise
with pytest.raises(ValueError):
with pytest.raises(ValueError, match="cannot set Categorical codes directly"):
c.codes = np.array([0, 1, 2, 0, 1], dtype="int8")

# changes in the codes array should raise
codes = c.codes

with pytest.raises(ValueError):
with pytest.raises(ValueError, match="assignment destination is read-only"):
codes[4] = 1

# But even after getting the codes, the original array should still be
Expand Down
23 changes: 13 additions & 10 deletions pandas/tests/arrays/categorical/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ def test_setitem_different_unordered_raises(self, other):
# GH-24142
target = pd.Categorical(["a", "b"], categories=["a", "b"])
mask = np.array([True, False])
with pytest.raises(ValueError):
msg = "Cannot set a Categorical with another, without identical categories"
with pytest.raises(ValueError, match=msg):
target[mask] = other[mask]

@pytest.mark.parametrize(
Expand All @@ -78,8 +79,8 @@ def test_setitem_same_ordered_rasies(self, other):
# Gh-24142
target = pd.Categorical(["a", "b"], categories=["a", "b"], ordered=True)
mask = np.array([True, False])

with pytest.raises(ValueError):
msg = "Cannot set a Categorical with another, without identical categories"
with pytest.raises(ValueError, match=msg):
target[mask] = other[mask]


Expand Down Expand Up @@ -152,13 +153,15 @@ def test_categories_assigments(self):
tm.assert_numpy_array_equal(s.__array__(), exp)
tm.assert_index_equal(s.categories, Index([1, 2, 3]))

# lengthen
with pytest.raises(ValueError):
s.categories = [1, 2, 3, 4]

# shorten
with pytest.raises(ValueError):
s.categories = [1, 2]
@pytest.mark.parametrize("new_categories", [[1, 2, 3, 4], [1, 2]])
def test_categories_assigments_wrong_length_raises(self, new_categories):
cat = Categorical(["a", "b", "c", "a"])
msg = (
"new categories need to have the same number of items"
" as the old categories!"
)
with pytest.raises(ValueError, match=msg):
cat.categories = new_categories

# Combinations of sorted/unique:
@pytest.mark.parametrize(
Expand Down
45 changes: 26 additions & 19 deletions pandas/tests/arrays/categorical/test_operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,25 @@ def test_comparisons(self):
tm.assert_numpy_array_equal(res, exp)

# Only categories with same categories can be compared
with pytest.raises(TypeError):
msg = "Categoricals can only be compared if 'categories' are the same"
with pytest.raises(TypeError, match=msg):
cat > cat_rev

cat_rev_base2 = Categorical(["b", "b", "b"], categories=["c", "b", "a", "d"])

with pytest.raises(TypeError):
msg = (
"Categoricals can only be compared if 'categories' are the same. "
"Categories are different lengths"
)
with pytest.raises(TypeError, match=msg):
cat_rev > cat_rev_base2

# Only categories with same ordering information can be compared
cat_unorderd = cat.set_ordered(False)
assert not (cat > cat).any()

with pytest.raises(TypeError):
msg = "Categoricals can only be compared if 'ordered' is the same"
with pytest.raises(TypeError, match=msg):
cat > cat_unorderd

# comparison (in both directions) with Series will raise
Expand Down Expand Up @@ -131,18 +137,6 @@ def test_compare_frame(self):

df = DataFrame(cat)

for op in [
operator.eq,
operator.ne,
operator.ge,
operator.gt,
operator.le,
operator.lt,
]:
with pytest.raises(ValueError):
# alignment raises unless we transpose
op(cat, df)

result = cat == df.T
expected = DataFrame([[True, True, True, True]])
tm.assert_frame_equal(result, expected)
Expand All @@ -151,6 +145,15 @@ def test_compare_frame(self):
expected = DataFrame([[False, True, True, False]])
tm.assert_frame_equal(result, expected)

def test_compare_frame_raises(self, all_compare_operators):
# alignment raises unless we transpose
op = getattr(operator, all_compare_operators)
cat = Categorical(["a", "b", 2, "a"])
df = DataFrame(cat)
msg = "Unable to coerce to Series, length must be 1: given 4"
with pytest.raises(ValueError, match=msg):
op(cat, df)

def test_datetime_categorical_comparison(self):
dt_cat = Categorical(date_range("2014-01-01", periods=3), ordered=True)
tm.assert_numpy_array_equal(dt_cat > dt_cat[0], np.array([False, True, True]))
Expand Down Expand Up @@ -255,7 +258,8 @@ def test_comparisons(self, data, reverse, base):
tm.assert_numpy_array_equal(res_rev.values, exp_rev2)

# Only categories with same categories can be compared
with pytest.raises(TypeError):
msg = "Categoricals can only be compared if 'categories' are the same"
with pytest.raises(TypeError, match=msg):
cat > cat_rev

# categorical cannot be compared to Series or numpy array, and also
Expand Down Expand Up @@ -367,7 +371,9 @@ def test_numeric_like_ops(self):

# numpy ops
s = Series(Categorical([1, 2, 3, 4]))
with pytest.raises(TypeError):
with pytest.raises(
TypeError, match="Categorical cannot perform the operation sum"
):
np.sum(s)

# numeric ops on a Series
Expand All @@ -384,7 +390,8 @@ def test_numeric_like_ops(self):
getattr(s, op)(2)

# invalid ufunc
with pytest.raises(TypeError):
msg = "Object with dtype category cannot perform the numpy op log"
with pytest.raises(TypeError, match=msg):
np.log(s)

def test_contains(self):
Expand All @@ -394,7 +401,7 @@ def test_contains(self):
assert "b" in c
assert "z" not in c
assert np.nan not in c
with pytest.raises(TypeError):
with pytest.raises(TypeError, match="unhashable type: 'list'"):
assert [1] in c

# assert codes NOT in index
Expand Down