Skip to content

Commit 28291f1

Browse files
using new utils and fixtures in tests/indexes
1 parent baab827 commit 28291f1

File tree

5 files changed

+71
-140
lines changed

5 files changed

+71
-140
lines changed

pandas/tests/base/test_ops.py

Lines changed: 3 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,11 @@
2929
TimedeltaIndex,
3030
Timestamp,
3131
)
32-
from pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin
32+
from pandas.tests.base.utils import allow_na_ops
3333
import pandas.util.testing as tm
3434

3535

3636
class Ops:
37-
def _allow_na_ops(self, obj):
38-
"""Whether to skip test cases including NaN"""
39-
if (isinstance(obj, Index) and obj.is_boolean()) or not obj._can_hold_na:
40-
# don't test boolean / integer dtypes
41-
return False
42-
return True
43-
4437
def setup_method(self, method):
4538
self.bool_index = tm.makeBoolIndex(10, name="a")
4639
self.int_index = tm.makeIntIndex(10, name="a")
@@ -83,53 +76,6 @@ def setup_method(self, method):
8376

8477
self.objs = self.indexes + self.series + self.narrow_series
8578

86-
def check_ops_properties(self, props, filter=None, ignore_failures=False):
87-
for op in props:
88-
for o in self.is_valid_objs:
89-
90-
# if a filter, skip if it doesn't match
91-
if filter is not None:
92-
filt = o.index if isinstance(o, Series) else o
93-
if not filter(filt):
94-
continue
95-
96-
try:
97-
if isinstance(o, Series):
98-
expected = Series(getattr(o.index, op), index=o.index, name="a")
99-
else:
100-
expected = getattr(o, op)
101-
except (AttributeError):
102-
if ignore_failures:
103-
continue
104-
105-
result = getattr(o, op)
106-
107-
# these could be series, arrays or scalars
108-
if isinstance(result, Series) and isinstance(expected, Series):
109-
tm.assert_series_equal(result, expected)
110-
elif isinstance(result, Index) and isinstance(expected, Index):
111-
tm.assert_index_equal(result, expected)
112-
elif isinstance(result, np.ndarray) and isinstance(
113-
expected, np.ndarray
114-
):
115-
tm.assert_numpy_array_equal(result, expected)
116-
else:
117-
assert result == expected
118-
119-
# freq raises AttributeError on an Int64Index because its not
120-
# defined we mostly care about Series here anyhow
121-
if not ignore_failures:
122-
for o in self.not_valid_objs:
123-
124-
# an object that is datetimelike will raise a TypeError,
125-
# otherwise an AttributeError
126-
err = AttributeError
127-
if issubclass(type(o), DatetimeIndexOpsMixin):
128-
err = TypeError
129-
130-
with pytest.raises(err):
131-
getattr(o, op)
132-
13379

13480
@pytest.mark.parametrize("klass", [Series, DataFrame])
13581
def test_binary_ops_docs(klass):
@@ -314,7 +260,7 @@ def test_value_counts_unique_nunique_null(self, null_obj):
314260
klass = type(o)
315261
values = o._ndarray_values
316262

317-
if not self._allow_na_ops(o):
263+
if not allow_na_ops(o):
318264
continue
319265

320266
# special assign to the numpy array
@@ -796,7 +742,7 @@ def test_fillna(self):
796742
o = orig.copy()
797743
klass = type(o)
798744

799-
if not self._allow_na_ops(o):
745+
if not allow_na_ops(o):
800746
continue
801747

802748
if needs_i8_conversion(o):

pandas/tests/base/utils.py

Lines changed: 18 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
from typing import Any, Callable, List, Type
1+
from typing import Any
22

33
import numpy as np
4-
import pytest
54

65
from pandas import Index, Series
7-
from pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin
86
import pandas.util.testing as tm
97

108

@@ -14,46 +12,21 @@ def allow_na_ops(obj: Any) -> bool:
1412
return not is_bool_index and obj._can_hold_na
1513

1614

