Skip to content

TST: fixturize, collect #44242

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

Merged
merged 6 commits into from
Oct 31, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
17 changes: 17 additions & 0 deletions pandas/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,23 @@ def all_binary_operators(request):
return request.param


@pytest.fixture(
Copy link
Contributor

@jreback jreback Oct 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this all_compare_operators in this file ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't really distinguish the naming here. e.g. for arithmetic we have
all_binary_operations (using operator) and all_arithmetic_operators.

so ideally have some good pattern here.

maybe
all_comparison_operators (use operator)
all_comparison_dunder (use dunder)

would have to fix a bunch of things but prob worth it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yah not something i want to futz with

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure but we cannot add it like this, so need to do something. e.g. move next to the others & rename this one to conform.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will move this down adjacent to all_compare_operators

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like most of the places here we use the dunder one then do a getattr(operator, all_comparison_operators.strip("__")), so will just replace those usages with this

params=[
operator.eq,
operator.ne,
operator.gt,
operator.ge,
operator.lt,
operator.le,
]
)
def comparison_op(request):
"""
Fixture for operator module comparison functions.
"""
return request.param


@pytest.fixture(
params=[
operator.add,
Expand Down
40 changes: 13 additions & 27 deletions pandas/tests/arithmetic/test_datetime64.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,18 +365,14 @@ def test_dt64arr_timestamp_equality(self, box_with_array):
class TestDatetimeIndexComparisons:

# TODO: moved from tests.indexes.test_base; parametrize and de-duplicate
@pytest.mark.parametrize(
"op",
[operator.eq, operator.ne, operator.gt, operator.lt, operator.ge, operator.le],
)
def test_comparators(self, op):
def test_comparators(self, comparison_op):
index = tm.makeDateIndex(100)
element = index[len(index) // 2]
element = Timestamp(element).to_datetime64()

arr = np.array(index)
arr_result = op(arr, element)
index_result = op(index, element)
arr_result = comparison_op(arr, element)
index_result = comparison_op(index, element)

assert isinstance(index_result, np.ndarray)
tm.assert_numpy_array_equal(arr_result, index_result)
Expand Down Expand Up @@ -554,12 +550,9 @@ def test_dti_cmp_nat_behaves_like_float_cmp_nan(self):
expected = np.array([True, True, False, True, True, True])
tm.assert_numpy_array_equal(result, expected)

@pytest.mark.parametrize(
"op",
[operator.eq, operator.ne, operator.gt, operator.ge, operator.lt, operator.le],
)
def test_comparison_tzawareness_compat(self, op, box_with_array):
def test_comparison_tzawareness_compat(self, comparison_op, box_with_array):
# GH#18162
op = comparison_op
box = box_with_array

dr = date_range("2016-01-01", periods=6)
Expand Down Expand Up @@ -606,12 +599,10 @@ def test_comparison_tzawareness_compat(self, op, box_with_array):
assert np.all(np.array(tolist(dz), dtype=object) == dz)
assert np.all(dz == np.array(tolist(dz), dtype=object))

@pytest.mark.parametrize(
"op",
[operator.eq, operator.ne, operator.gt, operator.ge, operator.lt, operator.le],
)
def test_comparison_tzawareness_compat_scalars(self, op, box_with_array):
def test_comparison_tzawareness_compat_scalars(self, comparison_op, box_with_array):
# GH#18162
op = comparison_op

dr = date_range("2016-01-01", periods=6)
dz = dr.tz_localize("US/Pacific")

Expand All @@ -638,10 +629,6 @@ def test_comparison_tzawareness_compat_scalars(self, op, box_with_array):
with pytest.raises(TypeError, match=msg):
op(ts, dz)

@pytest.mark.parametrize(
"op",
[operator.eq, operator.ne, operator.gt, operator.ge, operator.lt, operator.le],
)
@pytest.mark.parametrize(
"other",
[datetime(2016, 1, 1), Timestamp("2016-01-01"), np.datetime64("2016-01-01")],
Expand All @@ -652,8 +639,9 @@ def test_comparison_tzawareness_compat_scalars(self, op, box_with_array):
@pytest.mark.filterwarnings("ignore:elementwise comp:DeprecationWarning")
@pytest.mark.filterwarnings("ignore:Converting timezone-aware:FutureWarning")
def test_scalar_comparison_tzawareness(
self, op, other, tz_aware_fixture, box_with_array
self, comparison_op, other, tz_aware_fixture, box_with_array
):
op = comparison_op
box = box_with_array
tz = tz_aware_fixture
dti = date_range("2016-01-01", periods=2, tz=tz)
Expand All @@ -680,13 +668,11 @@ def test_scalar_comparison_tzawareness(
with pytest.raises(TypeError, match=msg):
op(other, dtarr)

@pytest.mark.parametrize(
"op",
[operator.eq, operator.ne, operator.gt, operator.ge, operator.lt, operator.le],
)
def test_nat_comparison_tzawareness(self, op):
def test_nat_comparison_tzawareness(self, comparison_op):
# GH#19276
# tzaware DatetimeIndex should not raise when compared to NaT
op = comparison_op

dti = DatetimeIndex(
["2014-01-01", NaT, "2014-03-01", NaT, "2014-05-01", "2014-07-01"]
)
Expand Down
13 changes: 13 additions & 0 deletions pandas/tests/indexes/base_class/test_reshape.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ def test_insert(self):
null_index = Index([])
tm.assert_index_equal(Index(["a"]), null_index.insert(0, "a"))

def test_insert_missing(self, nulls_fixture):
# GH#22295
# test there is no mangling of NA values
expected = Index(["a", nulls_fixture, "b", "c"])
result = Index(list("abc")).insert(1, nulls_fixture)
tm.assert_index_equal(result, expected)

@pytest.mark.parametrize(
"pos,expected",
[
Expand All @@ -48,6 +55,12 @@ def test_delete(self, pos, expected):
tm.assert_index_equal(result, expected)
assert result.name == expected.name

def test_delete_raises(self):
index = Index(["a", "b", "c", "d"], name="index")
msg = "index 5 is out of bounds for axis 0 with size 4"
with pytest.raises(IndexError, match=msg):
index.delete(5)

def test_append_multiple(self):
index = Index(["a", "b", "c", "d", "e", "f"])

Expand Down
5 changes: 4 additions & 1 deletion pandas/tests/indexes/categorical/test_reindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


class TestReindex:
def test_reindex_dtype(self):
def test_reindex_list_non_unique(self):
# GH#11586
ci = CategoricalIndex(["a", "b", "c", "a"])
with tm.assert_produces_warning(FutureWarning, match="non-unique"):
Expand All @@ -19,6 +19,7 @@ def test_reindex_dtype(self):
tm.assert_index_equal(res, Index(["a", "a", "c"]), exact=True)
tm.assert_numpy_array_equal(indexer, np.array([0, 3, 2], dtype=np.intp))

def test_reindex_categorcal_non_unique(self):
ci = CategoricalIndex(["a", "b", "c", "a"])
with tm.assert_produces_warning(FutureWarning, match="non-unique"):
res, indexer = ci.reindex(Categorical(["a", "c"]))
Expand All @@ -27,13 +28,15 @@ def test_reindex_dtype(self):
tm.assert_index_equal(res, exp, exact=True)
tm.assert_numpy_array_equal(indexer, np.array([0, 3, 2], dtype=np.intp))

def test_reindex_list_non_unique_unused_category(self):
ci = CategoricalIndex(["a", "b", "c", "a"], categories=["a", "b", "c", "d"])
with tm.assert_produces_warning(FutureWarning, match="non-unique"):
res, indexer = ci.reindex(["a", "c"])
exp = Index(["a", "a", "c"], dtype="object")
tm.assert_index_equal(res, exp, exact=True)
tm.assert_numpy_array_equal(indexer, np.array([0, 3, 2], dtype=np.intp))

def test_reindex_categorical_non_unique_unused_category(self):
ci = CategoricalIndex(["a", "b", "c", "a"], categories=["a", "b", "c", "d"])
with tm.assert_produces_warning(FutureWarning, match="non-unique"):
res, indexer = ci.reindex(Categorical(["a", "c"]))
Expand Down
13 changes: 7 additions & 6 deletions pandas/tests/indexes/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,23 +333,24 @@ def test_numpy_argsort(self, index):
expected = index.argsort()
tm.assert_numpy_array_equal(result, expected)

if not isinstance(index, RangeIndex):
# TODO: add compatibility to RangeIndex?
result = np.argsort(index, kind="mergesort")
expected = index.argsort(kind="mergesort")
tm.assert_numpy_array_equal(result, expected)

# these are the only two types that perform
# pandas compatibility input validation - the
# rest already perform separate (or no) such
# validation via their 'values' attribute as
# defined in pandas.core.indexes/base.py - they
# cannot be changed at the moment due to
# backwards compatibility concerns
if isinstance(type(index), (CategoricalIndex, RangeIndex)):
# TODO: why type(index)?
if isinstance(index, (CategoricalIndex, RangeIndex)):
msg = "the 'axis' parameter is not supported"
with pytest.raises(ValueError, match=msg):
np.argsort(index, axis=1)

msg = "the 'kind' parameter is not supported"
with pytest.raises(ValueError, match=msg):
np.argsort(index, kind="mergesort")

msg = "the 'order' parameter is not supported"
with pytest.raises(ValueError, match=msg):
np.argsort(index, order=("a", "b"))
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/indexes/datetimes/test_pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def test_pickle(self):
assert idx_p[2] == idx[2]

def test_pickle_dont_infer_freq(self):
# GH##11002
# GH#11002
# don't infer freq
idx = date_range("1750-1-1", "2050-1-1", freq="7D")
idx_p = tm.round_trip_pickle(idx)
Expand Down
24 changes: 10 additions & 14 deletions pandas/tests/indexes/datetimes/test_unique.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
timedelta,
)

import pytest

from pandas import (
DatetimeIndex,
NaT,
Expand All @@ -13,18 +11,12 @@
import pandas._testing as tm


@pytest.mark.parametrize(
"arr, expected",
[
(DatetimeIndex(["2017", "2017"]), DatetimeIndex(["2017"])),
(
DatetimeIndex(["2017", "2017"], tz="US/Eastern"),
DatetimeIndex(["2017"], tz="US/Eastern"),
),
],
)
def test_unique(arr, expected):
result = arr.unique()
def test_unique(tz_naive_fixture):

idx = DatetimeIndex(["2017"] * 2, tz=tz_naive_fixture)
expected = idx[:1]

result = idx.unique()
tm.assert_index_equal(result, expected)
# GH#21737
# Ensure the underlying data is consistent
Expand Down Expand Up @@ -60,13 +52,17 @@ def test_index_unique(rand_series_with_duplicate_datetimeindex):
assert result.name == "foo"
tm.assert_index_equal(result, expected)


def test_index_unique2():
# NaT, note this is excluded
arr = [1370745748 + t for t in range(20)] + [NaT.value]
idx = DatetimeIndex(arr * 3)
tm.assert_index_equal(idx.unique(), DatetimeIndex(arr))
assert idx.nunique() == 20
assert idx.nunique(dropna=False) == 21


def test_index_unique3():
arr = [
Timestamp("2013-06-09 02:42:28") + timedelta(seconds=t) for t in range(20)
] + [NaT]
Expand Down
8 changes: 5 additions & 3 deletions pandas/tests/indexes/period/test_join.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@ def test_join_does_not_recur(self):
c_idx_type="p",
r_idx_type="dt",
)
s = df.iloc[:2, 0]
ser = df.iloc[:2, 0]

res = s.index.join(df.columns, how="outer")
expected = Index([s.index[0], s.index[1], df.columns[0], df.columns[1]], object)
res = ser.index.join(df.columns, how="outer")
expected = Index(
[ser.index[0], ser.index[1], df.columns[0], df.columns[1]], object
)
tm.assert_index_equal(res, expected)

def test_join_mismatched_freq_raises(self):
Expand Down
4 changes: 2 additions & 2 deletions pandas/tests/indexes/test_any_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def test_tolist_matches_list(self, index):
class TestRoundTrips:
def test_pickle_roundtrip(self, index):
result = tm.round_trip_pickle(index)
tm.assert_index_equal(result, index)
tm.assert_index_equal(result, index, exact=True)
if result.nlevels > 1:
# GH#8367 round-trip with timezone
assert index.equal_levels(result)
Expand All @@ -133,7 +133,7 @@ class TestIndexing:
def test_slice_keeps_name(self, index):
assert index.name == index[1:].name

@pytest.mark.parametrize("item", [101, "no_int"])
@pytest.mark.parametrize("item", [101, "no_int", 2.5])
# FutureWarning from non-tuple sequence of nd indexing
@pytest.mark.filterwarnings("ignore::FutureWarning")
def test_getitem_error(self, index, item):
Expand Down
55 changes: 2 additions & 53 deletions pandas/tests/indexes/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,50 +181,13 @@ def test_constructor_from_frame_series_freq(self):
freq = pd.infer_freq(df["date"])
assert freq == "MS"

@pytest.mark.parametrize(
"array",
[
np.arange(5),
np.array(["a", "b", "c"]),
date_range("2000-01-01", periods=3).values,
],
)
def test_constructor_ndarray_like(self, array):
# GH 5460#issuecomment-44474502
# it should be possible to convert any object that satisfies the numpy
# ndarray interface directly into an Index
class ArrayLike:
def __init__(self, array):
self.array = array

def __array__(self, dtype=None) -> np.ndarray:
return self.array

expected = Index(array)
result = Index(ArrayLike(array))
tm.assert_index_equal(result, expected)

def test_constructor_int_dtype_nan(self):
# see gh-15187
data = [np.nan]
expected = Float64Index(data)
result = Index(data, dtype="float")
tm.assert_index_equal(result, expected)

@pytest.mark.parametrize("dtype", ["int64", "uint64"])
def test_constructor_int_dtype_nan_raises(self, dtype):
# see gh-15187
data = [np.nan]
msg = "cannot convert"
with pytest.raises(ValueError, match=msg):
Index(data, dtype=dtype)

def test_constructor_no_pandas_array(self):
ser = Series([1, 2, 3])
result = Index(ser.array)
expected = Index([1, 2, 3])
tm.assert_index_equal(result, expected)

@pytest.mark.parametrize(
"klass,dtype,na_val",
[
Expand Down Expand Up @@ -497,19 +460,6 @@ def test_equals_object(self):
def test_not_equals_object(self, comp):
assert not Index(["a", "b", "c"]).equals(comp)

def test_insert_missing(self, nulls_fixture):
# GH 22295
# test there is no mangling of NA values
expected = Index(["a", nulls_fixture, "b", "c"])
result = Index(list("abc")).insert(1, nulls_fixture)
tm.assert_index_equal(result, expected)

def test_delete_raises(self):
index = Index(["a", "b", "c", "d"], name="index")
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):

# index
Expand Down Expand Up @@ -1574,10 +1524,9 @@ def test_is_monotonic_na(self, index):
assert index._is_strictly_monotonic_increasing is False
assert index._is_strictly_monotonic_decreasing is False

@pytest.mark.parametrize("klass", [Series, DataFrame])
def test_int_name_format(self, klass):
def test_int_name_format(self, frame_or_series):
index = Index(["a", "b", "c"], name=0)
result = klass(list(range(3)), index=index)
result = frame_or_series(list(range(3)), index=index)
assert "0" in repr(result)

def test_str_to_bytes_raises(self):
Expand Down
Loading