Skip to content

Commit

Permalink
STY: use pytest.raises context manager (indexes) (#25447)
Browse files Browse the repository at this point in the history
  • Loading branch information
simonjayhawkins authored and jreback committed Feb 28, 2019
1 parent 778affc commit 72367b7
Show file tree
Hide file tree
Showing 11 changed files with 222 additions and 102 deletions.
38 changes: 26 additions & 12 deletions pandas/tests/indexes/interval/test_interval.py
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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):

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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading

0 comments on commit 72367b7

Please sign in to comment.