Skip to content

Cln tests interval wrt inclusive #47775

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 2 commits into from
Jul 18, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion pandas/tests/arrays/test_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ def test_array_inference(data, expected):
[
# mix of frequencies
[pd.Period("2000", "D"), pd.Period("2001", "A")],
# mix of closed
# mix of inclusive
[pd.Interval(0, 1, "left"), pd.Interval(1, 2, "right")],
# Mix of timezones
[pd.Timestamp("2000", tz="CET"), pd.Timestamp("2000", tz="UTC")],
Expand Down
10 changes: 5 additions & 5 deletions pandas/tests/dtypes/test_dtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -593,13 +593,13 @@ def test_construction_string_regex(self, subtype):
@pytest.mark.parametrize(
"subtype", ["interval[int64]", "Interval[int64]", "int64", np.dtype("int64")]
)
def test_construction_allows_closed_none(self, subtype):
def test_construction_allows_inclusive_none(self, subtype):
# GH#38394
dtype = IntervalDtype(subtype)

assert dtype.inclusive is None

def test_closed_mismatch(self):
def test_inclusive_mismatch(self):
msg = "'inclusive' keyword does not match value specified in dtype string"
with pytest.raises(ValueError, match=msg):
IntervalDtype("interval[int64, left]", "right")
Expand Down Expand Up @@ -638,15 +638,15 @@ def test_construction_errors(self, subtype):
with pytest.raises(TypeError, match=msg):
IntervalDtype(subtype)

def test_closed_must_match(self):
def test_inclusive_must_match(self):
# GH#37933
dtype = IntervalDtype(np.float64, "left")

msg = "dtype.inclusive and 'inclusive' do not match"
with pytest.raises(ValueError, match=msg):
IntervalDtype(dtype, inclusive="both")

def test_closed_invalid(self):
def test_inclusive_invalid(self):
with pytest.raises(ValueError, match="inclusive must be one of"):
IntervalDtype(np.float64, "foo")

Expand Down Expand Up @@ -822,7 +822,7 @@ def test_not_string(self):
# GH30568: though IntervalDtype has object kind, it cannot be string
assert not is_string_dtype(IntervalDtype())

def test_unpickling_without_closed(self):
def test_unpickling_without_inclusive(self):
# GH#38394
dtype = IntervalDtype("interval")

Expand Down
22 changes: 11 additions & 11 deletions pandas/tests/indexes/interval/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ def test_constructor_dtype(self, constructor, breaks, subtype):
timedelta_range("1 day", periods=5),
],
)
def test_constructor_pass_closed(self, constructor, breaks):
# not passing closed to IntervalDtype, but to IntervalArray constructor
def test_constructor_pass_inclusive(self, constructor, breaks):
# not passing inclusive to IntervalDtype, but to IntervalArray constructor
warn = None
if isinstance(constructor, partial) and constructor.func is Index:
# passing kwargs to Index is deprecated
Expand Down Expand Up @@ -193,7 +193,7 @@ def test_generic_errors(self, constructor):
# filler input data to be used when supplying invalid kwargs
filler = self.get_kwargs_from_breaks(range(10))

# invalid closed
# invalid inclusive
msg = "inclusive must be one of 'right', 'left', 'both', 'neither'"
with pytest.raises(ValueError, match=msg):
constructor(inclusive="invalid", **filler)
Expand Down Expand Up @@ -399,7 +399,7 @@ def test_constructor_string(self):
pass

def test_constructor_errors(self, constructor):
# mismatched closed within intervals with no constructor override
# mismatched inclusive within intervals with no constructor override
ivs = [Interval(0, 1, inclusive="right"), Interval(2, 3, inclusive="left")]
msg = "intervals must all be inclusive on the same side"
with pytest.raises(ValueError, match=msg):
Expand All @@ -420,7 +420,7 @@ def test_constructor_errors(self, constructor):

@pytest.mark.filterwarnings("ignore:Passing keywords other:FutureWarning")
@pytest.mark.parametrize(
"data, closed",
"data, inclusive",
[
([], "both"),
([np.nan, np.nan], "neither"),
Expand All @@ -438,14 +438,14 @@ def test_constructor_errors(self, constructor):
(IntervalIndex.from_breaks(range(5), inclusive="both"), "right"),
],
)
def test_override_inferred_closed(self, constructor, data, closed):
def test_override_inferred_inclusive(self, constructor, data, inclusive):
# GH 19370
if isinstance(data, IntervalIndex):
tuples = data.to_tuples()
else:
tuples = [(iv.left, iv.right) if notna(iv) else iv for iv in data]
expected = IntervalIndex.from_tuples(tuples, inclusive=closed)
result = constructor(data, inclusive=closed)
expected = IntervalIndex.from_tuples(tuples, inclusive=inclusive)
result = constructor(data, inclusive=inclusive)
tm.assert_index_equal(result, expected)

