Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLN: Refactor pandas/tests/base - part3 #30147

Merged
merged 27 commits into from
Feb 1, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4d1750c
added new fixtures that can replace the Ops mixin
SaturnFromTitan Dec 8, 2019
3d04ff2
fixed type hinting
SaturnFromTitan Dec 8, 2019
89d84b4
refactoring according to review comments
SaturnFromTitan Dec 9, 2019
199896f
removing unused variable arr and fixing the _narrow_series data
SaturnFromTitan Dec 9, 2019
e269b09
removing usage of Ops mixin in tests/indexes
SaturnFromTitan Dec 10, 2019
baab827
moved new fixtures to tests/indexes/conftest.py as they're not used a…
SaturnFromTitan Dec 10, 2019
28291f1
using new utils and fixtures in tests/indexes
SaturnFromTitan Dec 10, 2019
589ae3b
fixturizing tests/base/test_ops.py::test_binary_ops_docs
SaturnFromTitan Dec 10, 2019
2bbc3fd
refactoring of tests/indexes/conftest.py
SaturnFromTitan Dec 10, 2019
b3d0252
using pytest.skip instead of early return
SaturnFromTitan Dec 10, 2019
53db63f
skipping broken tests
SaturnFromTitan Dec 10, 2019
891b24c
replaced more return statements with pytest.skip
SaturnFromTitan Dec 10, 2019
8f0fdf6
Merge branch 'master' into refactor-test-base-part3
SaturnFromTitan Jan 23, 2020
69a0a0d
took care of review comments
SaturnFromTitan Jan 23, 2020
0fce4c5
removed redundant tests
SaturnFromTitan Jan 24, 2020
b7892fa
removed changes that aren't needed for this PR anymore
SaturnFromTitan Jan 24, 2020
471f217
moved helper to more appropriate location
SaturnFromTitan Jan 24, 2020
baa4965
Merge branch 'master' into refactor-test-base-part3
SaturnFromTitan Jan 24, 2020
7562479
removed some outdated changes
SaturnFromTitan Jan 24, 2020
85b16cb
moved datetime_series fixture to the root conftest so it's available …
SaturnFromTitan Jan 24, 2020
87e0a5b
using all_arithmetic_functions in test_binary_ops_docs now
SaturnFromTitan Jan 26, 2020
3979b3d
undid some unrelated changes
SaturnFromTitan Jan 26, 2020
452335a
Merge branch 'master' into refactor-test-base-part3
SaturnFromTitan Jan 26, 2020
8bf1142
undid my change in pandas/core/ops/__init__.py and handle the case di…
SaturnFromTitan Jan 27, 2020
c1e9f28
Revert "undid my change in pandas/core/ops/__init__.py and handle the…
SaturnFromTitan Jan 27, 2020
d9bea94
Merge branch 'master' into refactor-test-base-part3
SaturnFromTitan Jan 27, 2020
87247a5
using hard-coded values to parametrize test_binary_ops
SaturnFromTitan Feb 1, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions pandas/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -881,3 +881,72 @@ def index_or_series(request):
See GH#29725
"""
return request.param


_indexes = {
"bool-index": tm.makeBoolIndex(10, name="a"),
"int-index": tm.makeIntIndex(10, name="a"),
"float-index": tm.makeFloatIndex(10, name="a"),
"date-index": tm.makeDateIndex(10, name="a"),
"localized-date-index": tm.makeDateIndex(10, name="a", tz="US/Eastern"),
"period-index": tm.makePeriodIndex(10, name="a"),
"string-index": tm.makeStringIndex(10, name="a"),
"unicode-index": tm.makeUnicodeIndex(10, name="a"),
}


@pytest.fixture(params=_indexes.keys())
def index(request):
"""
Fixture for tests on indexes

copy to avoid mutation, e.g. setting .name
SaturnFromTitan marked this conversation as resolved.
Show resolved Hide resolved
"""
return _indexes[request.param].copy()


_arr = np.random.randn(10)


@pytest.fixture
def int_series():
""" Fixture for Series with random numbers and integer index """
index = _indexes["int-index"].copy()
return pd.Series(_arr, index=index, name=index.name)


_series = {
f"series-with-{i_id}": pd.Series(_arr, index=i, name=i.name)
for i_id, i in _indexes.items()
}

_arr_int = np.random.choice(10, size=10, replace=False)


def _create_narrow_series(data, data_dtype):
""" Helper for the _narrow_series dict """
index = _indexes["int-index"].copy()
return pd.Series(data.astype(data_dtype), index=index, name="a")
SaturnFromTitan marked this conversation as resolved.
Show resolved Hide resolved


_narrow_series = {
"float32-series": _create_narrow_series(_arr, np.float32),
"int8-series": _create_narrow_series(_arr_int, np.int8),
"int16-series": _create_narrow_series(_arr_int, np.int16),
"int32-series": _create_narrow_series(_arr_int, np.int32),
"uint8-series": _create_narrow_series(_arr_int, np.uint8),
"uint16-series": _create_narrow_series(_arr_int, np.uint16),
"uint32-series": _create_narrow_series(_arr_int, np.uint32),
}

_all_objs = {**_indexes, **_series, **_narrow_series}


@pytest.fixture(params=_all_objs.keys())
def index_or_series_obj(request):
SaturnFromTitan marked this conversation as resolved.
Show resolved Hide resolved
"""
Fixture for tests on indexes, series and series with a narrow dtype

