From a66e68e031ea4be16a5cbb05881334a303efa67a Mon Sep 17 00:00:00 2001 From: tp Date: Wed, 28 Apr 2021 09:53:11 +0100 Subject: [PATCH 1/4] REF: tests.indexes.numeric.py --- .../indexes/categorical/test_category.py | 2 +- pandas/tests/indexes/common.py | 6 +- pandas/tests/indexes/datetimelike.py | 6 +- .../indexes/datetimes/test_datetimelike.py | 2 +- pandas/tests/indexes/interval/test_base.py | 2 +- pandas/tests/indexes/period/test_period.py | 4 +- pandas/tests/indexes/ranges/test_range.py | 4 +- pandas/tests/indexes/test_base.py | 4 +- pandas/tests/indexes/test_numeric.py | 280 ++++++++++-------- .../indexes/timedeltas/test_timedelta.py | 2 +- 10 files changed, 176 insertions(+), 136 deletions(-) diff --git a/pandas/tests/indexes/categorical/test_category.py b/pandas/tests/indexes/categorical/test_category.py index 678344f5b6909..f0d2e9ee08fe9 100644 --- a/pandas/tests/indexes/categorical/test_category.py +++ b/pandas/tests/indexes/categorical/test_category.py @@ -17,7 +17,7 @@ class TestCategoricalIndex(Base): - _holder = CategoricalIndex + _index_cls = CategoricalIndex @pytest.fixture def index(self, request): diff --git a/pandas/tests/indexes/common.py b/pandas/tests/indexes/common.py index ab2b2db7eec53..c80576d85c1c3 100644 --- a/pandas/tests/indexes/common.py +++ b/pandas/tests/indexes/common.py @@ -31,7 +31,7 @@ class Base: """ base class for index sub-class tests """ - _holder: Type[Index] + _index_cls: Type[Index] def create_index(self) -> Index: raise NotImplementedError("Method not implemented") @@ -45,7 +45,7 @@ def test_pickle_compat_construction(self): r"__new__\(\) takes at least 2 arguments \(1 given\)" ) with pytest.raises(TypeError, match=msg): - self._holder() + self._index_cls() @pytest.mark.parametrize("name", [None, "new_name"]) def test_to_frame(self, name): @@ -495,7 +495,7 @@ def test_format(self): def test_format_empty(self): # GH35712 - empty_idx = self._holder([]) + empty_idx = self._index_cls([]) assert empty_idx.format() == [] assert empty_idx.format(name=True) == [""] diff --git a/pandas/tests/indexes/datetimelike.py b/pandas/tests/indexes/datetimelike.py index 4c8ab27d2c824..5f17b00b8193b 100644 --- a/pandas/tests/indexes/datetimelike.py +++ b/pandas/tests/indexes/datetimelike.py @@ -51,11 +51,11 @@ def test_view(self): i = self.create_index() i_view = i.view("i8") - result = self._holder(i) + result = self._index_cls(i) tm.assert_index_equal(result, i) - i_view = i.view(self._holder) - result = self._holder(i) + i_view = i.view(self._index_cls) + result = self._index_cls(i) tm.assert_index_equal(result, i_view) def test_map_callable(self): diff --git a/pandas/tests/indexes/datetimes/test_datetimelike.py b/pandas/tests/indexes/datetimes/test_datetimelike.py index 94303359958b3..0a686a4eb8b79 100644 --- a/pandas/tests/indexes/datetimes/test_datetimelike.py +++ b/pandas/tests/indexes/datetimes/test_datetimelike.py @@ -10,7 +10,7 @@ class TestDatetimeIndex(DatetimeLike): - _holder = DatetimeIndex + _index_cls = DatetimeIndex @pytest.fixture( params=[tm.makeDateIndex(10), date_range("20130110", periods=10, freq="-1D")], diff --git a/pandas/tests/indexes/interval/test_base.py b/pandas/tests/indexes/interval/test_base.py index 8bf418a2fc731..8a6deb0ebdda2 100644 --- a/pandas/tests/indexes/interval/test_base.py +++ b/pandas/tests/indexes/interval/test_base.py @@ -16,7 +16,7 @@ class TestBase(Base): in test_interval.py or the specific test file (e.g. test_astype.py) """ - _holder = IntervalIndex + _index_cls = IntervalIndex @pytest.fixture def index(self): diff --git a/pandas/tests/indexes/period/test_period.py b/pandas/tests/indexes/period/test_period.py index 032b376f6d6a9..bc6c9fb06ac94 100644 --- a/pandas/tests/indexes/period/test_period.py +++ b/pandas/tests/indexes/period/test_period.py @@ -19,7 +19,7 @@ class TestPeriodIndex(DatetimeLike): - _holder = PeriodIndex + _index_cls = PeriodIndex @pytest.fixture( params=[ @@ -357,7 +357,7 @@ def test_map(self): def test_format_empty(self): # GH35712 - empty_idx = self._holder([], freq="A") + empty_idx = self._index_cls([], freq="A") assert empty_idx.format() == [] assert empty_idx.format(name=True) == [""] diff --git a/pandas/tests/indexes/ranges/test_range.py b/pandas/tests/indexes/ranges/test_range.py index 3f77c2c974842..9dc7116f6ae8c 100644 --- a/pandas/tests/indexes/ranges/test_range.py +++ b/pandas/tests/indexes/ranges/test_range.py @@ -21,7 +21,7 @@ class TestRangeIndex(Numeric): - _holder = RangeIndex + _index_cls = RangeIndex @pytest.fixture( params=[ @@ -506,7 +506,7 @@ def test_engineless_lookup(self): def test_format_empty(self): # GH35712 - empty_idx = self._holder(0) + empty_idx = self._index_cls(0) assert empty_idx.format() == [] assert empty_idx.format(name=True) == [""] diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index 1e9348dc410d7..0067bc82e301b 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -46,7 +46,7 @@ class TestIndex(Base): - _holder = Index + _index_cls = Index def create_index(self) -> Index: return Index(list("abcde")) @@ -1415,7 +1415,7 @@ class TestMixedIntIndex(Base): # Mostly the tests from common.py for which the results differ # in py2 and py3 because ints and strings are uncomparable in py3 # (GH 13514) - _holder = Index + _index_cls = Index @pytest.fixture(params=[[0, "a", 1, "b", 2, "c"]], ids=["mixedIndex"]) def index(self, request): diff --git a/pandas/tests/indexes/test_numeric.py b/pandas/tests/indexes/test_numeric.py index 99dadfba4e7aa..a407e82f2e644 100644 --- a/pandas/tests/indexes/test_numeric.py +++ b/pandas/tests/indexes/test_numeric.py @@ -116,7 +116,12 @@ def test_insert_na(self, nulls_fixture): class TestFloat64Index(Numeric): - _holder = Float64Index + _index_cls = Float64Index + _dtype = "float64" + + def create_index(self) -> Float64Index: + values = np.arange(5, dtype=self._dtype) + return self._index_cls(values) @pytest.fixture( params=[ @@ -128,63 +133,74 @@ class TestFloat64Index(Numeric): ids=["mixed", "float", "mixed_dec", "float_dec"], ) def index(self, request): - return Float64Index(request.param) + return self._index_cls(request.param) @pytest.fixture def mixed_index(self): - return Float64Index([1.5, 2, 3, 4, 5]) + return self._index_cls([1.5, 2, 3, 4, 5]) @pytest.fixture def float_index(self): - return Float64Index([0.0, 2.5, 5.0, 7.5, 10.0]) - - def create_index(self) -> Float64Index: - return Float64Index(np.arange(5, dtype="float64")) + return self._index_cls([0.0, 2.5, 5.0, 7.5, 10.0]) def test_repr_roundtrip(self, index): tm.assert_index_equal(eval(repr(index)), index) - def check_is_index(self, i): - assert isinstance(i, Index) - assert not isinstance(i, Float64Index) + def check_is_index(self, idx): + assert isinstance(idx, Index) + assert not isinstance(idx, self._index_cls) 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, Float64Index) + assert isinstance(b, self._index_cls) else: self.check_is_index(b) def test_constructor(self): + index_cls = self._index_cls + dtype = self._dtype # explicit construction - index = Float64Index([1, 2, 3, 4, 5]) - assert isinstance(index, Float64Index) - expected = np.array([1, 2, 3, 4, 5], dtype="float64") + index = index_cls([1, 2, 3, 4, 5]) + + assert isinstance(index, index_cls) + assert index.dtype.type is dtype + + expected = np.array([1, 2, 3, 4, 5], dtype=dtype) tm.assert_numpy_array_equal(index.values, expected) - index = Float64Index(np.array([1, 2, 3, 4, 5])) - assert isinstance(index, Float64Index) - index = Float64Index([1.0, 2, 3, 4, 5]) - assert isinstance(index, Float64Index) - index = Float64Index(np.array([1.0, 2, 3, 4, 5])) - assert isinstance(index, Float64Index) + index = index_cls(np.array([1, 2, 3, 4, 5])) + assert isinstance(index, index_cls) + assert index.dtype.type is dtype + + index = index_cls([1.0, 2, 3, 4, 5]) + assert isinstance(index, index_cls) + assert index.dtype.type is dtype + + index = index_cls(np.array([1.0, 2, 3, 4, 5])) + assert isinstance(index, index_cls) + assert index.dtype.type is dtype assert index.dtype == float - index = Float64Index(np.array([1.0, 2, 3, 4, 5]), dtype=np.float32) - assert isinstance(index, Float64Index) - assert index.dtype == np.float64 + index = index_cls(np.array([1.0, 2, 3, 4, 5]), dtype=np.float32) + assert isinstance(index, index_cls) + assert index.dtype == dtype - index = Float64Index(np.array([1, 2, 3, 4, 5]), dtype=np.float32) - assert isinstance(index, Float64Index) - assert index.dtype == np.float64 + index = index_cls(np.array([1, 2, 3, 4, 5]), dtype=np.float32) + assert isinstance(index, index_cls) + assert index.dtype == dtype # nan handling - result = Float64Index([np.nan, np.nan]) + result = index_cls([np.nan, np.nan]) assert pd.isna(result.values).all() - result = Float64Index(np.array([np.nan])) + + result = index_cls(np.array([np.nan])) assert pd.isna(result.values).all() + result = Index(np.array([np.nan])) + assert isinstance(result, index_cls) + assert result.dtype == dtype assert pd.isna(result.values).all() @pytest.mark.parametrize( @@ -205,14 +221,16 @@ def test_invalid_dtype(self, index, dtype): index([1, 2, 3], dtype=dtype) def test_constructor_invalid(self): + index_cls = self._index_cls + cls_name = index_cls.__name__ # invalid msg = ( - r"Float64Index\(\.\.\.\) must be called with a collection of " + rf"{cls_name}\(\.\.\.\) must be called with a collection of " r"some kind, 0\.0 was passed" ) with pytest.raises(TypeError, match=msg): - Float64Index(0.0) + index_cls(0.0) # 2021-02-1 we get ValueError in numpy 1.20, but not on all builds msg = "|".join( @@ -222,11 +240,11 @@ def test_constructor_invalid(self): ] ) with pytest.raises((TypeError, ValueError), match=msg): - Float64Index(["a", "b", 0.0]) + index_cls(["a", "b", 0.0]) msg = r"float\(\) argument must be a string or a number, not 'Timestamp'" with pytest.raises(TypeError, match=msg): - Float64Index([Timestamp("20130101")]) + index_cls([Timestamp("20130101")]) def test_constructor_coerce(self, mixed_index, float_index): @@ -255,24 +273,25 @@ def test_type_coercion_fail(self, any_int_dtype): def test_type_coercion_valid(self, float_dtype): # There is no Float32Index, so we always # generate Float64Index. - i = Index([1, 2, 3.5], dtype=float_dtype) - tm.assert_index_equal(i, Index([1, 2, 3.5])) + idx = Index([1, 2, 3.5], dtype=float_dtype) + tm.assert_index_equal(idx, Index([1, 2, 3.5])) def test_equals_numeric(self): + index_cls = self._index_cls - i = Float64Index([1.0, 2.0]) - assert i.equals(i) - assert i.identical(i) + idx = index_cls([1.0, 2.0]) + assert idx.equals(idx) + assert idx.identical(idx) - i2 = Float64Index([1.0, 2.0]) - assert i.equals(i2) + idx2 = index_cls([1.0, 2.0]) + assert idx.equals(idx2) - i = Float64Index([1.0, np.nan]) - assert i.equals(i) - assert i.identical(i) + idx = index_cls([1.0, np.nan]) + assert idx.equals(idx) + assert idx.identical(idx) - i2 = Float64Index([1.0, np.nan]) - assert i.equals(i2) + idx2 = index_cls([1.0, np.nan]) + assert idx.equals(idx2) @pytest.mark.parametrize( "other", @@ -283,9 +302,9 @@ def test_equals_numeric(self): ), ) def test_equals_numeric_other_index_type(self, other): - i = Float64Index([1.0, 2.0]) - assert i.equals(other) - assert other.equals(i) + idx = self._index_cls([1.0, 2.0]) + assert idx.equals(other) + assert other.equals(idx) @pytest.mark.parametrize( "vals", @@ -295,10 +314,12 @@ def test_equals_numeric_other_index_type(self, other): ], ) def test_lookups_datetimelike_values(self, vals): + dtype = self._dtype + # If we have datetime64 or timedelta64 values, make sure they are # wrappped correctly GH#31163 ser = Series(vals, index=range(3, 6)) - ser.index = ser.index.astype("float64") + ser.index = ser.index.astype(dtype) expected = vals[1] @@ -332,19 +353,21 @@ def test_lookups_datetimelike_values(self, vals): assert isinstance(result, type(expected)) and result == expected def test_doesnt_contain_all_the_things(self): - i = Float64Index([np.nan]) - assert not i.isin([0]).item() - assert not i.isin([1]).item() - assert i.isin([np.nan]).item() + idx = self._index_cls([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): - i = Float64Index([1.0, np.nan]) - tm.assert_numpy_array_equal(i.isin([1.0]), np.array([True, False])) - tm.assert_numpy_array_equal(i.isin([2.0, np.pi]), np.array([False, False])) - tm.assert_numpy_array_equal(i.isin([np.nan]), np.array([False, True])) - tm.assert_numpy_array_equal(i.isin([1.0, np.nan]), np.array([True, True])) - i = Float64Index([1.0, 2.0]) - tm.assert_numpy_array_equal(i.isin([np.nan]), np.array([False, False])) + index_cls = self._index_cls + + idx = index_cls([1.0, np.nan]) + tm.assert_numpy_array_equal(idx.isin([1.0]), np.array([True, False])) + tm.assert_numpy_array_equal(idx.isin([2.0, np.pi]), np.array([False, False])) + tm.assert_numpy_array_equal(idx.isin([np.nan]), np.array([False, True])) + tm.assert_numpy_array_equal(idx.isin([1.0, np.nan]), np.array([True, True])) + idx = index_cls([1.0, 2.0]) + tm.assert_numpy_array_equal(idx.isin([np.nan]), np.array([False, False])) def test_fillna_float64(self): # GH 11343 @@ -354,7 +377,7 @@ def test_fillna_float64(self): tm.assert_index_equal(idx.fillna(0.1), exp) # downcast - exp = Float64Index([1.0, 2.0, 3.0], name="x") + exp = self._index_cls([1.0, 2.0, 3.0], name="x") tm.assert_index_equal(idx.fillna(2), exp) # object @@ -364,30 +387,34 @@ def test_fillna_float64(self): class NumericInt(Numeric): def test_view(self): - i = self._holder([], name="Foo") - i_view = i.view() - assert i_view.name == "Foo" + index_cls = self._index_cls - i_view = i.view(self._dtype) - tm.assert_index_equal(i, self._holder(i_view, name="Foo")) + idx = index_cls([], name="Foo") + idx_view = idx.view() + assert idx_view.name == "Foo" - i_view = i.view(self._holder) - tm.assert_index_equal(i, self._holder(i_view, name="Foo")) + idx_view = idx.view(self._dtype) + tm.assert_index_equal(idx, index_cls(idx_view, name="Foo")) + + idx_view = idx.view(index_cls) + tm.assert_index_equal(idx, index_cls(idx_view, name="Foo")) def test_is_monotonic(self): - index = self._holder([1, 2, 3, 4]) + index_cls = self._index_cls + + index = index_cls([1, 2, 3, 4]) assert index.is_monotonic is True assert index.is_monotonic_increasing is True assert index._is_strictly_monotonic_increasing is True assert index.is_monotonic_decreasing is False assert index._is_strictly_monotonic_decreasing is False - index = self._holder([4, 3, 2, 1]) + index = index_cls([4, 3, 2, 1]) assert index.is_monotonic is False assert index._is_strictly_monotonic_increasing is False assert index._is_strictly_monotonic_decreasing is True - index = self._holder([1]) + index = index_cls([1]) assert index.is_monotonic is True assert index.is_monotonic_increasing is True assert index.is_monotonic_decreasing is True @@ -395,15 +422,17 @@ def test_is_monotonic(self): assert index._is_strictly_monotonic_decreasing is True def test_is_strictly_monotonic(self): - index = self._holder([1, 1, 2, 3]) + index_cls = self._index_cls + + index = index_cls([1, 1, 2, 3]) assert index.is_monotonic_increasing is True assert index._is_strictly_monotonic_increasing is False - index = self._holder([3, 2, 1, 1]) + index = index_cls([3, 2, 1, 1]) assert index.is_monotonic_decreasing is True assert index._is_strictly_monotonic_decreasing is False - index = self._holder([1, 1]) + index = index_cls([1, 1]) assert index.is_monotonic_increasing assert index.is_monotonic_decreasing assert not index._is_strictly_monotonic_increasing @@ -416,19 +445,20 @@ def test_logical_compat(self): def test_identical(self): index = self.create_index() - i = Index(index.copy()) - assert i.identical(index) - same_values_different_type = Index(i, dtype=object) - assert not i.identical(same_values_different_type) + idx = Index(index.copy()) + assert idx.identical(index) - i = index.astype(dtype=object) - i = i.rename("foo") - same_values = Index(i, dtype=object) - assert same_values.identical(i) + same_values_different_type = Index(idx, dtype=object) + assert not idx.identical(same_values_different_type) - assert not i.identical(index) - assert Index(same_values, name="foo", dtype=object).identical(i) + idx = index.astype(dtype=object) + idx = idx.rename("foo") + same_values = Index(idx, dtype=object) + assert same_values.identical(idx) + + assert not idx.identical(index) + assert Index(same_values, name="foo", dtype=object).identical(idx) assert not index.astype(dtype=object).identical(index.astype(dtype=self._dtype)) @@ -440,12 +470,12 @@ def test_cant_or_shouldnt_cast(self): # can't data = ["foo", "bar", "baz"] with pytest.raises(TypeError, match=msg): - self._holder(data) + self._index_cls(data) # shouldn't data = ["0", "1", "2"] with pytest.raises(TypeError, match=msg): - self._holder(data) + self._index_cls(data) def test_view_index(self): index = self.create_index() @@ -458,40 +488,45 @@ def test_prevent_casting(self): class TestInt64Index(NumericInt): + _index_cls = Int64Index _dtype = "int64" - _holder = Int64Index + + def create_index(self, values=None) -> Int64Index: + if values is None: + values = range(0, 20, 2) + + return self._index_cls(values, dtype=self._dtype) @pytest.fixture( params=[range(0, 20, 2), range(19, -1, -1)], ids=["index_inc", "index_dec"] ) def index(self, request): - return Int64Index(request.param) - - def create_index(self) -> Int64Index: - # return Int64Index(np.arange(5, dtype="int64")) - return Int64Index(range(0, 20, 2)) + return self.create_index(request.param) def test_constructor(self): + index_cls = self._index_cls + dtype = self._dtype + # pass list, coerce fine - index = Int64Index([-5, 0, 1, 2]) - expected = Index([-5, 0, 1, 2], dtype=np.int64) + index = index_cls([-5, 0, 1, 2]) + expected = Index([-5, 0, 1, 2], dtype=dtype) tm.assert_index_equal(index, expected) # from iterable - index = Int64Index(iter([-5, 0, 1, 2])) + index = index_cls(iter([-5, 0, 1, 2])) tm.assert_index_equal(index, expected) # scalar raise Exception msg = ( - r"Int64Index\(\.\.\.\) must be called with a collection of some " + rf"{index_cls.__name__}\(\.\.\.\) must be called with a collection of some " "kind, 5 was passed" ) with pytest.raises(TypeError, match=msg): - Int64Index(5) + index_cls(5) # copy arr = index.values - new_index = Int64Index(arr, copy=True) + new_index = index_cls(arr, copy=True) tm.assert_index_equal(new_index, index) val = arr[0] + 3000 @@ -500,29 +535,32 @@ def test_constructor(self): assert new_index[0] != val # interpret list-like - expected = Int64Index([5, 0]) - for cls in [Index, Int64Index]: + expected = index_cls([5, 0]) + for cls in [Index, index_cls]: for idx in [ - cls([5, 0], dtype="int64"), - cls(np.array([5, 0]), dtype="int64"), - cls(Series([5, 0]), dtype="int64"), + cls([5, 0], dtype=dtype), + cls(np.array([5, 0]), dtype=dtype), + cls(Series([5, 0]), dtype=dtype), ]: tm.assert_index_equal(idx, expected) def test_constructor_corner(self): + index_cls = self._index_cls + dtype = self._dtype + arr = np.array([1, 2, 3, 4], dtype=object) - index = Int64Index(arr) - assert index.values.dtype == np.int64 + index = index_cls(arr) + assert index.values.dtype == dtype tm.assert_index_equal(index, Index(arr)) # preventing casting arr = np.array([1, "2", 3, "4"], dtype=object) with pytest.raises(TypeError, match="casting"): - Int64Index(arr) + index_cls(arr) arr_with_floats = [0, 2, 3, 4, 5, 1.25, 3, -1] with pytest.raises(TypeError, match="casting"): - Int64Index(arr_with_floats) + index_cls(arr_with_floats) def test_constructor_coercion_signed_to_unsigned(self, uint_dtype): @@ -534,14 +572,14 @@ def test_constructor_coercion_signed_to_unsigned(self, uint_dtype): def test_constructor_unwraps_index(self): idx = Index([1, 2]) - result = Int64Index(idx) - expected = np.array([1, 2], dtype="int64") + result = self._index_cls(idx) + expected = np.array([1, 2], dtype=self._dtype) tm.assert_numpy_array_equal(result._data, expected) def test_coerce_list(self): # coerce things arr = Index([1, 2, 3, 4]) - assert isinstance(arr, Int64Index) + assert isinstance(arr, self._index_cls) # but not if explicit dtype passed arr = Index([1, 2, 3, 4], dtype=object) @@ -550,8 +588,8 @@ def test_coerce_list(self): class TestUInt64Index(NumericInt): + _index_cls = UInt64Index _dtype = "uint64" - _holder = UInt64Index @pytest.fixture( params=[ @@ -561,22 +599,24 @@ class TestUInt64Index(NumericInt): ids=["index_inc", "index_dec"], ) def index(self, request): - return UInt64Index(request.param) + return self._index_cls(request.param) def create_index(self) -> UInt64Index: # compat with shared Int64/Float64 tests - return UInt64Index(np.arange(5, dtype="uint64")) + return self._index_cls(np.arange(5, dtype=self._dtype)) - def test_constructor(self): - idx = UInt64Index([1, 2, 3]) - res = Index([1, 2, 3], dtype=np.uint64) + def test_constructor(self, dtype): + index_cls = self._index_cls + + idx = index_cls([1, 2, 3]) + res = Index([1, 2, 3], dtype=dtype) tm.assert_index_equal(res, idx) - idx = UInt64Index([1, 2 ** 63]) - res = Index([1, 2 ** 63], dtype=np.uint64) + idx = index_cls([1, 2 ** 63]) + res = Index([1, 2 ** 63], dtype=dtype) tm.assert_index_equal(res, idx) - idx = UInt64Index([1, 2 ** 63]) + idx = index_cls([1, 2 ** 63]) res = Index([1, 2 ** 63]) tm.assert_index_equal(res, idx) @@ -585,8 +625,8 @@ def test_constructor(self): tm.assert_index_equal(res, idx) # https://github.com/pandas-dev/pandas/issues/29526 - idx = UInt64Index([1, 2 ** 63 + 1], dtype=np.uint64) - res = Index([1, 2 ** 63 + 1], dtype=np.uint64) + idx = index_cls([1, 2 ** 63 + 1], dtype=dtype) + res = Index([1, 2 ** 63 + 1], dtype=dtype) tm.assert_index_equal(res, idx) diff --git a/pandas/tests/indexes/timedeltas/test_timedelta.py b/pandas/tests/indexes/timedeltas/test_timedelta.py index d0f4828e8c7bd..c329d5940a1b8 100644 --- a/pandas/tests/indexes/timedeltas/test_timedelta.py +++ b/pandas/tests/indexes/timedeltas/test_timedelta.py @@ -20,7 +20,7 @@ class TestTimedeltaIndex(DatetimeLike): - _holder = TimedeltaIndex + _index_cls = TimedeltaIndex @pytest.fixture def index(self): From e2f8887bd6f3b0bf1ea8708924dfbd8e5a332d39 Mon Sep 17 00:00:00 2001 From: tp Date: Wed, 28 Apr 2021 10:37:20 +0100 Subject: [PATCH 2/4] fixes --- pandas/tests/indexes/test_numeric.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/pandas/tests/indexes/test_numeric.py b/pandas/tests/indexes/test_numeric.py index a407e82f2e644..44a32247086f7 100644 --- a/pandas/tests/indexes/test_numeric.py +++ b/pandas/tests/indexes/test_numeric.py @@ -117,7 +117,7 @@ def test_insert_na(self, nulls_fixture): class TestFloat64Index(Numeric): _index_cls = Float64Index - _dtype = "float64" + _dtype = np.float64 def create_index(self) -> Float64Index: values = np.arange(5, dtype=self._dtype) @@ -489,19 +489,16 @@ def test_prevent_casting(self): class TestInt64Index(NumericInt): _index_cls = Int64Index - _dtype = "int64" + _dtype = np.int64 - def create_index(self, values=None) -> Int64Index: - if values is None: - values = range(0, 20, 2) - - return self._index_cls(values, dtype=self._dtype) + def create_index(self) -> Int64Index: + return self._index_cls(range(0, 20, 2), dtype=self._dtype) @pytest.fixture( params=[range(0, 20, 2), range(19, -1, -1)], ids=["index_inc", "index_dec"] ) def index(self, request): - return self.create_index(request.param) + return self._index_cls(request.param) def test_constructor(self): index_cls = self._index_cls @@ -589,7 +586,7 @@ def test_coerce_list(self): class TestUInt64Index(NumericInt): _index_cls = UInt64Index - _dtype = "uint64" + _dtype = np.uint64 @pytest.fixture( params=[ @@ -605,8 +602,9 @@ def create_index(self) -> UInt64Index: # compat with shared Int64/Float64 tests return self._index_cls(np.arange(5, dtype=self._dtype)) - def test_constructor(self, dtype): + def test_constructor(self): index_cls = self._index_cls + dtype = self._dtype idx = index_cls([1, 2, 3]) res = Index([1, 2, 3], dtype=dtype) From 88e76901bc6a9f21d22323f14c4d8c34d4831016 Mon Sep 17 00:00:00 2001 From: tp Date: Wed, 28 Apr 2021 10:45:47 +0100 Subject: [PATCH 3/4] more fixes --- pandas/tests/indexes/test_numeric.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pandas/tests/indexes/test_numeric.py b/pandas/tests/indexes/test_numeric.py index 44a32247086f7..5d8835f0558f2 100644 --- a/pandas/tests/indexes/test_numeric.py +++ b/pandas/tests/indexes/test_numeric.py @@ -172,16 +172,15 @@ def test_constructor(self): tm.assert_numpy_array_equal(index.values, expected) index = index_cls(np.array([1, 2, 3, 4, 5])) assert isinstance(index, index_cls) - assert index.dtype.type is dtype + assert index.dtype == dtype index = index_cls([1.0, 2, 3, 4, 5]) assert isinstance(index, index_cls) - assert index.dtype.type is dtype + assert index.dtype == dtype index = index_cls(np.array([1.0, 2, 3, 4, 5])) assert isinstance(index, index_cls) - assert index.dtype.type is dtype - assert index.dtype == float + assert index.dtype == dtype index = index_cls(np.array([1.0, 2, 3, 4, 5]), dtype=np.float32) assert isinstance(index, index_cls) From f0ea8cdca56fbcf476dae1b5d3d73666cb0f60e2 Mon Sep 17 00:00:00 2001 From: tp Date: Wed, 28 Apr 2021 23:27:54 +0100 Subject: [PATCH 4/4] use fixtures instead of create_index method --- .../indexes/categorical/test_category.py | 14 +- pandas/tests/indexes/common.py | 190 +++++++++--------- pandas/tests/indexes/datetimelike.py | 58 +++--- .../indexes/datetimes/test_datetimelike.py | 11 +- pandas/tests/indexes/interval/test_base.py | 14 +- pandas/tests/indexes/period/test_period.py | 7 +- pandas/tests/indexes/ranges/test_range.py | 51 ++--- pandas/tests/indexes/test_base.py | 54 ++--- pandas/tests/indexes/test_numeric.py | 43 ++-- .../indexes/timedeltas/test_timedelta.py | 9 +- 10 files changed, 235 insertions(+), 216 deletions(-) diff --git a/pandas/tests/indexes/categorical/test_category.py b/pandas/tests/indexes/categorical/test_category.py index f0d2e9ee08fe9..dc6fb9910161c 100644 --- a/pandas/tests/indexes/categorical/test_category.py +++ b/pandas/tests/indexes/categorical/test_category.py @@ -19,11 +19,15 @@ class TestCategoricalIndex(Base): _index_cls = CategoricalIndex + @pytest.fixture + def simple_index(self) -> CategoricalIndex: + return self._index_cls(list("aabbca"), categories=list("cab"), ordered=False) + @pytest.fixture def index(self, request): return tm.makeCategoricalIndex(100) - def create_index(self, categories=None, ordered=False): + def create_index(self, *, categories=None, ordered=False): if categories is None: categories = list("cab") return CategoricalIndex(list("aabbca"), categories=categories, ordered=ordered) @@ -33,9 +37,9 @@ def test_can_hold_identifiers(self): key = idx[0] assert idx._can_hold_identifiers_and_holds_name(key) is True - def test_insert(self): + def test_insert(self, simple_index): - ci = self.create_index() + ci = simple_index categories = ci.categories # test 0th element @@ -70,9 +74,9 @@ def test_insert_na_mismatched_dtype(self): expected = Index([pd.NaT, 0, 1, 1], dtype=object) tm.assert_index_equal(result, expected) - def test_delete(self): + def test_delete(self, simple_index): - ci = self.create_index() + ci = simple_index categories = ci.categories result = ci.delete(0) diff --git a/pandas/tests/indexes/common.py b/pandas/tests/indexes/common.py index c80576d85c1c3..6139d8af48d98 100644 --- a/pandas/tests/indexes/common.py +++ b/pandas/tests/indexes/common.py @@ -33,6 +33,10 @@ class Base: _index_cls: Type[Index] + @pytest.fixture + def simple_index(self) -> Index: + raise NotImplementedError("Method not implemented") + def create_index(self) -> Index: raise NotImplementedError("Method not implemented") @@ -48,9 +52,9 @@ def test_pickle_compat_construction(self): self._index_cls() @pytest.mark.parametrize("name", [None, "new_name"]) - def test_to_frame(self, name): + def test_to_frame(self, name, simple_index): # see GH-15230, GH-22580 - idx = self.create_index() + idx = simple_index if name: idx_name = name @@ -67,10 +71,10 @@ def test_to_frame(self, name): df = idx.to_frame(index=False, name=idx_name) assert df.index is not idx - def test_shift(self): + def test_shift(self, simple_index): # GH8083 test the base class for shift - idx = self.create_index() + idx = simple_index msg = ( f"This method is only implemented for DatetimeIndex, PeriodIndex and " f"TimedeltaIndex; Got type {type(idx).__name__}" @@ -80,18 +84,18 @@ def test_shift(self): with pytest.raises(NotImplementedError, match=msg): idx.shift(1, 2) - def test_constructor_name_unhashable(self): + def test_constructor_name_unhashable(self, simple_index): # GH#29069 check that name is hashable # See also same-named test in tests.series.test_constructors - idx = self.create_index() + idx = simple_index with pytest.raises(TypeError, match="Index.name must be a hashable type"): type(idx)(idx, name=[]) - def test_create_index_existing_name(self): + def test_create_index_existing_name(self, simple_index): # GH11193, when an existing index is passed, and a new name is not # specified, the new index should inherit the previous object name - expected = self.create_index() + expected = simple_index if not isinstance(expected, MultiIndex): expected.name = "foo" result = Index(expected) @@ -140,9 +144,9 @@ def test_create_index_existing_name(self): ), ) - def test_numeric_compat(self): + def test_numeric_compat(self, simple_index): - idx = self.create_index() + idx = simple_index # Check that this doesn't cover MultiIndex case, if/when it does, # we can remove multi.test_compat.test_numeric_compat assert not isinstance(idx, MultiIndex) @@ -183,21 +187,21 @@ def test_numeric_compat(self): with pytest.raises(TypeError, match=floordiv_err): 1 // idx - def test_logical_compat(self): - idx = self.create_index() + def test_logical_compat(self, simple_index): + idx = simple_index with pytest.raises(TypeError, match="cannot perform all"): idx.all() with pytest.raises(TypeError, match="cannot perform any"): idx.any() - def test_repr_roundtrip(self): + def test_repr_roundtrip(self, simple_index): - idx = self.create_index() + idx = simple_index tm.assert_index_equal(eval(repr(idx)), idx) - def test_repr_max_seq_item_setting(self): + def test_repr_max_seq_item_setting(self, simple_index): # GH10182 - idx = self.create_index() + idx = simple_index idx = idx.repeat(50) with pd.option_context("display.max_seq_items", None): repr(idx) @@ -331,42 +335,42 @@ def test_numpy_argsort(self, index): with pytest.raises(ValueError, match=msg): np.argsort(index, order=("a", "b")) - def test_repeat(self): + def test_repeat(self, simple_index): rep = 2 - i = self.create_index() - expected = Index(i.values.repeat(rep), name=i.name) - tm.assert_index_equal(i.repeat(rep), expected) + idx = simple_index.copy() + expected = Index(idx.values.repeat(rep), name=idx.name) + tm.assert_index_equal(idx.repeat(rep), expected) - i = self.create_index() - rep = np.arange(len(i)) - expected = Index(i.values.repeat(rep), name=i.name) - tm.assert_index_equal(i.repeat(rep), expected) + idx = simple_index + rep = np.arange(len(idx)) + expected = Index(idx.values.repeat(rep), name=idx.name) + tm.assert_index_equal(idx.repeat(rep), expected) - def test_numpy_repeat(self): + def test_numpy_repeat(self, simple_index): rep = 2 - i = self.create_index() - expected = i.repeat(rep) - tm.assert_index_equal(np.repeat(i, rep), expected) + idx = simple_index + expected = idx.repeat(rep) + tm.assert_index_equal(np.repeat(idx, rep), expected) msg = "the 'axis' parameter is not supported" with pytest.raises(ValueError, match=msg): - np.repeat(i, rep, axis=0) + np.repeat(idx, rep, axis=0) @pytest.mark.parametrize("klass", [list, tuple, np.array, Series]) - def test_where(self, klass): - i = self.create_index() - if isinstance(i, (DatetimeIndex, TimedeltaIndex)): + def test_where(self, klass, simple_index): + idx = simple_index + if isinstance(idx, (DatetimeIndex, TimedeltaIndex)): # where does not preserve freq - i = i._with_freq(None) + idx = idx._with_freq(None) - cond = [True] * len(i) - result = i.where(klass(cond)) - expected = i + cond = [True] * len(idx) + result = idx.where(klass(cond)) + expected = idx tm.assert_index_equal(result, expected) - cond = [False] + [True] * len(i[1:]) - expected = Index([i._na_value] + i[1:].tolist(), dtype=i.dtype) - result = i.where(klass(cond)) + cond = [False] + [True] * len(idx[1:]) + expected = Index([idx._na_value] + idx[1:].tolist(), dtype=idx.dtype) + result = idx.where(klass(cond)) tm.assert_index_equal(result, expected) def test_insert_base(self, index): @@ -424,9 +428,9 @@ def test_equals(self, index): # do not test MultiIndex assert not index.equals(Series(index)) - def test_equals_op(self): + def test_equals_op(self, simple_index): # GH9947, GH10637 - index_a = self.create_index() + index_a = simple_index n = len(index_a) index_b = index_a[0:-1] @@ -487,9 +491,9 @@ def test_equals_op(self): # For RangeIndex we can convert to Int64Index tm.assert_series_equal(series_a == item, Series(expected3)) - def test_format(self): + def test_format(self, simple_index): # GH35439 - idx = self.create_index() + idx = simple_index expected = [str(x) for x in idx] assert idx.format() == expected @@ -588,29 +592,29 @@ def test_nulls(self, index): tm.assert_numpy_array_equal(index.isna(), result) tm.assert_numpy_array_equal(index.notna(), ~result) - def test_empty(self): + def test_empty(self, simple_index): # GH 15270 - index = self.create_index() - assert not index.empty - assert index[:0].empty + idx = simple_index + assert not idx.empty + assert idx[:0].empty - def test_join_self_unique(self, join_type): - index = self.create_index() - if index.is_unique: - joined = index.join(index, how=join_type) - assert (index == joined).all() + def test_join_self_unique(self, join_type, simple_index): + idx = simple_index + if idx.is_unique: + joined = idx.join(idx, how=join_type) + assert (idx == joined).all() - def test_map(self): + def test_map(self, simple_index): # callable - index = self.create_index() + idx = simple_index # we don't infer UInt64 - if isinstance(index, UInt64Index): - expected = index.astype("int64") + if isinstance(idx, UInt64Index): + expected = idx.astype("int64") else: - expected = index + expected = idx - result = index.map(lambda x: x) + result = idx.map(lambda x: x) # For RangeIndex we convert to Int64Index tm.assert_index_equal(result, expected) @@ -621,66 +625,66 @@ def test_map(self): lambda values, index: Series(values, index), ], ) - def test_map_dictlike(self, mapper): + def test_map_dictlike(self, mapper, simple_index): - index = self.create_index() - if isinstance(index, CategoricalIndex): - pytest.skip(f"skipping tests for {type(index)}") + idx = simple_index + if isinstance(idx, CategoricalIndex): + pytest.skip(f"skipping tests for {type(idx)}") - identity = mapper(index.values, index) + identity = mapper(idx.values, idx) # we don't infer to UInt64 for a dict - if isinstance(index, UInt64Index) and isinstance(identity, dict): - expected = index.astype("int64") + if isinstance(idx, UInt64Index) and isinstance(identity, dict): + expected = idx.astype("int64") else: - expected = index + expected = idx - result = index.map(identity) + result = idx.map(identity) # For RangeIndex we convert to Int64Index tm.assert_index_equal(result, expected) # empty mappable - expected = Index([np.nan] * len(index)) - result = index.map(mapper(expected, index)) + expected = Index([np.nan] * len(idx)) + result = idx.map(mapper(expected, idx)) tm.assert_index_equal(result, expected) - def test_map_str(self): + def test_map_str(self, simple_index): # GH 31202 - index = self.create_index() - result = index.map(str) - expected = Index([str(x) for x in index], dtype=object) + idx = simple_index + result = idx.map(str) + expected = Index([str(x) for x in idx], dtype=object) tm.assert_index_equal(result, expected) @pytest.mark.parametrize("copy", [True, False]) @pytest.mark.parametrize("name", [None, "foo"]) @pytest.mark.parametrize("ordered", [True, False]) - def test_astype_category(self, copy, name, ordered): + def test_astype_category(self, copy, name, ordered, simple_index): # GH 18630 - index = self.create_index() + idx = simple_index if name: - index = index.rename(name) + idx = idx.rename(name) # standard categories dtype = CategoricalDtype(ordered=ordered) - result = index.astype(dtype, copy=copy) - expected = CategoricalIndex(index.values, name=name, ordered=ordered) + result = idx.astype(dtype, copy=copy) + expected = CategoricalIndex(idx.values, name=name, ordered=ordered) tm.assert_index_equal(result, expected) # non-standard categories - dtype = CategoricalDtype(index.unique().tolist()[:-1], ordered) - result = index.astype(dtype, copy=copy) - expected = CategoricalIndex(index.values, name=name, dtype=dtype) + dtype = CategoricalDtype(idx.unique().tolist()[:-1], ordered) + result = idx.astype(dtype, copy=copy) + expected = CategoricalIndex(idx.values, name=name, dtype=dtype) tm.assert_index_equal(result, expected) if ordered is False: # dtype='category' defaults to ordered=False, so only test once - result = index.astype("category", copy=copy) - expected = CategoricalIndex(index.values, name=name) + result = idx.astype("category", copy=copy) + expected = CategoricalIndex(idx.values, name=name) tm.assert_index_equal(result, expected) - def test_is_unique(self): + def test_is_unique(self, simple_index): # initialize a unique index - index = self.create_index().drop_duplicates() + index = simple_index.drop_duplicates() assert index.is_unique is True # empty index should be unique @@ -700,32 +704,32 @@ def test_is_unique(self): assert index_na_dup.is_unique is False @pytest.mark.arm_slow - def test_engine_reference_cycle(self): + def test_engine_reference_cycle(self, simple_index): # GH27585 - index = self.create_index() + index = simple_index nrefs_pre = len(gc.get_referrers(index)) index._engine assert len(gc.get_referrers(index)) == nrefs_pre - def test_getitem_2d_deprecated(self): + def test_getitem_2d_deprecated(self, simple_index): # GH#30588 - idx = self.create_index() + idx = simple_index with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): res = idx[:, None] assert isinstance(res, np.ndarray), type(res) - def test_copy_shares_cache(self): + def test_copy_shares_cache(self, simple_index): # GH32898, GH36840 - idx = self.create_index() + idx = simple_index idx.get_loc(idx[0]) # populates the _cache. copy = idx.copy() assert copy._cache is idx._cache - def test_shallow_copy_shares_cache(self): + def test_shallow_copy_shares_cache(self, simple_index): # GH32669, GH36840 - idx = self.create_index() + idx = simple_index idx.get_loc(idx[0]) # populates the _cache. shallow_copy = idx._view() diff --git a/pandas/tests/indexes/datetimelike.py b/pandas/tests/indexes/datetimelike.py index 5f17b00b8193b..a8f8406e24fef 100644 --- a/pandas/tests/indexes/datetimelike.py +++ b/pandas/tests/indexes/datetimelike.py @@ -9,33 +9,33 @@ class DatetimeLike(Base): - def test_argsort_matches_array(self): - rng = self.create_index() - rng = rng.insert(1, pd.NaT) + def test_argsort_matches_array(self, simple_index): + idx = simple_index + idx = idx.insert(1, pd.NaT) - result = rng.argsort() - expected = rng._data.argsort() + result = idx.argsort() + expected = idx._data.argsort() tm.assert_numpy_array_equal(result, expected) - def test_can_hold_identifiers(self): - idx = self.create_index() + def test_can_hold_identifiers(self, simple_index): + idx = simple_index key = idx[0] assert idx._can_hold_identifiers_and_holds_name(key) is False - def test_shift_identity(self): + def test_shift_identity(self, simple_index): - idx = self.create_index() + idx = simple_index tm.assert_index_equal(idx, idx.shift(0)) - def test_shift_empty(self): + def test_shift_empty(self, simple_index): # GH#14811 - idx = self.create_index()[:0] + idx = simple_index[:0] tm.assert_index_equal(idx, idx.shift(1)) - def test_str(self): + def test_str(self, simple_index): # test the string repr - idx = self.create_index() + idx = simple_index idx.name = "foo" assert not (f"length={len(idx)}" in str(idx)) assert "'foo'" in str(idx) @@ -47,19 +47,19 @@ def test_str(self): if hasattr(idx, "freq"): assert f"freq='{idx.freqstr}'" in str(idx) - def test_view(self): - i = self.create_index() + def test_view(self, simple_index): + idx = simple_index - i_view = i.view("i8") - result = self._index_cls(i) - tm.assert_index_equal(result, i) + idx_view = idx.view("i8") + result = self._index_cls(idx) + tm.assert_index_equal(result, idx) - i_view = i.view(self._index_cls) - result = self._index_cls(i) - tm.assert_index_equal(result, i_view) + idx_view = idx.view(self._index_cls) + result = self._index_cls(idx) + tm.assert_index_equal(result, idx_view) - def test_map_callable(self): - index = self.create_index() + def test_map_callable(self, simple_index): + index = simple_index expected = index + index.freq result = index.map(lambda x: x + x.freq) tm.assert_index_equal(result, expected) @@ -76,8 +76,8 @@ def test_map_callable(self): lambda values, index: pd.Series(values, index, dtype=object), ], ) - def test_map_dictlike(self, mapper): - index = self.create_index() + def test_map_dictlike(self, mapper, simple_index): + index = simple_index expected = index + index.freq # don't compare the freqs @@ -97,15 +97,15 @@ def test_map_dictlike(self, mapper): result = index.map(mapper([], [])) tm.assert_index_equal(result, expected) - def test_getitem_preserves_freq(self): - index = self.create_index() + def test_getitem_preserves_freq(self, simple_index): + index = simple_index assert index.freq is not None result = index[:] assert result.freq == index.freq - def test_where_cast_str(self): - index = self.create_index() + def test_where_cast_str(self, simple_index): + index = simple_index mask = np.ones(len(index), dtype=bool) mask[-1] = False diff --git a/pandas/tests/indexes/datetimes/test_datetimelike.py b/pandas/tests/indexes/datetimes/test_datetimelike.py index 0a686a4eb8b79..0a387fe3141e4 100644 --- a/pandas/tests/indexes/datetimes/test_datetimelike.py +++ b/pandas/tests/indexes/datetimes/test_datetimelike.py @@ -12,6 +12,10 @@ 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"], @@ -19,12 +23,9 @@ class TestDatetimeIndex(DatetimeLike): def index(self, request): return request.param - def create_index(self) -> DatetimeIndex: - return date_range("20130101", periods=5) - - def test_format(self): + def test_format(self, simple_index): # GH35439 - idx = self.create_index() + idx = simple_index expected = [f"{x:%Y-%m-%d}" for x in idx] assert idx.format() == expected diff --git a/pandas/tests/indexes/interval/test_base.py b/pandas/tests/indexes/interval/test_base.py index 8a6deb0ebdda2..b14db459f996d 100644 --- a/pandas/tests/indexes/interval/test_base.py +++ b/pandas/tests/indexes/interval/test_base.py @@ -18,11 +18,15 @@ class TestBase(Base): _index_cls = IntervalIndex + @pytest.fixture + def simple_index(self) -> IntervalIndex: + return self._index_cls.from_breaks(range(11), closed="right") + @pytest.fixture def index(self): return tm.makeIntervalIndex(10) - def create_index(self, closed="right"): + def create_index(self, *, closed="right"): return IntervalIndex.from_breaks(range(11), closed=closed) def test_repr_max_seq_item_setting(self): @@ -44,8 +48,8 @@ def test_take(self, closed): tm.assert_index_equal(result, expected) @pytest.mark.parametrize("klass", [list, tuple, np.array, Series]) - def test_where(self, closed, klass): - idx = self.create_index(closed=closed) + def test_where(self, simple_index, klass): + idx = simple_index cond = [True] * len(idx) expected = idx result = expected.where(klass(cond)) @@ -56,9 +60,9 @@ def test_where(self, closed, klass): result = idx.where(klass(cond)) tm.assert_index_equal(result, expected) - def test_getitem_2d_deprecated(self): + def test_getitem_2d_deprecated(self, simple_index): # GH#30588 multi-dim indexing is deprecated, but raising is also acceptable - idx = self.create_index() + idx = simple_index with pytest.raises(ValueError, match="multi-dimensional indexing not allowed"): with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): idx[:, None] diff --git a/pandas/tests/indexes/period/test_period.py b/pandas/tests/indexes/period/test_period.py index bc6c9fb06ac94..b80e92b105dbd 100644 --- a/pandas/tests/indexes/period/test_period.py +++ b/pandas/tests/indexes/period/test_period.py @@ -21,6 +21,10 @@ class TestPeriodIndex(DatetimeLike): _index_cls = PeriodIndex + @pytest.fixture + def simple_index(self) -> Index: + return period_range("20130101", periods=5, freq="D") + @pytest.fixture( params=[ tm.makePeriodIndex(10), @@ -31,9 +35,6 @@ class TestPeriodIndex(DatetimeLike): def index(self, request): return request.param - def create_index(self) -> PeriodIndex: - return period_range("20130101", periods=5, freq="D") - def test_pickle_compat_construction(self): pass diff --git a/pandas/tests/indexes/ranges/test_range.py b/pandas/tests/indexes/ranges/test_range.py index 9dc7116f6ae8c..f7313f100d429 100644 --- a/pandas/tests/indexes/ranges/test_range.py +++ b/pandas/tests/indexes/ranges/test_range.py @@ -23,6 +23,10 @@ class TestRangeIndex(Numeric): _index_cls = RangeIndex + @pytest.fixture + def simple_index(self) -> Index: + return self._index_cls(start=0, stop=20, step=2) + @pytest.fixture( params=[ RangeIndex(start=0, stop=20, step=2, name="foo"), @@ -33,16 +37,13 @@ class TestRangeIndex(Numeric): def index(self, request): return request.param - def create_index(self) -> RangeIndex: - return RangeIndex(start=0, stop=20, step=2) - - def test_can_hold_identifiers(self): - idx = self.create_index() + def test_can_hold_identifiers(self, simple_index): + idx = simple_index key = idx[0] assert idx._can_hold_identifiers_and_holds_name(key) is False - def test_too_many_names(self): - index = self.create_index() + def test_too_many_names(self, simple_index): + index = simple_index with pytest.raises(ValueError, match="^Length"): index.names = ["roger", "harold"] @@ -62,9 +63,9 @@ def test_start_stop_step_attrs(self, index, start, stop, step): assert index.step == step @pytest.mark.parametrize("attr_name", ["_start", "_stop", "_step"]) - def test_deprecated_start_stop_step_attrs(self, attr_name): + def test_deprecated_start_stop_step_attrs(self, attr_name, simple_index): # GH 26581 - idx = self.create_index() + idx = simple_index with tm.assert_produces_warning(FutureWarning): getattr(idx, attr_name) @@ -140,8 +141,8 @@ def test_view(self): i_view = i.view(RangeIndex) tm.assert_index_equal(i, i_view) - def test_dtype(self): - index = self.create_index() + def test_dtype(self, simple_index): + index = simple_index assert index.dtype == np.int64 def test_cache(self): @@ -253,13 +254,13 @@ def test_equals_range(self): assert left.equals(right) assert right.equals(left) - def test_logical_compat(self): - idx = self.create_index() + def test_logical_compat(self, simple_index): + idx = simple_index assert idx.all() == idx.values.all() assert idx.any() == idx.values.any() - def test_identical(self): - index = self.create_index() + def test_identical(self, simple_index): + index = simple_index i = Index(index.copy()) assert i.identical(index) @@ -304,17 +305,17 @@ def test_cant_or_shouldnt_cast(self, start, stop, step): with pytest.raises(TypeError, match=msg): RangeIndex(start, stop, step) - def test_view_index(self): - index = self.create_index() + def test_view_index(self, simple_index): + index = simple_index index.view(Index) - def test_prevent_casting(self): - index = self.create_index() + def test_prevent_casting(self, simple_index): + index = simple_index result = index.astype("O") assert result.dtype == np.object_ - def test_repr_roundtrip(self): - index = self.create_index() + def test_repr_roundtrip(self, simple_index): + index = simple_index tm.assert_index_equal(eval(repr(index)), index) def test_slice_keep_name(self): @@ -325,8 +326,8 @@ def test_has_duplicates(self, index): assert index.is_unique assert not index.has_duplicates - def test_extended_gcd(self): - index = self.create_index() + def test_extended_gcd(self, simple_index): + index = simple_index result = index._extended_gcd(6, 10) assert result[0] == result[1] * 6 + result[2] * 10 assert 2 == result[0] @@ -375,8 +376,8 @@ def test_pickle_compat_construction(self): # RangeIndex() is a valid constructor pass - def test_slice_specialised(self): - index = self.create_index() + def test_slice_specialised(self, simple_index): + index = simple_index index.name = "foo" # scalar indexing diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index 0067bc82e301b..b5822b768fdde 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -48,11 +48,12 @@ class TestIndex(Base): _index_cls = Index - def create_index(self) -> Index: - return Index(list("abcde")) + @pytest.fixture + def simple_index(self) -> Index: + return self._index_cls(list("abcde")) - def test_can_hold_identifiers(self): - index = self.create_index() + def test_can_hold_identifiers(self, simple_index): + index = simple_index key = index[0] assert index._can_hold_identifiers_and_holds_name(key) is True @@ -77,8 +78,6 @@ def test_constructor_casting(self, index): @pytest.mark.parametrize("index", ["string"], indirect=True) def test_constructor_copy(self, index): - # copy - # index = self.create_index() arr = np.array(index) new_index = Index(arr, copy=True, name="name") assert isinstance(new_index, Index) @@ -600,8 +599,8 @@ def test_booleanindex(self, index): for i, val in enumerate(sub_index): assert sub_index.get_loc(val) == i - def test_fancy(self): - index = self.create_index() + def test_fancy(self, simple_index): + index = simple_index sl = index[[1, 2, 3]] for i in sl: assert i == sl[sl.get_loc(i)] @@ -628,9 +627,9 @@ def test_empty_fancy_raises(self, index): with pytest.raises(IndexError, match=msg): index[empty_farr] - def test_union_dt_as_obj(self, sort): + def test_union_dt_as_obj(self, sort, simple_index): # TODO: Replace with fixturesult - index = self.create_index() + index = simple_index date_index = date_range("2019-01-01", periods=10) first_cat = index.union(date_index) second_cat = index.union(index) @@ -754,9 +753,9 @@ def test_append_empty_preserve_name(self, name, expected): result = left.append(right) assert result.name == expected - def test_is_mixed_deprecated(self): + def test_is_mixed_deprecated(self, simple_index): # GH#32922 - index = self.create_index() + index = simple_index with tm.assert_produces_warning(FutureWarning): index.is_mixed() @@ -866,8 +865,8 @@ def test_format_datetime_with_time(self): assert result == expected @pytest.mark.parametrize("op", ["any", "all"]) - def test_logical_compat(self, op): - index = self.create_index() + def test_logical_compat(self, op, simple_index): + index = simple_index assert getattr(index, op)() == getattr(index.values, op)() @pytest.mark.parametrize("index", ["string", "int", "float"], indirect=True) @@ -973,9 +972,9 @@ def test_is_monotonic_incomparable(self, attr): index = Index([5, datetime.now(), 7]) assert not getattr(index, attr) - def test_set_value_deprecated(self): + def test_set_value_deprecated(self, simple_index): # GH 28621 - idx = self.create_index() + idx = simple_index arr = np.array([1, 2, 3]) with tm.assert_produces_warning(FutureWarning): idx.set_value(arr, idx[1], 80) @@ -1417,27 +1416,28 @@ class TestMixedIntIndex(Base): # (GH 13514) _index_cls = Index + @pytest.fixture + def simple_index(self) -> Index: + return self._index_cls([0, "a", 1, "b", 2, "c"]) + @pytest.fixture(params=[[0, "a", 1, "b", 2, "c"]], ids=["mixedIndex"]) def index(self, request): return Index(request.param) - def create_index(self) -> Index: - return Index([0, "a", 1, "b", 2, "c"]) - - def test_argsort(self): - index = self.create_index() + def test_argsort(self, simple_index): + index = simple_index with pytest.raises(TypeError, match="'>|<' not supported"): index.argsort() - def test_numpy_argsort(self): - index = self.create_index() + def test_numpy_argsort(self, simple_index): + index = simple_index with pytest.raises(TypeError, match="'>|<' not supported"): np.argsort(index) - def test_copy_name(self): + def test_copy_name(self, simple_index): # Check that "name" argument passed at initialization is honoured # GH12309 - index = self.create_index() + index = simple_index first = type(index)(index, copy=True, name="mario") second = type(first)(first, copy=False) @@ -1482,8 +1482,8 @@ def test_unique_na(self): result = idx.unique() tm.assert_index_equal(result, expected) - def test_logical_compat(self): - index = self.create_index() + def test_logical_compat(self, simple_index): + index = simple_index assert index.all() == index.values.all() assert index.any() == index.values.any() diff --git a/pandas/tests/indexes/test_numeric.py b/pandas/tests/indexes/test_numeric.py index 5d8835f0558f2..5f02f9625a9e6 100644 --- a/pandas/tests/indexes/test_numeric.py +++ b/pandas/tests/indexes/test_numeric.py @@ -86,14 +86,14 @@ def test_where(self): # Tested in numeric.test_indexing pass - def test_can_hold_identifiers(self): - idx = self.create_index() + def test_can_hold_identifiers(self, simple_index): + idx = simple_index key = idx[0] assert idx._can_hold_identifiers_and_holds_name(key) is False - def test_format(self): + def test_format(self, simple_index): # GH35439 - idx = self.create_index() + idx = simple_index max_width = max(len(str(x)) for x in idx) expected = [str(x).ljust(max_width) for x in idx] assert idx.format() == expected @@ -101,9 +101,9 @@ def test_format(self): def test_numeric_compat(self): pass # override Base method - def test_insert_na(self, nulls_fixture): + def test_insert_na(self, nulls_fixture, simple_index): # GH 18295 (test missing) - index = self.create_index() + index = simple_index na_val = nulls_fixture if na_val is pd.NaT: @@ -119,7 +119,8 @@ class TestFloat64Index(Numeric): _index_cls = Float64Index _dtype = np.float64 - def create_index(self) -> Float64Index: + @pytest.fixture + def simple_index(self) -> Index: values = np.arange(5, dtype=self._dtype) return self._index_cls(values) @@ -437,13 +438,13 @@ def test_is_strictly_monotonic(self): assert not index._is_strictly_monotonic_increasing assert not index._is_strictly_monotonic_decreasing - def test_logical_compat(self): - idx = self.create_index() + def test_logical_compat(self, simple_index): + idx = simple_index assert idx.all() == idx.values.all() assert idx.any() == idx.values.any() - def test_identical(self): - index = self.create_index() + def test_identical(self, simple_index): + index = simple_index idx = Index(index.copy()) assert idx.identical(index) @@ -476,12 +477,12 @@ def test_cant_or_shouldnt_cast(self): with pytest.raises(TypeError, match=msg): self._index_cls(data) - def test_view_index(self): - index = self.create_index() + def test_view_index(self, simple_index): + index = simple_index index.view(Index) - def test_prevent_casting(self): - index = self.create_index() + def test_prevent_casting(self, simple_index): + index = simple_index result = index.astype("O") assert result.dtype == np.object_ @@ -490,7 +491,8 @@ class TestInt64Index(NumericInt): _index_cls = Int64Index _dtype = np.int64 - def create_index(self) -> Int64Index: + @pytest.fixture + def simple_index(self) -> Index: return self._index_cls(range(0, 20, 2), dtype=self._dtype) @pytest.fixture( @@ -587,6 +589,11 @@ class TestUInt64Index(NumericInt): _index_cls = UInt64Index _dtype = np.uint64 + @pytest.fixture + def simple_index(self) -> Index: + # compat with shared Int64/Float64 tests + return self._index_cls(np.arange(5, dtype=self._dtype)) + @pytest.fixture( params=[ [2 ** 63, 2 ** 63 + 10, 2 ** 63 + 15, 2 ** 63 + 20, 2 ** 63 + 25], @@ -597,10 +604,6 @@ class TestUInt64Index(NumericInt): def index(self, request): return self._index_cls(request.param) - def create_index(self) -> UInt64Index: - # compat with shared Int64/Float64 tests - return self._index_cls(np.arange(5, dtype=self._dtype)) - def test_constructor(self): index_cls = self._index_cls dtype = self._dtype diff --git a/pandas/tests/indexes/timedeltas/test_timedelta.py b/pandas/tests/indexes/timedeltas/test_timedelta.py index c329d5940a1b8..478697ed1a5be 100644 --- a/pandas/tests/indexes/timedeltas/test_timedelta.py +++ b/pandas/tests/indexes/timedeltas/test_timedelta.py @@ -23,16 +23,17 @@ class TestTimedeltaIndex(DatetimeLike): _index_cls = TimedeltaIndex @pytest.fixture - def index(self): - return tm.makeTimedeltaIndex(10) - - def create_index(self) -> TimedeltaIndex: + def simple_index(self) -> TimedeltaIndex: index = pd.to_timedelta(range(5), unit="d")._with_freq("infer") assert index.freq == "D" ret = index + pd.offsets.Hour(1) assert ret.freq == "D" return ret + @pytest.fixture + def index(self): + return tm.makeTimedeltaIndex(10) + def test_numeric_compat(self): # Dummy method to override super's version; this test is now done # in test_arithmetic.py