17-
def check_ops_properties_valid(obj: Any, props: List[str], filter: Callable) -> None:
15+
def check_ops_properties_valid(obj: Any, op: str) -> None:
1816
""" Validates that certain properties are available """
19-
for op in props:
20-
# if a filter, skip if it doesn't match
21-
index = obj.index if isinstance(obj, Series) else obj
22-
if not filter(index):
23-
continue
24-
25-
try:
26-
if isinstance(obj, Series):
27-
expected = Series(getattr(obj.index, op), index=obj.index, name="a")
28-
else:
29-
expected = getattr(obj, op)
30-
except AttributeError:
31-
continue
32-
33-
result = getattr(obj, op)
34-
35-
# these could be series, arrays or scalars
36-
if isinstance(result, Series) and isinstance(expected, Series):
37-
tm.assert_series_equal(result, expected)
38-
elif isinstance(result, Index) and isinstance(expected, Index):
39-
tm.assert_index_equal(result, expected)
40-
elif isinstance(result, np.ndarray) and isinstance(expected, np.ndarray):
41-
tm.assert_numpy_array_equal(result, expected)
42-
else:
43-
assert result == expected
44-
45-
46-
def check_ops_properties_invalid(obj: Any, props: List[str]) -> None:
47-
""" Validates that certain properties are not available """
48-
for op in props:
49-
# freq raises AttributeError on an Int64Index because its not
50-
# defined we mostly care about Series here anyhow
51-
52-
# an object that is datetimelike will raise a TypeError,
53-
# otherwise an AttributeError
54-
err: Type[Exception] = AttributeError
55-
if issubclass(type(obj), DatetimeIndexOpsMixin):
56-
err = TypeError
57-
58-
with pytest.raises(err):
59-
getattr(obj, op)
17+
if isinstance(obj, Series):
18+
expected = Series(getattr(obj.index, op), index=obj.index, name="a")
19+
else:
20+
expected = getattr(obj, op)
21+
22+
result = getattr(obj, op)
23+
24+
# these could be series, arrays or scalars
25+
if isinstance(result, Series) and isinstance(expected, Series):
26+
tm.assert_series_equal(result, expected)
27+
elif isinstance(result, Index) and isinstance(expected, Index):
28+
tm.assert_index_equal(result, expected)
29+
elif isinstance(result, np.ndarray) and isinstance(expected, np.ndarray):
30+
tm.assert_numpy_array_equal(result, expected)
31+
else:
32+
assert result == expected

pandas/tests/indexes/datetimes/test_ops.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,12 @@
1212
Index,
1313
PeriodIndex,
1414
Series,
15+
TimedeltaIndex,
1516
Timestamp,
1617
bdate_range,
1718
date_range,
1819
)
19-
from pandas.tests.base.utils import (
20-
check_ops_properties_invalid,
21-
check_ops_properties_valid,
22-
)
20+
from pandas.tests.base.utils import check_ops_properties_valid
2321
import pandas.util.testing as tm
2422

2523
from pandas.tseries.offsets import BDay, BMonthEnd, CDay, Day, Hour
@@ -28,18 +26,22 @@
2826

2927

3028
class TestDatetimeIndexOps:
31-
def test_ops_properties(self, index_or_series_obj):
29+
@pytest.mark.parametrize("op", DatetimeIndex._datetimelike_ops)
30+
def test_valid_ops_properties(self, op, index_or_series_obj):
31+
obj = index_or_series_obj
32+
if isinstance(obj, DatetimeIndex):
33+
check_ops_properties_valid(obj, op)
34+
35+
@pytest.mark.parametrize("op", DatetimeIndex._datetimelike_ops)
36+
def test_invalid_ops_properties(self, op, index_or_series_obj):
3237
obj = index_or_series_obj
33-
is_valid = isinstance(obj, (DatetimeIndex, PeriodIndex))
34-
if is_valid:
35-
filter_ = lambda x: isinstance(x, DatetimeIndex)
36-
check_ops_properties_valid(obj, DatetimeIndex._field_ops, filter_)
37-
check_ops_properties_valid(obj, DatetimeIndex._object_ops, filter_)
38-
check_ops_properties_valid(obj, DatetimeIndex._bool_ops, filter_)
39-
else:
40-
check_ops_properties_invalid(obj, DatetimeIndex._field_ops)
41-
check_ops_properties_invalid(obj, DatetimeIndex._object_ops)
42-
check_ops_properties_invalid(obj, DatetimeIndex._bool_ops)
38+
if isinstance(obj, (DatetimeIndex, PeriodIndex)):
39+
return
40+
if op == "freq" and isinstance(obj, TimedeltaIndex):
41+
return
42+
43+
with pytest.raises((AttributeError, TypeError)):
44+
getattr(obj, op)
4345