@pytest.mark.parametrize(
Expand All @@ -460,7 +460,7 @@ def test_index_object_dtype(self, values_constructor):
assert type(result) is Index
tm.assert_numpy_array_equal(result.values, np.array(values))

def test_index_mixed_closed(self):
def test_index_mixed_inclusive(self):
# GH27172
intervals = [
Interval(0, 1, inclusive="left"),
Expand All @@ -473,8 +473,8 @@ def test_index_mixed_closed(self):
tm.assert_index_equal(result, expected)


def test_dtype_closed_mismatch():
# GH#38394 closed specified in both dtype and IntervalIndex constructor
def test_dtype_inclusive_mismatch():
# GH#38394

dtype = IntervalDtype(np.int64, "left")

Expand Down
8 changes: 4 additions & 4 deletions pandas/tests/indexes/interval/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,20 @@ def test_get_loc_length_one_scalar(self, scalar, closed):
with pytest.raises(KeyError, match=str(scalar)):
index.get_loc(scalar)

@pytest.mark.parametrize("other_closed", ["left", "right", "both", "neither"])
@pytest.mark.parametrize("other_inclusive", ["left", "right", "both", "neither"])
@pytest.mark.parametrize("left, right", [(0, 5), (-1, 4), (-1, 6), (6, 7)])
def test_get_loc_length_one_interval(self, left, right, closed, other_closed):
def test_get_loc_length_one_interval(self, left, right, closed, other_inclusive):
# GH 20921
index = IntervalIndex.from_tuples([(0, 5)], inclusive=closed)
interval = Interval(left, right, inclusive=other_closed)
interval = Interval(left, right, inclusive=other_inclusive)
if interval == index[0]:
result = index.get_loc(interval)
assert result == 0
else:
with pytest.raises(
KeyError,
match=re.escape(
f"Interval({left}, {right}, inclusive='{other_closed}')"
f"Interval({left}, {right}, inclusive='{other_inclusive}')"
),
):
index.get_loc(interval)
Expand Down
7 changes: 2 additions & 5 deletions pandas/tests/indexes/interval/test_pickle.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import pytest

from pandas import IntervalIndex
import pandas._testing as tm


class TestPickle:
@pytest.mark.parametrize("inclusive", ["left", "right", "both"])
def test_pickle_round_trip_closed(self, inclusive):
def test_pickle_round_trip_inclusive(self, closed):
# https://github.com/pandas-dev/pandas/issues/35658
idx = IntervalIndex.from_tuples([(1, 2), (2, 3)], inclusive=inclusive)
idx = IntervalIndex.from_tuples([(1, 2), (2, 3)], inclusive=closed)
result = tm.round_trip_pickle(idx)
tm.assert_index_equal(result, idx)
50 changes: 25 additions & 25 deletions pandas/tests/indexes/interval/test_setops.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@
import pandas._testing as tm


def monotonic_index(start, end, dtype="int64", closed="right"):
def monotonic_index(start, end, dtype="int64", inclusive="right"):
return IntervalIndex.from_breaks(
np.arange(start, end, dtype=dtype), inclusive=closed
np.arange(start, end, dtype=dtype), inclusive=inclusive
)


def empty_index(dtype="int64", closed="right"):
return IntervalIndex(np.array([], dtype=dtype), inclusive=closed)
def empty_index(dtype="int64", inclusive="right"):
return IntervalIndex(np.array([], dtype=dtype), inclusive=inclusive)


class TestIntervalIndex:
def test_union(self, closed, sort):
index = monotonic_index(0, 11, closed=closed)
other = monotonic_index(5, 13, closed=closed)
index = monotonic_index(0, 11, inclusive=closed)
other = monotonic_index(5, 13, inclusive=closed)

expected = monotonic_index(0, 13, closed=closed)
expected = monotonic_index(0, 13, inclusive=closed)
result = index[::-1].union(other, sort=sort)
if sort is None:
tm.assert_index_equal(result, expected)
Expand All @@ -41,31 +41,31 @@ def test_union(self, closed, sort):

def test_union_empty_result(self, closed, sort):
# GH 19101: empty result, same dtype
index = empty_index(dtype="int64", closed=closed)
index = empty_index(dtype="int64", inclusive=closed)
result = index.union(index, sort=sort)
tm.assert_index_equal(result, index)

# GH 19101: empty result, different numeric dtypes -> common dtype is f8
other = empty_index(dtype="float64", closed=closed)
other = empty_index(dtype="float64", inclusive=closed)
result = index.union(other, sort=sort)
expected = other
tm.assert_index_equal(result, expected)

other = index.union(index, sort=sort)
tm.assert_index_equal(result, expected)

other = empty_index(dtype="uint64", closed=closed)
other = empty_index(dtype="uint64", inclusive=closed)
result = index.union(other, sort=sort)
tm.assert_index_equal(result, expected)

result = other.union(index, sort=sort)
tm.assert_index_equal(result, expected)

def test_intersection(self, closed, sort):
index = monotonic_index(0, 11, closed=closed)
other = monotonic_index(5, 13, closed=closed)
index = monotonic_index(0, 11, inclusive=closed)
other = monotonic_index(5, 13, inclusive=closed)

expected = monotonic_index(5, 11, closed=closed)
expected = monotonic_index(5, 11, inclusive=closed)
result = index[::-1].intersection(other, sort=sort)
if sort is None:
tm.assert_index_equal(result, expected)
Expand Down Expand Up @@ -100,21 +100,21 @@ def test_intersection(self, closed, sort):
tm.assert_index_equal(result, expected)

def test_intersection_empty_result(self, closed, sort):
index = monotonic_index(0, 11, closed=closed)
index = monotonic_index(0, 11, inclusive=closed)

# GH 19101: empty result, same dtype
other = monotonic_index(300, 314, closed=closed)
expected = empty_index(dtype="int64", closed=closed)
other = monotonic_index(300, 314, inclusive=closed)
expected = empty_index(dtype="int64", inclusive=closed)
result = index.intersection(other, sort=sort)
tm.assert_index_equal(result, expected)

# GH 19101: empty result, different numeric dtypes -> common dtype is float64
other = monotonic_index(300, 314, dtype="float64", closed=closed)
other = monotonic_index(300, 314, dtype="float64", inclusive=closed)
result = index.intersection(other, sort=sort)
expected = other[:0]
tm.assert_index_equal(result, expected)

other = monotonic_index(300, 314, dtype="uint64", closed=closed)
other = monotonic_index(300, 314, dtype="uint64", inclusive=closed)
result = index.intersection(other, sort=sort)
tm.assert_index_equal(result, expected)

Expand All @@ -136,7 +136,7 @@ def test_difference(self, closed, sort):

# GH 19101: empty result, same dtype
result = index.difference(index, sort=sort)
expected = empty_index(dtype="int64", closed=closed)
expected = empty_index(dtype="int64", inclusive=closed)
tm.assert_index_equal(result, expected)

# GH 19101: empty result, different dtypes
Expand All @@ -147,7 +147,7 @@ def test_difference(self, closed, sort):
tm.assert_index_equal(result, expected)

def test_symmetric_difference(self, closed, sort):
index = monotonic_index(0, 11, closed=closed)
index = monotonic_index(0, 11, inclusive=closed)
result = index[1:].symmetric_difference(index[:-1], sort=sort)
expected = IntervalIndex([index[0], index[-1]])
if sort is None:
Expand All @@ -156,7 +156,7 @@ def test_symmetric_difference(self, closed, sort):

# GH 19101: empty result, same dtype
result = index.symmetric_difference(index, sort=sort)
expected = empty_index(dtype="int64", closed=closed)
expected = empty_index(dtype="int64", inclusive=closed)
if sort is None:
tm.assert_index_equal(result, expected)
assert tm.equalContents(result, expected)
Expand All @@ -166,15 +166,15 @@ def test_symmetric_difference(self, closed, sort):
index.left.astype("float64"), index.right, inclusive=closed
)
result = index.symmetric_difference(other, sort=sort)
expected = empty_index(dtype="float64", closed=closed)
expected = empty_index(dtype="float64", inclusive=closed)
tm.assert_index_equal(result, expected)

@pytest.mark.filterwarnings("ignore:'<' not supported between:RuntimeWarning")
@pytest.mark.parametrize(
"op_name", ["union", "intersection", "difference", "symmetric_difference"]
)
def test_set_incompatible_types(self, closed, op_name, sort):
index = monotonic_index(0, 11, closed=closed)
index = monotonic_index(0, 11, inclusive=closed)
set_op = getattr(index, op_name)

# TODO: standardize return type of non-union setops type(self vs other)
Expand All @@ -187,8 +187,8 @@ def test_set_incompatible_types(self, closed, op_name, sort):
tm.assert_index_equal(result, expected)

# mixed closed -> cast to object
for other_closed in {"right", "left", "both", "neither"} - {closed}:
other = monotonic_index(0, 11, closed=other_closed)
for other_inclusive in {"right", "left", "both", "neither"} - {closed}:
other = monotonic_index(0, 11, inclusive=other_inclusive)
expected = getattr(index.astype(object), op_name)(other, sort=sort)
if op_name == "difference":
expected = index
Expand Down
4 changes: 2 additions & 2 deletions pandas/tests/series/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -1200,8 +1200,8 @@ def test_constructor_infer_interval(self, data_constructor):
@pytest.mark.parametrize(
"data_constructor", [list, np.array], ids=["list", "ndarray[object]"]
)
def test_constructor_interval_mixed_closed(self, data_constructor):
# GH 23563: mixed closed results in object dtype (not interval dtype)
def test_constructor_interval_mixed_inclusive(self, data_constructor):
# GH 23563: mixed inclusive results in object dtype (not interval dtype)
data = [Interval(0, 1, inclusive="both"), Interval(0, 2, inclusive="neither")]
result = Series(data_constructor(data))
assert result.dtype == object
Expand Down