Skip to content

Commit

Permalink
TST: Remove inheritance from pandas/tests/indexes (pandas-dev#53544)
Browse files Browse the repository at this point in the history
* Refactor test/indexes

* Address failures
  • Loading branch information
mroeschke authored and im-vinicius committed Jul 8, 2023
1 parent 365f287 commit db3f6bc
Show file tree
Hide file tree
Showing 10 changed files with 253 additions and 348 deletions.
31 changes: 5 additions & 26 deletions pandas/tests/indexes/categorical/test_category.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,15 @@
CategoricalIndex,
Index,
)
from pandas.tests.indexes.common import Base


class TestCategoricalIndex(Base):
_index_cls = CategoricalIndex

class TestCategoricalIndex:
@pytest.fixture
def simple_index(self) -> CategoricalIndex:
return self._index_cls(list("aabbca"), categories=list("cab"), ordered=False)

@pytest.fixture
def index(self):
return tm.makeCategoricalIndex(100)

def create_index(self, *, categories=None, ordered=False):
if categories is None:
categories = list("cab")
return CategoricalIndex(list("aabbca"), categories=categories, ordered=ordered)
return CategoricalIndex(list("aabbca"), categories=list("cab"), ordered=False)

def test_can_hold_identifiers(self):
idx = self.create_index(categories=list("abcd"))
idx = CategoricalIndex(list("aabbca"), categories=None, ordered=False)
key = idx[0]
assert idx._can_hold_identifiers_and_holds_name(key) is True

Expand Down Expand Up @@ -247,12 +235,13 @@ def test_identical(self):
assert ci1.identical(ci1.copy())
assert not ci1.identical(ci2)

def test_ensure_copied_data(self, index):
def test_ensure_copied_data(self):
# gh-12309: Check the "copy" argument of each
# Index.__new__ is honored.
#
# Must be tested separately from other indexes because
# self.values is not an ndarray.
index = tm.makeCategoricalIndex(10)

result = CategoricalIndex(index.values, copy=True)
tm.assert_index_equal(index, result)
Expand All @@ -267,18 +256,8 @@ def test_frame_repr(self):
expected = " A\na 1\nb 2\nc 3"
assert result == expected

def test_reindex_base(self):
# See test_reindex.py
pass

def test_map_str(self):
# See test_map.py
pass


class TestCategoricalIndex2:
# Tests that are not overriding a test in Base

def test_view_i8(self):
# GH#25464
ci = tm.makeCategoricalIndex(100)
Expand Down
37 changes: 4 additions & 33 deletions pandas/tests/indexes/datetimes/test_datetimelike.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,10 @@
""" generic tests from the Datetimelike class """
import pytest
from pandas import date_range

from pandas import (
DatetimeIndex,
date_range,
)
import pandas._testing as tm
from pandas.tests.indexes.datetimelike import DatetimeLike


class TestDatetimeIndex(DatetimeLike):
_index_cls = DatetimeIndex

@pytest.fixture
def simple_index(self) -> DatetimeIndex:
return date_range("20130101", periods=5)

@pytest.fixture(
params=[tm.makeDateIndex(10), date_range("20130110", periods=10, freq="-1D")],
ids=["index_inc", "index_dec"],
)
def index(self, request):
return request.param

def test_format(self, simple_index):
class TestDatetimeIndex:
def test_format(self):
# GH35439
idx = simple_index
idx = date_range("20130101", periods=5)
expected = [f"{x:%Y-%m-%d}" for x in idx]
assert idx.format() == expected

def test_shift(self):
pass # handled in test_ops

def test_intersection(self):
pass # handled in test_setops

def test_union(self):
pass # handled in test_setops
20 changes: 3 additions & 17 deletions pandas/tests/indexes/interval/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,24 @@

from pandas import IntervalIndex
import pandas._testing as tm
from pandas.tests.indexes.common import Base


class TestBase(Base):
class TestInterval:
"""
Tests specific to the shared common index tests; unrelated tests should be placed
in test_interval.py or the specific test file (e.g. test_astype.py)
"""

_index_cls = IntervalIndex

@pytest.fixture
def simple_index(self) -> IntervalIndex:
return self._index_cls.from_breaks(range(11), closed="right")
return IntervalIndex.from_breaks(range(11), closed="right")

@pytest.fixture
def index(self):
return tm.makeIntervalIndex(10)

def create_index(self, *, closed="right"):
return IntervalIndex.from_breaks(range(11), closed=closed)

