Skip to content
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

STY: use pytest.raises context manager (indexes) #25447

Merged
merged 8 commits into from Feb 28, 2019
38 changes: 26 additions & 12 deletions pandas/tests/indexes/interval/test_interval.py
Expand Up @@ -403,13 +403,16 @@ def test_get_item(self, closed):

# To be removed, replaced by test_interval_new.py (see #16316, #16386)
def test_get_loc_value(self):
pytest.raises(KeyError, self.index.get_loc, 0)
with pytest.raises(KeyError, match="^0$"):
self.index.get_loc(0)
assert self.index.get_loc(0.5) == 0
assert self.index.get_loc(1) == 0
assert self.index.get_loc(1.5) == 1
assert self.index.get_loc(2) == 1
pytest.raises(KeyError, self.index.get_loc, -1)
pytest.raises(KeyError, self.index.get_loc, 3)
with pytest.raises(KeyError, match="^-1$"):
self.index.get_loc(-1)
with pytest.raises(KeyError, match="^3$"):
self.index.get_loc(3)

idx = IntervalIndex.from_tuples([(0, 2), (1, 3)])
assert idx.get_loc(0.5) == 0
Expand All @@ -419,10 +422,12 @@ def test_get_loc_value(self):
tm.assert_numpy_array_equal(np.sort(idx.get_loc(2)),
np.array([0, 1], dtype='intp'))
assert idx.get_loc(3) == 1
pytest.raises(KeyError, idx.get_loc, 3.5)
with pytest.raises(KeyError, match=r"^3\.5$"):
idx.get_loc(3.5)

idx = IntervalIndex.from_arrays([0, 2], [1, 3])
pytest.raises(KeyError, idx.get_loc, 1.5)
with pytest.raises(KeyError, match=r"^1\.5$"):
idx.get_loc(1.5)

# To be removed, replaced by test_interval_new.py (see #16316, #16386)
def slice_locs_cases(self, breaks):
Expand Down Expand Up @@ -486,17 +491,22 @@ def test_slice_locs_decreasing_float64(self):
# To be removed, replaced by test_interval_new.py (see #16316, #16386)
def test_slice_locs_fails(self):
index = IntervalIndex.from_tuples([(1, 2), (0, 1), (2, 3)])
with pytest.raises(KeyError):
msg = ("'can only get slices from an IntervalIndex if bounds are"
" non-overlapping and all monotonic increasing or decreasing'")
with pytest.raises(KeyError, match=msg):
index.slice_locs(1, 2)

# To be removed, replaced by test_interval_new.py (see #16316, #16386)
def test_get_loc_interval(self):
assert self.index.get_loc(Interval(0, 1)) == 0
assert self.index.get_loc(Interval(0, 0.5)) == 0
assert self.index.get_loc(Interval(0, 1, 'left')) == 0
pytest.raises(KeyError, self.index.get_loc, Interval(2, 3))
pytest.raises(KeyError, self.index.get_loc,
Interval(-1, 0, 'left'))
msg = r"Interval\(2, 3, closed='right'\)"
with pytest.raises(KeyError, match=msg):
self.index.get_loc(Interval(2, 3))
msg = r"Interval\(-1, 0, closed='left'\)"
with pytest.raises(KeyError, match=msg):
self.index.get_loc(Interval(-1, 0, 'left'))

# Make consistent with test_interval_new.py (see #16316, #16386)
@pytest.mark.parametrize('item', [3, Interval(1, 4)])
Expand Down Expand Up @@ -981,9 +991,11 @@ def test_comparison(self):
self.index > 0
with pytest.raises(TypeError, match='unorderable types'):
self.index <= 0
with pytest.raises(TypeError):
msg = r"unorderable types: Interval\(\) > int\(\)"
with pytest.raises(TypeError, match=msg):
self.index > np.arange(2)
with pytest.raises(ValueError):
msg = "Lengths must match to compare"
with pytest.raises(ValueError, match=msg):
self.index > np.arange(3)

