diff --git a/doc/source/reference/arrays.rst b/doc/source/reference/arrays.rst index fed0d2c5f7827..0d8444841fcae 100644 --- a/doc/source/reference/arrays.rst +++ b/doc/source/reference/arrays.rst @@ -304,6 +304,7 @@ Properties :toctree: api/ Interval.inclusive + Interval.closed Interval.closed_left Interval.closed_right Interval.is_empty diff --git a/pandas/_libs/interval.pyi b/pandas/_libs/interval.pyi index a40a6a1a3e323..3bd5dd2042e69 100644 --- a/pandas/_libs/interval.pyi +++ b/pandas/_libs/interval.pyi @@ -65,6 +65,8 @@ class Interval(IntervalMixin, Generic[_OrderableT]): def right(self: Interval[_OrderableT]) -> _OrderableT: ... @property def inclusive(self) -> IntervalClosedType: ... + @property + def closed(self) -> IntervalClosedType: ... mid: _MidDescriptor length: _LengthDescriptor def __init__( diff --git a/pandas/_libs/interval.pyx b/pandas/_libs/interval.pyx index 178836ff1548b..79b3c0d056735 100644 --- a/pandas/_libs/interval.pyx +++ b/pandas/_libs/interval.pyx @@ -9,6 +9,8 @@ from cpython.datetime cimport ( import_datetime, ) +from pandas.util._exceptions import find_stack_level + import_datetime() cimport cython @@ -229,7 +231,7 @@ def _warning_interval(inclusive: str | None = None, closed: None | lib.NoDefault stacklevel=2, ) if closed is None: - inclusive = "both" + inclusive = "right" elif closed in ("both", "neither", "left", "right"): inclusive = closed else: @@ -364,7 +366,7 @@ cdef class Interval(IntervalMixin): inclusive, closed = _warning_interval(inclusive, closed) if inclusive is None: - inclusive = "both" + inclusive = "right" if inclusive not in VALID_CLOSED: raise ValueError(f"invalid option for 'inclusive': {inclusive}") @@ -379,6 +381,21 @@ cdef class Interval(IntervalMixin): self.right = right self.inclusive = inclusive + @property + def closed(self): + """ + Whether the interval is closed on the left-side, right-side, both or + neither. + + .. deprecated:: 1.5.0 + """ + warnings.warn( + "Attribute `closed` is deprecated in favor of `inclusive`.", + FutureWarning, + stacklevel=find_stack_level(), + ) + return self.inclusive + def _validate_endpoint(self, endpoint): # GH 23013 if not (is_integer_object(endpoint) or is_float_object(endpoint) or diff --git a/pandas/_libs/intervaltree.pxi.in b/pandas/_libs/intervaltree.pxi.in index 9842332bae7ef..1a6106173e58e 100644 --- a/pandas/_libs/intervaltree.pxi.in +++ b/pandas/_libs/intervaltree.pxi.in @@ -69,7 +69,7 @@ cdef class IntervalTree(IntervalMixin): inclusive, closed = _warning_interval(inclusive, closed) if inclusive is None: - inclusive = "both" + inclusive = "right" if inclusive not in ['left', 'right', 'both', 'neither']: raise ValueError("invalid option for 'inclusive': %s" % inclusive) diff --git a/pandas/core/arrays/arrow/_arrow_utils.py b/pandas/core/arrays/arrow/_arrow_utils.py index e0f242e2ced5d..e4bb7dc94cb8d 100644 --- a/pandas/core/arrays/arrow/_arrow_utils.py +++ b/pandas/core/arrays/arrow/_arrow_utils.py @@ -6,9 +6,8 @@ import numpy as np import pyarrow -from pandas._libs import lib -from pandas._libs.interval import _warning_interval from pandas.errors import PerformanceWarning +from pandas.util._decorators import deprecate_kwarg from pandas.util._exceptions import find_stack_level from pandas.core.arrays.interval import VALID_CLOSED @@ -105,15 +104,10 @@ def to_pandas_dtype(self): class ArrowIntervalType(pyarrow.ExtensionType): - def __init__( - self, - subtype, - inclusive: str | None = None, - closed: None | lib.NoDefault = lib.no_default, - ) -> None: + @deprecate_kwarg(old_arg_name="closed", new_arg_name="inclusive") + def __init__(self, subtype, inclusive: str) -> None: # attributes need to be set first before calling # super init (as that calls serialize) - inclusive, closed = _warning_interval(inclusive, closed) assert inclusive in VALID_CLOSED self._closed = inclusive if not isinstance(subtype, pyarrow.DataType): @@ -131,6 +125,15 @@ def subtype(self): def inclusive(self): return self._closed + @property + def closed(self): + warnings.warn( + "Attribute `closed` is deprecated in favor of `inclusive`.", + FutureWarning, + stacklevel=find_stack_level(), + ) + return self._closed + def __arrow_ext_serialize__(self): metadata = {"subtype": str(self.subtype), "inclusive": self.inclusive} return json.dumps(metadata).encode() diff --git a/pandas/core/arrays/interval.py b/pandas/core/arrays/interval.py index e58032c48f8d3..56aae3039f7d6 100644 --- a/pandas/core/arrays/interval.py +++ b/pandas/core/arrays/interval.py @@ -15,6 +15,7 @@ cast, overload, ) +import warnings import numpy as np @@ -25,7 +26,6 @@ VALID_CLOSED, Interval, IntervalMixin, - _warning_interval, intervals_to_interval_bounds, ) from pandas._libs.missing import NA @@ -43,8 +43,10 @@ from pandas.errors import IntCastingNaNError from pandas.util._decorators import ( Appender, + deprecate_kwarg, deprecate_nonkeyword_arguments, ) +from pandas.util._exceptions import find_stack_level from pandas.core.dtypes.cast import LossySetitemError from pandas.core.dtypes.common import ( @@ -220,16 +222,15 @@ def ndim(self) -> Literal[1]: # --------------------------------------------------------------------- # Constructors + @deprecate_kwarg(old_arg_name="closed", new_arg_name="inclusive") def __new__( cls: type[IntervalArrayT], data, inclusive: str | None = None, - closed: None | lib.NoDefault = lib.no_default, dtype: Dtype | None = None, copy: bool = False, verify_integrity: bool = True, ): - inclusive, closed = _warning_interval(inclusive, closed) data = extract_array(data, extract_numpy=True) @@ -267,24 +268,22 @@ def __new__( ) @classmethod + @deprecate_kwarg(old_arg_name="closed", new_arg_name="inclusive") def _simple_new( cls: type[IntervalArrayT], left, right, inclusive=None, - closed: None | lib.NoDefault = lib.no_default, copy: bool = False, dtype: Dtype | None = None, verify_integrity: bool = True, ) -> IntervalArrayT: result = IntervalMixin.__new__(cls) - inclusive, closed = _warning_interval(inclusive, closed) - if inclusive is None and isinstance(dtype, IntervalDtype): inclusive = dtype.inclusive - inclusive = inclusive or "both" + inclusive = inclusive or "right" left = ensure_index(left, copy=copy) right = ensure_index(right, copy=copy) @@ -424,13 +423,17 @@ def _from_factorized( ), } ) + @deprecate_kwarg(old_arg_name="closed", new_arg_name="inclusive") def from_breaks( cls: type[IntervalArrayT], breaks, - inclusive="both", + inclusive: IntervalClosedType | None = None, copy: bool = False, dtype: Dtype | None = None, ) -> IntervalArrayT: + if inclusive is None: + inclusive = "right" + breaks = _maybe_convert_platform_interval(breaks) return cls.from_arrays( @@ -501,14 +504,19 @@ def from_breaks( ), } ) + @deprecate_kwarg(old_arg_name="closed", new_arg_name="inclusive") def from_arrays( cls: type[IntervalArrayT], left, right, - inclusive="both", + inclusive: IntervalClosedType | None = None, copy: bool = False, dtype: Dtype | None = None, ) -> IntervalArrayT: + + if inclusive is None: + inclusive = "right" + left = _maybe_convert_platform_interval(left) right = _maybe_convert_platform_interval(right) @@ -570,13 +578,17 @@ def from_arrays( ), } ) + @deprecate_kwarg(old_arg_name="closed", new_arg_name="inclusive") def from_tuples( cls: type[IntervalArrayT], data, - inclusive="both", + inclusive=None, copy: bool = False, dtype: Dtype | None = None, ) -> IntervalArrayT: + if inclusive is None: + inclusive = "right" + if len(data): left, right = [], [] else: @@ -1355,6 +1367,19 @@ def inclusive(self) -> IntervalClosedType: """ return self.dtype.inclusive + @property + def closed(self) -> IntervalClosedType: + """ + Whether the intervals are closed on the left-side, right-side, both or + neither. + """ + warnings.warn( + "Attribute `closed` is deprecated in favor of `inclusive`.", + FutureWarning, + stacklevel=find_stack_level(), + ) + return self.dtype.inclusive + _interval_shared_docs["set_closed"] = textwrap.dedent( """ Return an %(klass)s identical to the current one, but closed on the @@ -1395,6 +1420,7 @@ def inclusive(self) -> IntervalClosedType: ), } ) + @deprecate_kwarg(old_arg_name="closed", new_arg_name="inclusive") def set_closed( self: IntervalArrayT, inclusive: IntervalClosedType ) -> IntervalArrayT: diff --git a/pandas/core/dtypes/dtypes.py b/pandas/core/dtypes/dtypes.py index 32594854f49ae..20fecbb0095c5 100644 --- a/pandas/core/dtypes/dtypes.py +++ b/pandas/core/dtypes/dtypes.py @@ -10,6 +10,7 @@ MutableMapping, cast, ) +import warnings import numpy as np import pytz @@ -40,6 +41,7 @@ npt, type_t, ) +from pandas.util._exceptions import find_stack_level from pandas.core.dtypes.base import ( ExtensionDtype, @@ -1176,6 +1178,15 @@ def _can_hold_na(self) -> bool: def inclusive(self): return self._closed + @property + def closed(self): + warnings.warn( + "Attribute `closed` is deprecated in favor of `inclusive`.", + FutureWarning, + stacklevel=find_stack_level(), + ) + return self._closed + @property def subtype(self): """ diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index 11e2da47c5738..5f48be921f7c6 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -11,6 +11,7 @@ Hashable, Literal, ) +import warnings import numpy as np @@ -19,7 +20,6 @@ Interval, IntervalMixin, IntervalTree, - _warning_interval, ) from pandas._libs.tslibs import ( BaseOffset, @@ -37,8 +37,12 @@ from pandas.util._decorators import ( Appender, cache_readonly, + deprecate_kwarg, +) +from pandas.util._exceptions import ( + find_stack_level, + rewrite_exception, ) -from pandas.util._exceptions import rewrite_exception from pandas.core.dtypes.cast import ( find_common_type, @@ -209,19 +213,17 @@ class IntervalIndex(ExtensionIndex): # -------------------------------------------------------------------- # Constructors + @deprecate_kwarg(old_arg_name="closed", new_arg_name="inclusive") def __new__( cls, data, inclusive=None, - closed: None | lib.NoDefault = lib.no_default, dtype: Dtype | None = None, copy: bool = False, name: Hashable = None, verify_integrity: bool = True, ) -> IntervalIndex: - inclusive, closed = _warning_interval(inclusive, closed) - name = maybe_extract_name(name, data, cls) with rewrite_exception("IntervalArray", cls.__name__): @@ -235,6 +237,15 @@ def __new__( return cls._simple_new(array, name) + @property + def closed(self): + warnings.warn( + "Attribute `closed` is deprecated in favor of `inclusive`.", + FutureWarning, + stacklevel=find_stack_level(), + ) + return self.inclusive + @classmethod @Appender( _interval_shared_docs["from_breaks"] @@ -251,19 +262,18 @@ def __new__( ), } ) + @deprecate_kwarg(old_arg_name="closed", new_arg_name="inclusive") def from_breaks( cls, breaks, inclusive=None, - closed: None | lib.NoDefault = lib.no_default, name: Hashable = None, copy: bool = False, dtype: Dtype | None = None, ) -> IntervalIndex: - inclusive, closed = _warning_interval(inclusive, closed) if inclusive is None: - inclusive = "both" + inclusive = "right" with rewrite_exception("IntervalArray", cls.__name__): array = IntervalArray.from_breaks( @@ -287,20 +297,19 @@ def from_breaks( ), } ) + @deprecate_kwarg(old_arg_name="closed", new_arg_name="inclusive") def from_arrays( cls, left, right, inclusive=None, - closed: None | lib.NoDefault = lib.no_default, name: Hashable = None, copy: bool = False, dtype: Dtype | None = None, ) -> IntervalIndex: - inclusive, closed = _warning_interval(inclusive, closed) if inclusive is None: - inclusive = "both" + inclusive = "right" with rewrite_exception("IntervalArray", cls.__name__): array = IntervalArray.from_arrays( @@ -324,19 +333,18 @@ def from_arrays( ), } ) + @deprecate_kwarg(old_arg_name="closed", new_arg_name="inclusive") def from_tuples( cls, data, inclusive=None, - closed: None | lib.NoDefault = lib.no_default, name: Hashable = None, copy: bool = False, dtype: Dtype | None = None, ) -> IntervalIndex: - inclusive, closed = _warning_interval(inclusive, closed) if inclusive is None: - inclusive = "both" + inclusive = "right" with rewrite_exception("IntervalArray", cls.__name__): arr = IntervalArray.from_tuples( @@ -974,13 +982,13 @@ def _is_type_compatible(a, b) -> bool: ) +@deprecate_kwarg(old_arg_name="closed", new_arg_name="inclusive") def interval_range( start=None, end=None, periods=None, freq=None, name: Hashable = None, - closed: IntervalClosedType | lib.NoDefault = lib.no_default, inclusive: IntervalClosedType | None = None, ) -> IntervalIndex: """ @@ -1000,6 +1008,10 @@ def interval_range( for numeric and 'D' for datetime-like. name : str, default None Name of the resulting IntervalIndex. + inclusive : {"both", "neither", "left", "right"}, default "both" + Include boundaries; Whether to set each bound as closed or open. + + .. versionadded:: 1.5.0 closed : {'left', 'right', 'both', 'neither'}, default 'right' Whether the intervals are closed on the left-side, right-side, both or neither. @@ -1007,10 +1019,6 @@ def interval_range( .. deprecated:: 1.5.0 Argument `closed` has been deprecated to standardize boundary inputs. Use `inclusive` instead, to set each bound as closed or open. - inclusive : {"both", "neither", "left", "right"}, default "both" - Include boundaries; Whether to set each bound as closed or open. - - .. versionadded:: 1.5.0 Returns ------- @@ -1077,9 +1085,8 @@ def interval_range( IntervalIndex([[1, 2], [2, 3], [3, 4], [4, 5]], dtype='interval[int64, both]') """ - inclusive, closed = _warning_interval(inclusive, closed) if inclusive is None: - inclusive = "both" + inclusive = "right" start = maybe_box_datetimelike(start) end = maybe_box_datetimelike(end) diff --git a/pandas/tests/arrays/interval/test_interval.py b/pandas/tests/arrays/interval/test_interval.py index 44eafc72b1f5f..7ca86408a7f59 100644 --- a/pandas/tests/arrays/interval/test_interval.py +++ b/pandas/tests/arrays/interval/test_interval.py @@ -414,15 +414,15 @@ def test_interval_error_and_warning(): def test_interval_array_error_and_warning(): # GH 40245 - msg = ( - "Deprecated argument `closed` cannot " - "be passed if argument `inclusive` is not None" - ) - with pytest.raises(ValueError, match=msg): - IntervalArray([Interval(0, 1), Interval(1, 5)], closed="both", inclusive="both") - - msg = "Argument `closed` is deprecated in favor of `inclusive`" - with tm.assert_produces_warning(FutureWarning, match=msg, check_stacklevel=False): + msg = "Can only specify 'closed' or 'inclusive', not both." + with pytest.raises(TypeError, match=msg): + with tm.assert_produces_warning(FutureWarning): + IntervalArray( + [Interval(0, 1), Interval(1, 5)], closed="both", inclusive="both" + ) + + msg = "the 'closed'' keyword is deprecated, use 'inclusive' instead." + with tm.assert_produces_warning(FutureWarning, match=msg): IntervalArray([Interval(0, 1), Interval(1, 5)], closed="both") @@ -433,15 +433,13 @@ def test_arrow_interval_type_error_and_warning(): from pandas.core.arrays.arrow._arrow_utils import ArrowIntervalType - msg = ( - "Deprecated argument `closed` cannot " - "be passed if argument `inclusive` is not None" - ) - with pytest.raises(ValueError, match=msg): - ArrowIntervalType(pa.int64(), closed="both", inclusive="both") + msg = "Can only specify 'closed' or 'inclusive', not both." + with pytest.raises(TypeError, match=msg): + with tm.assert_produces_warning(FutureWarning): + ArrowIntervalType(pa.int64(), closed="both", inclusive="both") - msg = "Argument `closed` is deprecated in favor of `inclusive`" - with tm.assert_produces_warning(FutureWarning, match=msg, check_stacklevel=False): + msg = "the 'closed'' keyword is deprecated, use 'inclusive' instead." + with tm.assert_produces_warning(FutureWarning, match=msg): ArrowIntervalType(pa.int64(), closed="both") @@ -460,3 +458,47 @@ def test_interval_index_subtype(timezone, inclusive_endpoints_fixture): dates[:-1], dates[1:], inclusive=inclusive_endpoints_fixture ) tm.assert_index_equal(result, expected) + + +def test_from_tuples_deprecation(): + # GH#40245 + with tm.assert_produces_warning(FutureWarning): + IntervalArray.from_tuples([(0, 1), (1, 2)], closed="right") + + +def test_from_tuples_deprecation_error(): + # GH#40245 + msg = "Can only specify 'closed' or 'inclusive', not both." + with pytest.raises(TypeError, match=msg): + with tm.assert_produces_warning(FutureWarning): + IntervalArray.from_tuples( + [(0, 1), (1, 2)], closed="right", inclusive="right" + ) + + +def test_from_breaks_deprecation(): + # GH#40245 + with tm.assert_produces_warning(FutureWarning): + IntervalArray.from_breaks([0, 1, 2, 3], closed="right") + + +def test_from_arrays_deprecation(): + # GH#40245 + with tm.assert_produces_warning(FutureWarning): + IntervalArray.from_arrays([0, 1, 2], [1, 2, 3], closed="right") + + +def test_set_closed_deprecated_closed(): + # 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") diff --git a/pandas/tests/indexes/interval/test_constructors.py b/pandas/tests/indexes/interval/test_constructors.py index b57bcf7abc1e1..1966f344356a3 100644 --- a/pandas/tests/indexes/interval/test_constructors.py +++ b/pandas/tests/indexes/interval/test_constructors.py @@ -61,6 +61,16 @@ def test_constructor(self, constructor, breaks, closed, name): tm.assert_index_equal(result.left, Index(breaks[:-1])) tm.assert_index_equal(result.right, Index(breaks[1:])) + def test_constructor_inclusive_default(self, constructor, name): + result_kwargs = self.get_kwargs_from_breaks([3, 14, 15, 92, 653]) + inclusive_in = result_kwargs.pop("inclusive", None) + result = constructor(name=name, **result_kwargs) + + if inclusive_in is not None: + result_kwargs["inclusive"] = "right" + expected = constructor(name=name, **result_kwargs) + tm.assert_index_equal(result, expected) + @pytest.mark.parametrize( "breaks, subtype", [ @@ -78,7 +88,7 @@ def test_constructor_dtype(self, constructor, breaks, subtype): expected = constructor(**expected_kwargs) result_kwargs = self.get_kwargs_from_breaks(breaks) - iv_dtype = IntervalDtype(subtype, "both") + iv_dtype = IntervalDtype(subtype, "right") for dtype in (iv_dtype, str(iv_dtype)): result = constructor(dtype=dtype, **result_kwargs) tm.assert_index_equal(result, expected) @@ -219,7 +229,7 @@ class TestFromArrays(ConstructorTests): def constructor(self): return IntervalIndex.from_arrays - def get_kwargs_from_breaks(self, breaks, inclusive="both"): + def get_kwargs_from_breaks(self, breaks, inclusive="right"): """ converts intervals in breaks format to a dictionary of kwargs to specific to the format expected by IntervalIndex.from_arrays @@ -268,7 +278,7 @@ class TestFromBreaks(ConstructorTests): def constructor(self): return IntervalIndex.from_breaks - def get_kwargs_from_breaks(self, breaks, inclusive="both"): + def get_kwargs_from_breaks(self, breaks, inclusive="right"): """ converts intervals in breaks format to a dictionary of kwargs to specific to the format expected by IntervalIndex.from_breaks @@ -306,7 +316,7 @@ class TestFromTuples(ConstructorTests): def constructor(self): return IntervalIndex.from_tuples - def get_kwargs_from_breaks(self, breaks, inclusive="both"): + def get_kwargs_from_breaks(self, breaks, inclusive="right"): """ converts intervals in breaks format to a dictionary of kwargs to specific to the format expected by IntervalIndex.from_tuples @@ -356,7 +366,7 @@ class TestClassConstructors(ConstructorTests): def constructor(self, request): return request.param - def get_kwargs_from_breaks(self, breaks, inclusive="both"): + def get_kwargs_from_breaks(self, breaks, inclusive="right"): """ converts intervals in breaks format to a dictionary of kwargs to specific to the format expected by the IntervalIndex/Index constructors diff --git a/pandas/tests/indexes/interval/test_interval.py b/pandas/tests/indexes/interval/test_interval.py index 4e33c3abd3252..90497780311de 100644 --- a/pandas/tests/indexes/interval/test_interval.py +++ b/pandas/tests/indexes/interval/test_interval.py @@ -897,35 +897,31 @@ def test_is_all_dates(self): def test_interval_index_error_and_warning(self): # GH 40245 - msg = ( - "Deprecated argument `closed` cannot " - "be passed if argument `inclusive` is not None" - ) - with pytest.raises(ValueError, match=msg): - IntervalIndex.from_breaks(range(11), closed="both", inclusive="both") + msg = "Can only specify 'closed' or 'inclusive', not both." + msg_warn = "the 'closed'' keyword is deprecated, use 'inclusive' instead." + with pytest.raises(TypeError, match=msg): + with tm.assert_produces_warning(FutureWarning, match=msg_warn): + IntervalIndex.from_breaks(range(11), closed="both", inclusive="both") - with pytest.raises(ValueError, match=msg): - IntervalIndex.from_arrays([0, 1], [1, 2], closed="both", inclusive="both") + with pytest.raises(TypeError, match=msg): + with tm.assert_produces_warning(FutureWarning, match=msg_warn): + IntervalIndex.from_arrays( + [0, 1], [1, 2], closed="both", inclusive="both" + ) - with pytest.raises(ValueError, match=msg): - IntervalIndex.from_tuples( - [(0, 1), (0.5, 1.5)], closed="both", inclusive="both" - ) + with pytest.raises(TypeError, match=msg): + with tm.assert_produces_warning(FutureWarning, match=msg_warn): + IntervalIndex.from_tuples( + [(0, 1), (0.5, 1.5)], closed="both", inclusive="both" + ) - msg = "Argument `closed` is deprecated in favor of `inclusive`" - with tm.assert_produces_warning( - FutureWarning, match=msg, check_stacklevel=False - ): + with tm.assert_produces_warning(FutureWarning, match=msg_warn): IntervalIndex.from_breaks(range(11), closed="both") - with tm.assert_produces_warning( - FutureWarning, match=msg, check_stacklevel=False - ): + with tm.assert_produces_warning(FutureWarning, match=msg_warn): IntervalIndex.from_arrays([0, 1], [1, 2], closed="both") - with tm.assert_produces_warning( - FutureWarning, match=msg, check_stacklevel=False - ): + with tm.assert_produces_warning(FutureWarning, match=msg_warn): IntervalIndex.from_tuples([(0, 1), (0.5, 1.5)], closed="both") @@ -955,3 +951,9 @@ def test_searchsorted_invalid_argument(arg): msg = "'<' not supported between instances of 'pandas._libs.interval.Interval' and " with pytest.raises(TypeError, match=msg): values.searchsorted(arg) + + +def test_interval_range_deprecated_closed(): + # GH#40245 + with tm.assert_produces_warning(FutureWarning): + interval_range(start=0, end=5, closed="right") diff --git a/pandas/tests/indexes/interval/test_interval_range.py b/pandas/tests/indexes/interval/test_interval_range.py index 255470cf4683e..3bde2f51178dc 100644 --- a/pandas/tests/indexes/interval/test_interval_range.py +++ b/pandas/tests/indexes/interval/test_interval_range.py @@ -360,13 +360,13 @@ def test_errors(self): def test_interval_range_error_and_warning(self): # GH 40245 - msg = ( - "Deprecated argument `closed` cannot " - "be passed if argument `inclusive` is not None" - ) - with pytest.raises(ValueError, match=msg): - interval_range(end=5, periods=4, closed="both", inclusive="both") + msg = "Can only specify 'closed' or 'inclusive', not both." + msg_warn = "the 'closed'' keyword is deprecated, use 'inclusive' instead." + + with pytest.raises(TypeError, match=msg): + with tm.assert_produces_warning(FutureWarning, match=msg_warn): + interval_range(end=5, periods=4, closed="both", inclusive="both") - msg = "Argument `closed` is deprecated in favor of `inclusive`" - with tm.assert_produces_warning(FutureWarning, match=msg): + msg = "the 'closed'' keyword is deprecated, use 'inclusive' instead." + with tm.assert_produces_warning(FutureWarning, match=msg_warn): interval_range(end=5, periods=4, closed="right") diff --git a/pandas/tests/plotting/test_misc.py b/pandas/tests/plotting/test_misc.py index 4d042579701eb..ab8e64be648d4 100644 --- a/pandas/tests/plotting/test_misc.py +++ b/pandas/tests/plotting/test_misc.py @@ -607,7 +607,7 @@ def test_bar_plt_xaxis_intervalrange(self): expected = [Text(0, 0, "([0, 1],)"), Text(1, 0, "([1, 2],)")] s = Series( [1, 2], - index=[interval_range(0, 2)], + index=[interval_range(0, 2, inclusive="both")], ) _check_plot_works(s.plot.bar) assert all(