def test_repr_max_seq_item_setting(self):
# override base test: not a valid repr as we use interval notation
pass

def test_repr_roundtrip(self):
# override base test: not a valid repr as we use interval notation
pass

def test_take(self, closed):
index = self.create_index(closed=closed)
index = IntervalIndex.from_breaks(range(11), closed=closed)

result = index.take(range(10))
tm.assert_index_equal(result, index)
Expand Down
92 changes: 31 additions & 61 deletions pandas/tests/indexes/numeric/test_numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,17 @@
Series,
)
import pandas._testing as tm
from pandas.tests.indexes.common import NumericBase


class TestFloatNumericIndex(NumericBase):
_index_cls = Index

class TestFloatNumericIndex:
@pytest.fixture(params=[np.float64, np.float32])
def dtype(self, request):
return request.param

@pytest.fixture
def simple_index(self, dtype):
values = np.arange(5, dtype=dtype)
return self._index_cls(values)
return Index(values)

@pytest.fixture(
params=[
Expand All @@ -32,15 +29,15 @@ def simple_index(self, dtype):
ids=["mixed", "float", "mixed_dec", "float_dec"],
)
def index(self, request, dtype):
return self._index_cls(request.param, dtype=dtype)
return Index(request.param, dtype=dtype)

@pytest.fixture
def mixed_index(self, dtype):
return self._index_cls([1.5, 2, 3, 4, 5], dtype=dtype)
return Index([1.5, 2, 3, 4, 5], dtype=dtype)

@pytest.fixture
def float_index(self, dtype):
return self._index_cls([0.0, 2.5, 5.0, 7.5, 10.0], dtype=dtype)
return Index([0.0, 2.5, 5.0, 7.5, 10.0], dtype=dtype)

def test_repr_roundtrip(self, index):
tm.assert_index_equal(eval(repr(index)), index, exact=True)
Expand All @@ -49,16 +46,16 @@ def check_coerce(self, a, b, is_float_index=True):
assert a.equals(b)
tm.assert_index_equal(a, b, exact=False)
if is_float_index:
assert isinstance(b, self._index_cls)
assert isinstance(b, Index)
else:
assert type(b) is Index

def test_constructor_from_list_no_dtype(self):
index = self._index_cls([1.5, 2.5, 3.5])
index = Index([1.5, 2.5, 3.5])
assert index.dtype == np.float64

def test_constructor(self, dtype):
index_cls = self._index_cls
index_cls = Index

# explicit construction
index = index_cls([1, 2, 3, 4, 5], dtype=dtype)
Expand Down Expand Up @@ -97,7 +94,7 @@ def test_constructor(self, dtype):
assert pd.isna(result.values).all()

def test_constructor_invalid(self):
index_cls = self._index_cls
index_cls = Index
cls_name = index_cls.__name__
# invalid
msg = (
Expand Down Expand Up @@ -131,7 +128,7 @@ def test_type_coercion_fail(self, any_int_numpy_dtype):
Index([1, 2, 3.5], dtype=any_int_numpy_dtype)

def test_equals_numeric(self):
index_cls = self._index_cls
index_cls = Index

idx = index_cls([1.0, 2.0])
assert idx.equals(idx)
Expand All @@ -156,7 +153,7 @@ def test_equals_numeric(self):
),
)
def test_equals_numeric_other_index_type(self, other):
idx = self._index_cls([1.0, 2.0])
idx = Index([1.0, 2.0])
assert idx.equals(other)
assert other.equals(idx)

Expand Down Expand Up @@ -198,13 +195,13 @@ def test_lookups_datetimelike_values(self, vals, dtype):
assert isinstance(result, type(expected)) and result == expected

def test_doesnt_contain_all_the_things(self):
idx = self._index_cls([np.nan])
idx = Index([np.nan])
assert not idx.isin([0]).item()
assert not idx.isin([1]).item()
assert idx.isin([np.nan]).item()

def test_nan_multiple_containment(self):
index_cls = self._index_cls
index_cls = Index

idx = index_cls([1.0, np.nan])
tm.assert_numpy_array_equal(idx.isin([1.0]), np.array([True, False]))
Expand All @@ -215,7 +212,7 @@ def test_nan_multiple_containment(self):
tm.assert_numpy_array_equal(idx.isin([np.nan]), np.array([False, False]))

