Skip to content

Commit

Permalink
DEPR: Deprecate set_closed and add set_incluive (pandas-dev#47636)
Browse files Browse the repository at this point in the history
* DEPR: Deprecate set_closed and add set_incluive

* Remove set closed

* Revert "Remove set closed"

This reverts commit 15ec590.

* Add set closed

* Add set closed

* Add whatsnew
  • Loading branch information
phofl authored and yehoshuadimarsky committed Jul 13, 2022
1 parent 59228f1 commit 30c8bdc
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 27 deletions.
1 change: 1 addition & 0 deletions doc/redirects.csv
Expand Up @@ -761,6 +761,7 @@ generated/pandas.IntervalIndex.mid,../reference/api/pandas.IntervalIndex.mid
generated/pandas.IntervalIndex.overlaps,../reference/api/pandas.IntervalIndex.overlaps
generated/pandas.IntervalIndex.right,../reference/api/pandas.IntervalIndex.right
generated/pandas.IntervalIndex.set_closed,../reference/api/pandas.IntervalIndex.set_closed
generated/pandas.IntervalIndex.set_inclusive,../reference/api/pandas.IntervalIndex.set_inclusive
generated/pandas.IntervalIndex.to_tuples,../reference/api/pandas.IntervalIndex.to_tuples
generated/pandas.IntervalIndex.values,../reference/api/pandas.IntervalIndex.values
generated/pandas.Interval.left,../reference/api/pandas.Interval.left
Expand Down
1 change: 1 addition & 0 deletions doc/source/reference/arrays.rst
Expand Up @@ -352,6 +352,7 @@ A collection of intervals may be stored in an :class:`arrays.IntervalArray`.
arrays.IntervalArray.contains
arrays.IntervalArray.overlaps
arrays.IntervalArray.set_closed
arrays.IntervalArray.set_inclusive
arrays.IntervalArray.to_tuples


Expand Down
1 change: 1 addition & 0 deletions doc/source/reference/indexing.rst
Expand Up @@ -251,6 +251,7 @@ IntervalIndex components
IntervalIndex.get_loc
IntervalIndex.get_indexer
IntervalIndex.set_closed
IntervalIndex.set_inclusive
IntervalIndex.contains
IntervalIndex.overlaps
IntervalIndex.to_tuples
Expand Down
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v1.5.0.rst
Expand Up @@ -762,7 +762,7 @@ Other Deprecations
- Deprecated the ``closed`` argument in :class:`IntervalIndex` in favor of ``inclusive`` argument; In a future version passing ``closed`` will raise (:issue:`40245`)
- Deprecated the ``closed`` argument in :class:`IntervalDtype` in favor of ``inclusive`` argument; In a future version passing ``closed`` will raise (:issue:`40245`)
- Deprecated the ``closed`` argument in :class:`.IntervalArray` in favor of ``inclusive`` argument; In a future version passing ``closed`` will raise (:issue:`40245`)
- Deprecated the ``closed`` argument in :class:`IntervalTree` in favor of ``inclusive`` argument; In a future version passing ``closed`` will raise (:issue:`40245`)
- Deprecated :meth:`.IntervalArray.set_closed` and :meth:`.IntervalIndex.set_closed` in favor of ``set_inclusive``; In a future version ``set_closed`` will get removed (:issue:`40245`)
- Deprecated the ``closed`` argument in :class:`ArrowInterval` in favor of ``inclusive`` argument; In a future version passing ``closed`` will raise (:issue:`40245`)
- Deprecated allowing ``unit="M"`` or ``unit="Y"`` in :class:`Timestamp` constructor with a non-round float value (:issue:`47267`)
- Deprecated the ``display.column_space`` global configuration option (:issue:`7576`)
Expand Down
59 changes: 56 additions & 3 deletions pandas/core/arrays/interval.py
Expand Up @@ -159,6 +159,7 @@
contains
overlaps
set_closed
set_inclusive
to_tuples
%(extra_methods)s\
Expand Down Expand Up @@ -1388,9 +1389,11 @@ def closed(self) -> IntervalClosedType:
Return an %(klass)s identical to the current one, but closed on the
specified side.
.. deprecated:: 1.5.0
Parameters
----------
inclusive : {'left', 'right', 'both', 'neither'}
closed : {'left', 'right', 'both', 'neither'}
Whether the intervals are closed on the left-side, right-side, both
or neither.
Expand Down Expand Up @@ -1423,8 +1426,58 @@ def closed(self) -> IntervalClosedType:
),
}
)
@deprecate_kwarg(old_arg_name="closed", new_arg_name="inclusive")
def set_closed(
def set_closed(self: IntervalArrayT, closed: IntervalClosedType) -> IntervalArrayT:
warnings.warn(
"set_closed is deprecated and will be removed in a future version. "
"Use set_inclusive instead.",
FutureWarning,
stacklevel=find_stack_level(),
)
return self.set_inclusive(closed)

_interval_shared_docs["set_inclusive"] = textwrap.dedent(
"""
Return an %(klass)s identical to the current one, but closed on the
specified side.
.. versionadded:: 1.5
Parameters
----------
inclusive : {'left', 'right', 'both', 'neither'}
Whether the intervals are closed on the left-side, right-side, both
or neither.
Returns
-------
new_index : %(klass)s
%(examples)s\
"""
)

@Appender(
_interval_shared_docs["set_inclusive"]
% {
"klass": "IntervalArray",
"examples": textwrap.dedent(
"""\
Examples
--------
>>> index = pd.arrays.IntervalArray.from_breaks(range(4), "right")
>>> index
<IntervalArray>
[(0, 1], (1, 2], (2, 3]]
Length: 3, dtype: interval[int64, right]
>>> index.set_inclusive('both')
<IntervalArray>
[[0, 1], [1, 2], [2, 3]]
Length: 3, dtype: interval[int64, both]
"""
),
}
)
def set_inclusive(
self: IntervalArrayT, inclusive: IntervalClosedType
) -> IntervalArrayT:
if inclusive not in VALID_CLOSED:
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/indexes/interval.py
Expand Up @@ -179,7 +179,7 @@ def _new_IntervalIndex(cls, d):
),
}
)
@inherit_names(["set_closed", "to_tuples"], IntervalArray, wrap=True)
@inherit_names(["set_closed", "set_inclusive", "to_tuples"], IntervalArray, wrap=True)
@inherit_names(
[
"__array__",
Expand Down
23 changes: 7 additions & 16 deletions pandas/tests/arrays/interval/test_interval.py
Expand Up @@ -60,12 +60,12 @@ def test_is_empty(self, constructor, left, right, closed):


class TestMethods:
@pytest.mark.parametrize("new_closed", ["left", "right", "both", "neither"])
def test_set_closed(self, closed, new_closed):
@pytest.mark.parametrize("new_inclusive", ["left", "right", "both", "neither"])
def test_set_inclusive(self, closed, new_inclusive):
# GH 21670
array = IntervalArray.from_breaks(range(10), inclusive=closed)
result = array.set_closed(new_closed)
expected = IntervalArray.from_breaks(range(10), inclusive=new_closed)
result = array.set_inclusive(new_inclusive)
expected = IntervalArray.from_breaks(range(10), inclusive=new_inclusive)
tm.assert_extension_array_equal(result, expected)

@pytest.mark.parametrize(
Expand Down Expand Up @@ -134,10 +134,10 @@ def test_set_na(self, left_right_dtypes):

tm.assert_extension_array_equal(result, expected)

def test_setitem_mismatched_closed(self):
def test_setitem_mismatched_inclusive(self):
arr = IntervalArray.from_breaks(range(4), "right")
orig = arr.copy()
other = arr.set_closed("both")
other = arr.set_inclusive("both")

msg = "'value.inclusive' is 'both', expected 'right'"
with pytest.raises(ValueError, match=msg):
Expand Down Expand Up @@ -488,17 +488,8 @@ def test_from_arrays_deprecation():
IntervalArray.from_arrays([0, 1, 2], [1, 2, 3], closed="right")


def test_set_closed_deprecated_closed():
def test_set_closed_deprecated():
# GH#40245
array = IntervalArray.from_breaks(range(10))
with tm.assert_produces_warning(FutureWarning):
array.set_closed(closed="both")


def test_set_closed_both_provided_deprecation():
# GH#40245
array = IntervalArray.from_breaks(range(10))
msg = "Can only specify 'closed' or 'inclusive', not both."
with pytest.raises(TypeError, match=msg):
with tm.assert_produces_warning(FutureWarning):
array.set_closed(inclusive="both", closed="both")
12 changes: 6 additions & 6 deletions pandas/tests/indexes/interval/test_interval.py
Expand Up @@ -871,21 +871,21 @@ def test_nbytes(self):
expected = 64 # 4 * 8 * 2
assert result == expected

@pytest.mark.parametrize("new_closed", ["left", "right", "both", "neither"])
def test_set_closed(self, name, closed, new_closed):
@pytest.mark.parametrize("new_inclusive", ["left", "right", "both", "neither"])
def test_set_inclusive(self, name, closed, new_inclusive):
# GH 21670
index = interval_range(0, 5, inclusive=closed, name=name)
result = index.set_closed(new_closed)
expected = interval_range(0, 5, inclusive=new_closed, name=name)
result = index.set_inclusive(new_inclusive)
expected = interval_range(0, 5, inclusive=new_inclusive, name=name)
tm.assert_index_equal(result, expected)

@pytest.mark.parametrize("bad_inclusive", ["foo", 10, "LEFT", True, False])
def test_set_closed_errors(self, bad_inclusive):
def test_set_inclusive_errors(self, bad_inclusive):
# GH 21670
index = interval_range(0, 5)
msg = f"invalid option for 'inclusive': {bad_inclusive}"
with pytest.raises(ValueError, match=msg):
index.set_closed(bad_inclusive)
index.set_inclusive(bad_inclusive)

def test_is_all_dates(self):
# GH 23576
Expand Down

0 comments on commit 30c8bdc

Please sign in to comment.