4446
def test_ops_properties_basic(self, datetime_series):
4547

pandas/tests/indexes/period/test_ops.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,29 @@
22
import pytest
33

44
import pandas as pd
5-
from pandas import DatetimeIndex, Index, NaT, PeriodIndex, Series
5+
from pandas import DatetimeIndex, Index, NaT, PeriodIndex, Series, TimedeltaIndex
66
from pandas.core.arrays import PeriodArray
7-
from pandas.tests.base.utils import (
8-
check_ops_properties_invalid,
9-
check_ops_properties_valid,
10-
)
7+
from pandas.tests.base.utils import check_ops_properties_valid
118
import pandas.util.testing as tm
129

1310

1411
class TestPeriodIndexOps:
15-
def test_ops_properties(self, index_or_series_obj):
12+
@pytest.mark.parametrize("op", PeriodArray._datetimelike_ops)
13+
def test_valid_ops_properties(self, op, index_or_series_obj):
1614
obj = index_or_series_obj
17-
is_valid = isinstance(obj, (DatetimeIndex, PeriodIndex))
18-
if is_valid:
19-
filter_ = lambda x: isinstance(x, PeriodIndex)
20-
check_ops_properties_valid(obj, PeriodArray._field_ops, filter_)
21-
check_ops_properties_valid(obj, PeriodArray._object_ops, filter_)
22-
check_ops_properties_valid(obj, PeriodArray._bool_ops, filter_)
23-
else:
24-
check_ops_properties_invalid(obj, PeriodArray._field_ops)
25-
check_ops_properties_invalid(obj, PeriodArray._object_ops)
26-
check_ops_properties_invalid(obj, PeriodArray._bool_ops)
15+
if isinstance(obj, PeriodIndex):
16+
check_ops_properties_valid(obj, op)
17+
18+
@pytest.mark.parametrize("op", PeriodArray._datetimelike_ops)
19+
def test_invalid_ops_properties(self, op, index_or_series_obj):
20+
obj = index_or_series_obj
21+
if isinstance(obj, (PeriodIndex, DatetimeIndex)):
22+
return
23+
if op == "freq" and isinstance(obj, TimedeltaIndex):
24+
return
25+
26+
with pytest.raises((AttributeError, TypeError)):
27+
getattr(obj, op)
2728

2829
def test_resolution(self):
2930
for freq, expected in zip(

pandas/tests/indexes/timedeltas/test_ops.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,30 @@
66
from pandas.core.dtypes.generic import ABCDateOffset
77

88
import pandas as pd
9-
from pandas import Series, TimedeltaIndex, timedelta_range
9+
from pandas import DatetimeIndex, PeriodIndex, Series, TimedeltaIndex, timedelta_range
1010
from pandas.tests.base.utils import check_ops_properties_valid
1111
import pandas.util.testing as tm
1212

1313
from pandas.tseries.offsets import Day, Hour
1414

1515

1616
class TestTimedeltaIndexOps:
17-
def test_ops_properties(self, index_or_series_obj):
17+
@pytest.mark.parametrize("op", TimedeltaIndex._datetimelike_ops)
18+
def test_valid_ops_properties(self, op, index_or_series_obj):
1819
obj = index_or_series_obj
19-
is_valid = isinstance(obj, TimedeltaIndex)
20-
if is_valid:
21-
filter_ = lambda x: isinstance(x, TimedeltaIndex)
22-
check_ops_properties_valid(obj, TimedeltaIndex._field_ops, filter_)
23-
check_ops_properties_valid(obj, TimedeltaIndex._object_ops, filter_)
20+
if isinstance(obj, TimedeltaIndex):
21+
check_ops_properties_valid(obj, op)
22+
23+
@pytest.mark.parametrize("op", TimedeltaIndex._datetimelike_ops)
24+
def test_invalid_ops_properties(self, op, index_or_series_obj):
25+
obj = index_or_series_obj
26+
if isinstance(obj, TimedeltaIndex):
27+
return
28+
if op == "freq" and isinstance(obj, (DatetimeIndex, PeriodIndex)):
29+
return
30+
31+
with pytest.raises((AttributeError, TypeError)):
32+
getattr(obj, op)
2433

2534
def test_value_counts_unique(self):
2635
# GH 7735

0 commit comments

Comments
 (0)