def test_fillna_float64(self):
index_cls = self._index_cls
index_cls = Index
# GH 11343
idx = Index([1.0, np.nan, 3.0], dtype=float, name="x")
# can't downcast
Expand All @@ -231,11 +228,17 @@ def test_fillna_float64(self):
tm.assert_index_equal(idx.fillna("obj"), exp, exact=True)


class NumericInt(NumericBase):
_index_cls = Index
class TestNumericInt:
@pytest.fixture(params=[np.int64, np.int32, np.int16, np.int8, np.uint64])
def dtype(self, request):
return request.param

@pytest.fixture
def simple_index(self, dtype):
return Index(range(0, 20, 2), dtype=dtype)

def test_is_monotonic(self):
index_cls = self._index_cls
index_cls = Index

index = index_cls([1, 2, 3, 4])
assert index.is_monotonic_increasing is True
Expand All @@ -257,7 +260,7 @@ def test_is_monotonic(self):
assert index._is_strictly_monotonic_decreasing is True

def test_is_strictly_monotonic(self):
index_cls = self._index_cls
index_cls = Index

index = index_cls([1, 1, 2, 3])
assert index.is_monotonic_increasing is True
Expand Down Expand Up @@ -303,7 +306,7 @@ def test_cant_or_shouldnt_cast(self, dtype):
# can't
data = ["foo", "bar", "baz"]
with pytest.raises(ValueError, match=msg):
self._index_cls(data, dtype=dtype)
Index(data, dtype=dtype)

def test_view_index(self, simple_index):
index = simple_index
Expand All @@ -315,27 +318,17 @@ def test_prevent_casting(self, simple_index):
assert result.dtype == np.object_


class TestIntNumericIndex(NumericInt):
class TestIntNumericIndex:
@pytest.fixture(params=[np.int64, np.int32, np.int16, np.int8])
def dtype(self, request):
return request.param

@pytest.fixture
def simple_index(self, dtype):
return self._index_cls(range(0, 20, 2), dtype=dtype)

@pytest.fixture(
params=[range(0, 20, 2), range(19, -1, -1)], ids=["index_inc", "index_dec"]
)
def index(self, request, dtype):
return self._index_cls(request.param, dtype=dtype)

def test_constructor_from_list_no_dtype(self):
index = self._index_cls([1, 2, 3])
index = Index([1, 2, 3])
assert index.dtype == np.int64

def test_constructor(self, dtype):
index_cls = self._index_cls
index_cls = Index

# scalar raise Exception
msg = (
Expand Down Expand Up @@ -379,7 +372,7 @@ def test_constructor(self, dtype):
tm.assert_index_equal(idx, expected)

def test_constructor_corner(self, dtype):
index_cls = self._index_cls
index_cls = Index

arr = np.array([1, 2, 3, 4], dtype=object)

Expand Down Expand Up @@ -426,7 +419,7 @@ def test_constructor_np_unsigned(self, any_unsigned_int_numpy_dtype):
def test_coerce_list(self):
# coerce things
arr = Index([1, 2, 3, 4])
assert isinstance(arr, self._index_cls)
assert isinstance(arr, Index)

# but not if explicit dtype passed
arr = Index([1, 2, 3, 4], dtype=object)
Expand All @@ -436,10 +429,8 @@ def test_coerce_list(self):
class TestFloat16Index:
# float 16 indexes not supported
# GH 49535
_index_cls = Index

def test_constructor(self):
index_cls = self._index_cls
index_cls = Index
dtype = np.float16

msg = "float16 indexes are not supported"
Expand Down Expand Up @@ -471,27 +462,6 @@ def test_constructor(self):
index_cls(np.array([np.nan]), dtype=dtype)


class TestUIntNumericIndex(NumericInt):
@pytest.fixture(params=[np.uint64])
def dtype(self, request):
return request.param

@pytest.fixture
def simple_index(self, dtype):
# compat with shared Int64/Float64 tests
return self._index_cls(np.arange(5, dtype=dtype))

@pytest.fixture(
params=[
[2**63, 2**63 + 10, 2**63 + 15, 2**63 + 20, 2**63 + 25],
[2**63 + 25, 2**63 + 20, 2**63 + 15, 2**63 + 10, 2**63],
],
ids=["index_inc", "index_dec"],
)
def index(self, request):
return self._index_cls(request.param, dtype=np.uint64)


@pytest.mark.parametrize(
"box",
[list, lambda x: np.array(x, dtype=object), lambda x: Index(x, dtype=object)],
Expand Down
Loading

0 comments on commit db3f6bc

Please sign in to comment.