def test_missing_values(self, closed):
Expand All @@ -993,7 +1005,9 @@ def test_missing_values(self, closed):
[np.nan, 0, 1], [np.nan, 1, 2], closed=closed)
assert idx.equals(idx2)

with pytest.raises(ValueError):
msg = ("missing values must be missing in the same location both left"
" and right sides")
with pytest.raises(ValueError, match=msg):
IntervalIndex.from_arrays(
[np.nan, 0, 1], np.array([0, 1, 2]), closed=closed)

Expand Down
47 changes: 29 additions & 18 deletions pandas/tests/indexes/test_base.py
Expand Up @@ -4,6 +4,7 @@
from datetime import datetime, timedelta
import math
import operator
import re
import sys

import numpy as np
Expand Down Expand Up @@ -107,7 +108,10 @@ def test_constructor_copy(self):

def test_constructor_corner(self):
# corner case
pytest.raises(TypeError, Index, 0)
msg = (r"Index\(\.\.\.\) must be called with a collection of some"
" kind, 0 was passed")
with pytest.raises(TypeError, match=msg):
Index(0)

@pytest.mark.parametrize("index_vals", [
[('A', 1), 'B'], ['B', ('A', 1)]])
Expand Down Expand Up @@ -488,21 +492,22 @@ def test_constructor_cast(self):
Index(["a", "b", "c"], dtype=float)