copy to avoid mutation, e.g. setting .name
"""
return _all_objs[request.param].copy(deep=True)
43 changes: 22 additions & 21 deletions pandas/tests/base/test_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,27 +130,28 @@ def check_ops_properties(self, props, filter=None, ignore_failures=False):
with pytest.raises(err):
getattr(o, op)

@pytest.mark.parametrize("klass", [Series, DataFrame])
def test_binary_ops_docs(self, klass):
op_map = {
"add": "+",
"sub": "-",
"mul": "*",
"mod": "%",
"pow": "**",
"truediv": "/",
"floordiv": "//",
}
for op_name in op_map:
operand1 = klass.__name__.lower()
operand2 = "other"
op = op_map[op_name]
expected_str = " ".join([operand1, op, operand2])
assert expected_str in getattr(klass, op_name).__doc__

# reverse version of the binary ops
expected_str = " ".join([operand2, op, operand1])
assert expected_str in getattr(klass, "r" + op_name).__doc__

@pytest.mark.parametrize("klass", [Series, DataFrame])
def test_binary_ops_docs(klass):
op_map = {
SaturnFromTitan marked this conversation as resolved.
Show resolved Hide resolved
"add": "+",
"sub": "-",
"mul": "*",
"mod": "%",
"pow": "**",
"truediv": "/",
"floordiv": "//",
}
for op_name in op_map:
operand1 = klass.__name__.lower()
operand2 = "other"
op = op_map[op_name]
expected_str = " ".join([operand1, op, operand2])
assert expected_str in getattr(klass, op_name).__doc__

# reverse version of the binary ops
expected_str = " ".join([operand2, op, operand1])
assert expected_str in getattr(klass, "r" + op_name).__doc__


class TestTranspose(Ops):
Expand Down
59 changes: 59 additions & 0 deletions pandas/tests/base/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from typing import Any, Callable, List, Type

import numpy as np
import pytest

SaturnFromTitan marked this conversation as resolved.
Show resolved Hide resolved
from pandas import Index, Series
from pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin
import pandas.util.testing as tm


def allow_na_ops(obj: Any) -> bool:
SaturnFromTitan marked this conversation as resolved.
Show resolved Hide resolved
"""Whether to skip test cases including NaN"""
is_bool_index = isinstance(obj, Index) and obj.is_boolean()
return not is_bool_index and obj._can_hold_na


def check_ops_properties_valid(obj: Any, props: List[str], filter: Callable) -> None:
""" Validates that certain properties are available """
for op in props:
# if a filter, skip if it doesn't match
index = obj.index if isinstance(obj, Series) else obj
if not filter(index):
continue

try:
if isinstance(obj, Series):
expected = Series(getattr(obj.index, op), index=obj.index, name="a")
else:
expected = getattr(obj, op)
except AttributeError:
continue

result = getattr(obj, op)

# these could be series, arrays or scalars
if isinstance(result, Series) and isinstance(expected, Series):
tm.assert_series_equal(result, expected)
elif isinstance(result, Index) and isinstance(expected, Index):
tm.assert_index_equal(result, expected)
elif isinstance(result, np.ndarray) and isinstance(expected, np.ndarray):
tm.assert_numpy_array_equal(result, expected)
else:
assert result == expected


def check_ops_properties_invalid(obj: Any, props: List[str]) -> None:
""" Validates that certain properties are not available """
for op in props:
# freq raises AttributeError on an Int64Index because its not
# defined we mostly care about Series here anyhow

# an object that is datetimelike will raise a TypeError,
# otherwise an AttributeError
err: Type[Exception] = AttributeError
if issubclass(type(obj), DatetimeIndexOpsMixin):
err = TypeError

with pytest.raises(err):
getattr(obj, op)
SaturnFromTitan marked this conversation as resolved.
Show resolved Hide resolved