def test_view_with_args(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you mean to just remove this test completely? (and replace with one below)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the original test has been split


restricted = ['unicodeIndex', 'strIndex', 'catIndex', 'boolIndex',
'empty']

for i in restricted:
ind = self.indices[i]

# with arguments
pytest.raises(TypeError, lambda: ind.view('i8'))

# these are ok
for i in list(set(self.indices.keys()) - set(restricted)):
ind = self.indices[i]
ind.view('i8')

# with arguments
@pytest.mark.parametrize('index_type', [
'unicodeIndex',
'strIndex',
pytest.param('catIndex', marks=pytest.mark.xfail(reason="gh-25464")),
'boolIndex',
'empty'])
def test_view_with_args_object_array_raises(self, index_type):
ind = self.indices[index_type]
msg = "Cannot change data-type for object array"
with pytest.raises(TypeError, match=msg):
ind.view('i8')

def test_astype(self):
Expand Down Expand Up @@ -565,8 +570,8 @@ def test_delete(self, pos, expected):

def test_delete_raises(self):
index = Index(['a', 'b', 'c', 'd'], name='index')
with pytest.raises((IndexError, ValueError)):
# either depending on numpy version
msg = "index 5 is out of bounds for axis 0 with size 4"
with pytest.raises(IndexError, match=msg):
index.delete(5)

def test_identical(self):
Expand Down Expand Up @@ -683,7 +688,9 @@ def test_empty_fancy_raises(self, attr):

assert index[[]].identical(empty_index)
# np.ndarray only accepts ndarray of int & bool dtypes, so should Index
pytest.raises(IndexError, index.__getitem__, empty_farr)
msg = r"arrays used as indices must be of integer \(or boolean\) type"
with pytest.raises(IndexError, match=msg):
index[empty_farr]

@pytest.mark.parametrize("sort", [None, False])
def test_intersection(self, sort):
Expand Down Expand Up @@ -1426,13 +1433,14 @@ def test_get_indexer_strings(self, method, expected):
def test_get_indexer_strings_raises(self):
index = pd.Index(['b', 'c'])

with pytest.raises(TypeError):
msg = r"unsupported operand type\(s\) for -: 'str' and 'str'"
with pytest.raises(TypeError, match=msg):
index.get_indexer(['a', 'b', 'c', 'd'], method='nearest')

with pytest.raises(TypeError):
with pytest.raises(TypeError, match=msg):
index.get_indexer(['a', 'b', 'c', 'd'], method='pad', tolerance=2)

with pytest.raises(TypeError):
with pytest.raises(TypeError, match=msg):
index.get_indexer(['a', 'b', 'c', 'd'], method='pad',
tolerance=[2, 2, 2, 2])

Expand Down Expand Up @@ -1685,8 +1693,11 @@ def test_drop_tuple(self, values, to_drop):
tm.assert_index_equal(result, expected)

removed = index.drop(to_drop[1])
msg = r"\"\[{}\] not found in axis\"".format(
re.escape(to_drop[1].__repr__()))
for drop_me in to_drop[1], [to_drop[1]]:
pytest.raises(KeyError, removed.drop, drop_me)
with pytest.raises(KeyError, match=msg):
removed.drop(drop_me)

@pytest.mark.parametrize("method,expected,sort", [
('intersection', np.array([(1, 'A'), (2, 'A'), (1, 'B'), (2, 'B')],
Expand Down
77 changes: 46 additions & 31 deletions pandas/tests/indexes/test_category.py
Expand Up @@ -181,18 +181,21 @@ def test_create_categorical(self):
expected = Categorical(['a', 'b', 'c'])
tm.assert_categorical_equal(result, expected)

def test_disallow_set_ops(self):

@pytest.mark.parametrize('func,op_name', [
(lambda idx: idx - idx, '__sub__'),
(lambda idx: idx + idx, '__add__'),
(lambda idx: idx - ['a', 'b'], '__sub__'),
(lambda idx: idx + ['a', 'b'], '__add__'),
(lambda idx: ['a', 'b'] - idx, '__rsub__'),
(lambda idx: ['a', 'b'] + idx, '__radd__'),
])
def test_disallow_set_ops(self, func, op_name):
# GH 10039
# set ops (+/-) raise TypeError
idx = pd.Index(pd.Categorical(['a', 'b']))

pytest.raises(TypeError, lambda: idx - idx)
pytest.raises(TypeError, lambda: idx + idx)
pytest.raises(TypeError, lambda: idx - ['a', 'b'])
pytest.raises(TypeError, lambda: idx + ['a', 'b'])
pytest.raises(TypeError, lambda: ['a', 'b'] - idx)
pytest.raises(TypeError, lambda: ['a', 'b'] + idx)
msg = "cannot perform {} with this index type: CategoricalIndex"
with pytest.raises(TypeError, match=msg.format(op_name)):
func(idx)

def test_method_delegation(self):

Expand Down Expand Up @@ -231,8 +234,9 @@ def test_method_delegation(self):
list('aabbca'), categories=list('cabdef'), ordered=True))

# invalid
pytest.raises(ValueError, lambda: ci.set_categories(
list('cab'), inplace=True))
msg = "cannot use inplace with CategoricalIndex"
with pytest.raises(ValueError, match=msg):
ci.set_categories(list('cab'), inplace=True)

def test_contains(self):

Expand Down Expand Up @@ -357,20 +361,21 @@ def test_append(self):
tm.assert_index_equal(result, ci, exact=True)

# appending with different categories or reordered is not ok
pytest.raises(
TypeError,
lambda: ci.append(ci.values.set_categories(list('abcd'))))
pytest.raises(
TypeError,
lambda: ci.append(ci.values.reorder_categories(list('abc'))))
msg = "all inputs must be Index"
with pytest.raises(TypeError, match=msg):
ci.append(ci.values.set_categories(list('abcd')))
with pytest.raises(TypeError, match=msg):
ci.append(ci.values.reorder_categories(list('abc')))

# with objects
result = ci.append(Index(['c', 'a']))
expected = CategoricalIndex(list('aabbcaca'), categories=categories)
tm.assert_index_equal(result, expected, exact=True)

# invalid objects
pytest.raises(TypeError, lambda: ci.append(Index(['a', 'd'])))
msg = "cannot append a non-category item to a CategoricalIndex"
with pytest.raises(TypeError, match=msg):
ci.append(Index(['a', 'd']))

# GH14298 - if base object is not categorical -> coerce to object
result = Index(['c', 'a']).append(ci)
Expand Down Expand Up @@ -406,7 +411,10 @@ def test_insert(self):
tm.assert_index_equal(result, expected, exact=True)

# invalid
pytest.raises(TypeError, lambda: ci.insert(0, 'd'))
msg = ("cannot insert an item into a CategoricalIndex that is not"
" already an existing category")
with pytest.raises(TypeError, match=msg):
ci.insert(0, 'd')

# GH 18295 (test missing)
expected = CategoricalIndex(['a', np.nan, 'a', 'b', 'c', 'b'])
Expand Down Expand Up @@ -633,12 +641,16 @@ def test_get_indexer(self):
r1 = idx1.get_indexer(idx2)
assert_almost_equal(r1, np.array([0, 1, 2, -1], dtype=np.intp))

pytest.raises(NotImplementedError,
lambda: idx2.get_indexer(idx1, method='pad'))
pytest.raises(NotImplementedError,
lambda: idx2.get_indexer(idx1, method='backfill'))
pytest.raises(NotImplementedError,
lambda: idx2.get_indexer(idx1, method='nearest'))
msg = ("method='pad' and method='backfill' not implemented yet for"
" CategoricalIndex")
with pytest.raises(NotImplementedError, match=msg):
idx2.get_indexer(idx1, method='pad')
with pytest.raises(NotImplementedError, match=msg):
idx2.get_indexer(idx1, method='backfill')

msg = "method='nearest' not implemented yet for CategoricalIndex"
with pytest.raises(NotImplementedError, match=msg):
idx2.get_indexer(idx1, method='nearest')

def test_get_loc(self):
# GH 12531
Expand Down Expand Up @@ -776,12 +788,15 @@ def test_equals_categorical(self):
# invalid comparisons
with pytest.raises(ValueError, match="Lengths must match"):
ci1 == Index(['a', 'b', 'c'])
pytest.raises(TypeError, lambda: ci1 == ci2)
pytest.raises(
TypeError, lambda: ci1 == Categorical(ci1.values, ordered=False))
pytest.raises(
TypeError,
lambda: ci1 == Categorical(ci1.values, categories=list('abc')))

msg = ("categorical index comparisons must have the same categories"
" and ordered attributes")
with pytest.raises(TypeError, match=msg):
ci1 == ci2
with pytest.raises(TypeError, match=msg):
ci1 == Categorical(ci1.values, ordered=False)
with pytest.raises(TypeError, match=msg):
ci1 == Categorical(ci1.values, categories=list('abc'))

# tests
# make sure that we are testing for category inclusion properly
Expand Down
20 changes: 16 additions & 4 deletions pandas/tests/indexes/test_common.py
Expand Up @@ -3,6 +3,8 @@
any index subclass. Makes use of the `indices` fixture defined
in pandas/tests/indexes/conftest.py.
"""
import re

import numpy as np
import pytest

Expand Down Expand Up @@ -189,8 +191,14 @@ def test_unique(self, indices):
result = indices.unique(level=level)
tm.assert_index_equal(result, expected)

for level in 3, 'wrong':
pytest.raises((IndexError, KeyError), indices.unique, level=level)
msg = "Too many levels: Index has only 1 level, not 4"
with pytest.raises(IndexError, match=msg):
indices.unique(level=3)

msg = r"Level wrong must be same as name \({}\)".format(
re.escape(indices.name.__repr__()))
with pytest.raises(KeyError, match=msg):
indices.unique(level='wrong')

def test_get_unique_index(self, indices):
# MultiIndex tested separately
Expand Down Expand Up @@ -239,12 +247,16 @@ def test_get_unique_index(self, indices):
tm.assert_index_equal(result, expected)

def test_sort(self, indices):
pytest.raises(TypeError, indices.sort)
msg = "cannot sort an Index object in-place, use sort_values instead"
with pytest.raises(TypeError, match=msg):
indices.sort()

def test_mutability(self, indices):
if not len(indices):
pytest.skip('Skip check for empty Index')
pytest.raises(TypeError, indices.__setitem__, 0, indices[0])
msg = "Index does not support mutable operations"
with pytest.raises(TypeError, match=msg):
indices[0] = indices[0]

def test_view(self, indices):
assert indices.view().name == indices.name
Expand Down