From 9e7ae14ca15956d408e264d8bcb98b1dbdbfaf6b Mon Sep 17 00:00:00 2001 From: patrick Date: Thu, 7 Jul 2022 19:28:34 +0200 Subject: [PATCH 1/3] CLN: Rename private variables from closed to inclusive --- pandas/_libs/interval.pyi | 22 +++++----- pandas/_libs/interval.pyx | 50 +++++++++++------------ pandas/_typing.py | 2 +- pandas/core/arrays/arrow/_arrow_utils.py | 10 ++--- pandas/core/arrays/interval.py | 51 ++++++++++++------------ pandas/core/generic.py | 6 +-- pandas/core/indexes/datetimes.py | 6 +-- pandas/core/indexes/interval.py | 16 ++++---- 8 files changed, 83 insertions(+), 80 deletions(-) diff --git a/pandas/_libs/interval.pyi b/pandas/_libs/interval.pyi index 3bd5dd2042e69..aa9de174a95ff 100644 --- a/pandas/_libs/interval.pyi +++ b/pandas/_libs/interval.pyi @@ -12,12 +12,12 @@ import numpy.typing as npt from pandas._libs import lib from pandas._typing import ( - IntervalClosedType, + IntervalInclusiveType, Timedelta, Timestamp, ) -VALID_CLOSED: frozenset[str] +VALID_INCLUSIVE: frozenset[str] _OrderableScalarT = TypeVar("_OrderableScalarT", int, float) _OrderableTimesT = TypeVar("_OrderableTimesT", Timestamp, Timedelta) @@ -52,11 +52,13 @@ class IntervalMixin: def open_right(self) -> bool: ... @property def is_empty(self) -> bool: ... - def _check_closed_matches(self, other: IntervalMixin, name: str = ...) -> None: ... + def _check_inclusive_matches( + self, other: IntervalMixin, name: str = ... + ) -> None: ... def _warning_interval( inclusive, closed -) -> tuple[IntervalClosedType, lib.NoDefault]: ... +) -> tuple[IntervalInclusiveType, lib.NoDefault]: ... class Interval(IntervalMixin, Generic[_OrderableT]): @property @@ -64,17 +66,17 @@ class Interval(IntervalMixin, Generic[_OrderableT]): @property def right(self: Interval[_OrderableT]) -> _OrderableT: ... @property - def inclusive(self) -> IntervalClosedType: ... + def inclusive(self) -> IntervalInclusiveType: ... @property - def closed(self) -> IntervalClosedType: ... + def closed(self) -> IntervalInclusiveType: ... mid: _MidDescriptor length: _LengthDescriptor def __init__( self, left: _OrderableT, right: _OrderableT, - inclusive: IntervalClosedType = ..., - closed: IntervalClosedType = ..., + inclusive: IntervalInclusiveType = ..., + closed: IntervalInclusiveType = ..., ) -> None: ... def __hash__(self) -> int: ... @overload @@ -150,7 +152,7 @@ class Interval(IntervalMixin, Generic[_OrderableT]): def overlaps(self: Interval[_OrderableT], other: Interval[_OrderableT]) -> bool: ... def intervals_to_interval_bounds( - intervals: np.ndarray, validate_closed: bool = ... + intervals: np.ndarray, validate_inclusive: bool = ... ) -> tuple[np.ndarray, np.ndarray, str]: ... class IntervalTree(IntervalMixin): @@ -158,7 +160,7 @@ class IntervalTree(IntervalMixin): self, left: np.ndarray, right: np.ndarray, - inclusive: IntervalClosedType = ..., + inclusive: IntervalInclusiveType = ..., leaf_size: int = ..., ) -> None: ... @property diff --git a/pandas/_libs/interval.pyx b/pandas/_libs/interval.pyx index 79b3c0d056735..bc0a63c5c5a33 100644 --- a/pandas/_libs/interval.pyx +++ b/pandas/_libs/interval.pyx @@ -56,7 +56,7 @@ from pandas._libs.tslibs.util cimport ( is_timedelta64_object, ) -VALID_CLOSED = frozenset(['both', 'neither', 'left', 'right']) +VALID_INCLUSIVE = frozenset(['both', 'neither', 'left', 'right']) cdef class IntervalMixin: @@ -85,7 +85,7 @@ cdef class IntervalMixin: Returns ------- bool - True if the Interval is closed on the left-side. + True if the Interval is closed on the right-side. """ return self.inclusive in ('right', 'both') @@ -99,7 +99,7 @@ cdef class IntervalMixin: Returns ------- bool - True if the Interval is closed on the left-side. + True if the Interval is not closed on the left-side. """ return not self.closed_left @@ -113,7 +113,7 @@ cdef class IntervalMixin: Returns ------- bool - True if the Interval is closed on the left-side. + True if the Interval is not closed on the right-side. """ return not self.closed_right @@ -188,7 +188,7 @@ cdef class IntervalMixin: """ return (self.right == self.left) & (self.inclusive != 'both') - def _check_closed_matches(self, other, name='other'): + def _check_inclusive_matches(self, other, name='other'): """ Check if the inclusive attribute of `other` matches. @@ -203,7 +203,7 @@ cdef class IntervalMixin: Raises ------ ValueError - When `other` is not closed exactly the same as self. + When `other` is not inclusive exactly the same as self. """ if self.inclusive != other.inclusive: raise ValueError(f"'{name}.inclusive' is {repr(other.inclusive)}, " @@ -259,14 +259,14 @@ cdef class Interval(IntervalMixin): .. deprecated:: 1.5.0 inclusive : {'both', 'neither', 'left', 'right'}, default 'both' - Whether the interval is closed on the left-side, right-side, both or + Whether the interval is inclusive on the left-side, right-side, both or neither. See the Notes for more detailed explanation. .. versionadded:: 1.5.0 See Also -------- - IntervalIndex : An Index of Interval objects that are all closed on the + IntervalIndex : An Index of Interval objects that are all inclusive on the same side. cut : Convert continuous data into discrete bins (Categorical of Interval objects). @@ -279,13 +279,13 @@ cdef class Interval(IntervalMixin): The parameters `left` and `right` must be from the same type, you must be able to compare them and they must satisfy ``left <= right``. - A closed interval (in mathematics denoted by square brackets) contains - its endpoints, i.e. the closed interval ``[0, 5]`` is characterized by the + A inclusive interval (in mathematics denoted by square brackets) contains + its endpoints, i.e. the inclusive interval ``[0, 5]`` is characterized by the conditions ``0 <= x <= 5``. This is what ``inclusive='both'`` stands for. An open interval (in mathematics denoted by parentheses) does not contain its endpoints, i.e. the open interval ``(0, 5)`` is characterized by the conditions ``0 < x < 5``. This is what ``inclusive='neither'`` stands for. - Intervals can also be half-open or half-closed, i.e. ``[0, 5)`` is + Intervals can also be half-open or half-inclusive, i.e. ``[0, 5)`` is described by ``0 <= x < 5`` (``inclusive='left'``) and ``(0, 5]`` is described by ``0 < x <= 5`` (``inclusive='right'``). @@ -352,7 +352,7 @@ cdef class Interval(IntervalMixin): cdef readonly str inclusive """ - Whether the interval is closed on the left-side, right-side, both or + Whether the interval is inclusive on the left-side, right-side, both or neither. """ @@ -368,7 +368,7 @@ cdef class Interval(IntervalMixin): if inclusive is None: inclusive = "right" - if inclusive not in VALID_CLOSED: + if inclusive not in VALID_INCLUSIVE: raise ValueError(f"invalid option for 'inclusive': {inclusive}") if not left <= right: raise ValueError("left side of interval must be <= right side") @@ -522,7 +522,7 @@ cdef class Interval(IntervalMixin): """ Check whether two Interval objects overlap. - Two intervals overlap if they share a common point, including closed + Two intervals overlap if they share a common point, including inclusive endpoints. Intervals that only have an open endpoint in common do not overlap. @@ -551,7 +551,7 @@ cdef class Interval(IntervalMixin): >>> i1.overlaps(i3) False - Intervals that share closed endpoints overlap: + Intervals that share inclusive endpoints overlap: >>> i4 = pd.Interval(0, 1, inclusive='both') >>> i5 = pd.Interval(1, 2, inclusive='both') @@ -568,7 +568,7 @@ cdef class Interval(IntervalMixin): raise TypeError("`other` must be an Interval, " f"got {type(other).__name__}") - # equality is okay if both endpoints are closed (overlap at a point) + # equality is okay if both endpoints are inclusive (overlap at a point) op1 = le if (self.closed_left and other.closed_right) else lt op2 = le if (other.closed_left and self.closed_right) else lt @@ -580,16 +580,16 @@ cdef class Interval(IntervalMixin): @cython.wraparound(False) @cython.boundscheck(False) -def intervals_to_interval_bounds(ndarray intervals, bint validate_closed=True): +def intervals_to_interval_bounds(ndarray intervals, bint validate_inclusive=True): """ Parameters ---------- intervals : ndarray Object array of Intervals / nulls. - validate_closed: bool, default True - Boolean indicating if all intervals must be closed on the same side. - Mismatching closed will raise if True, else return None for closed. + validate_inclusive: bool, default True + Boolean indicating if all intervals must be inclusive on the same side. + Mismatching inclusive will raise if True, else return None for inclusive. Returns ------- @@ -602,7 +602,7 @@ def intervals_to_interval_bounds(ndarray intervals, bint validate_closed=True): object inclusive = None, interval Py_ssize_t i, n = len(intervals) ndarray left, right - bint seen_closed = False + bint seen_inclusive = False left = np.empty(n, dtype=intervals.dtype) right = np.empty(n, dtype=intervals.dtype) @@ -620,13 +620,13 @@ def intervals_to_interval_bounds(ndarray intervals, bint validate_closed=True): left[i] = interval.left right[i] = interval.right - if not seen_closed: - seen_closed = True + if not seen_inclusive: + seen_inclusive = True inclusive = interval.inclusive elif inclusive != interval.inclusive: inclusive = None - if validate_closed: - raise ValueError("intervals must all be closed on the same side") + if validate_inclusive: + raise ValueError("intervals must all be inclusive on the same side") return left, right, inclusive diff --git a/pandas/_typing.py b/pandas/_typing.py index ac1237f8841be..4bc5f75400455 100644 --- a/pandas/_typing.py +++ b/pandas/_typing.py @@ -314,7 +314,7 @@ def closed(self) -> bool: # Interval closed type IntervalLeftRight = Literal["left", "right"] -IntervalClosedType = Union[IntervalLeftRight, Literal["both", "neither"]] +IntervalInclusiveType = Union[IntervalLeftRight, Literal["both", "neither"]] # datetime and NaTType DatetimeNaTType = Union[datetime, "NaTType"] diff --git a/pandas/core/arrays/arrow/_arrow_utils.py b/pandas/core/arrays/arrow/_arrow_utils.py index e4bb7dc94cb8d..38f53b1a1b460 100644 --- a/pandas/core/arrays/arrow/_arrow_utils.py +++ b/pandas/core/arrays/arrow/_arrow_utils.py @@ -10,7 +10,7 @@ from pandas.util._decorators import deprecate_kwarg from pandas.util._exceptions import find_stack_level -from pandas.core.arrays.interval import VALID_CLOSED +from pandas.core.arrays.interval import VALID_INCLUSIVE def fallback_performancewarning(version: str | None = None): @@ -108,8 +108,8 @@ class ArrowIntervalType(pyarrow.ExtensionType): def __init__(self, subtype, inclusive: str) -> None: # attributes need to be set first before calling # super init (as that calls serialize) - assert inclusive in VALID_CLOSED - self._closed = inclusive + assert inclusive in VALID_INCLUSIVE + self._inclusive = inclusive if not isinstance(subtype, pyarrow.DataType): subtype = pyarrow.type_for_alias(str(subtype)) self._subtype = subtype @@ -123,7 +123,7 @@ def subtype(self): @property def inclusive(self): - return self._closed + return self._inclusive @property def closed(self): @@ -132,7 +132,7 @@ def closed(self): FutureWarning, stacklevel=find_stack_level(), ) - return self._closed + return self._inclusive def __arrow_ext_serialize__(self): metadata = {"subtype": str(self.subtype), "inclusive": self.inclusive} diff --git a/pandas/core/arrays/interval.py b/pandas/core/arrays/interval.py index 56aae3039f7d6..f8be95fd5c3cf 100644 --- a/pandas/core/arrays/interval.py +++ b/pandas/core/arrays/interval.py @@ -23,7 +23,7 @@ from pandas._libs import lib from pandas._libs.interval import ( - VALID_CLOSED, + VALID_INCLUSIVE, Interval, IntervalMixin, intervals_to_interval_bounds, @@ -32,7 +32,7 @@ from pandas._typing import ( ArrayLike, Dtype, - IntervalClosedType, + IntervalInclusiveType, NpDtype, PositionalIndexer, ScalarIndexer, @@ -127,7 +127,7 @@ Array-like containing Interval objects from which to build the %(klass)s. inclusive : {'left', 'right', 'both', 'neither'}, default 'right' - Whether the intervals are closed on the left-side, right-side, both or + Whether the intervals are inclusive on the left-side, right-side, both or neither. dtype : dtype or None, default None If None, dtype will be inferred. @@ -181,7 +181,8 @@ _interval_shared_docs["class"] % { "klass": "IntervalArray", - "summary": "Pandas array for interval data that are closed on the same side.", + "summary": "Pandas array for interval data that are inclusive on the same " + "side.", "versionadded": "0.24.0", "name": "", "extra_attributes": "", @@ -250,13 +251,13 @@ def __new__( # might need to convert empty or purely na data data = _maybe_convert_platform_interval(data) - left, right, infer_closed = intervals_to_interval_bounds( - data, validate_closed=inclusive is None + left, right, infer_inclusive = intervals_to_interval_bounds( + data, validate_inclusive=inclusive is None ) if left.dtype == object: left = lib.maybe_convert_objects(left) right = lib.maybe_convert_objects(right) - inclusive = inclusive or infer_closed + inclusive = inclusive or infer_inclusive return cls._simple_new( left, @@ -385,7 +386,7 @@ def _from_factorized( breaks : array-like (1-dimensional) Left and right bounds for each interval. inclusive : {'left', 'right', 'both', 'neither'}, default 'right' - Whether the intervals are closed on the left-side, right-side, both + Whether the intervals are inclusive on the left-side, right-side, both or neither. copy : bool, default False Copy the data. @@ -427,7 +428,7 @@ def _from_factorized( def from_breaks( cls: type[IntervalArrayT], breaks, - inclusive: IntervalClosedType | None = None, + inclusive: IntervalInclusiveType | None = None, copy: bool = False, dtype: Dtype | None = None, ) -> IntervalArrayT: @@ -451,7 +452,7 @@ def from_breaks( right : array-like (1-dimensional) Right bounds for each interval. inclusive : {'left', 'right', 'both', 'neither'}, default 'right' - Whether the intervals are closed on the left-side, right-side, both + Whether the intervals are inclusive on the left-side, right-side, both or neither. copy : bool, default False Copy the data. @@ -509,7 +510,7 @@ def from_arrays( cls: type[IntervalArrayT], left, right, - inclusive: IntervalClosedType | None = None, + inclusive: IntervalInclusiveType | None = None, copy: bool = False, dtype: Dtype | None = None, ) -> IntervalArrayT: @@ -538,7 +539,7 @@ def from_arrays( data : array-like (1-dimensional) Array of tuples. inclusive : {'left', 'right', 'both', 'neither'}, default 'right' - Whether the intervals are closed on the left-side, right-side, both + Whether the intervals are inclusive on the left-side, right-side, both or neither. copy : bool, default False By-default copy the data, this is compat only and ignored. @@ -625,7 +626,7 @@ def _validate(self): * left and right have the same missing values * left is always below right """ - if self.inclusive not in VALID_CLOSED: + if self.inclusive not in VALID_INCLUSIVE: msg = f"invalid option for 'inclusive': {self.inclusive}" raise ValueError(msg) if len(self._left) != len(self._right): @@ -741,7 +742,7 @@ def _cmp_method(self, other, op): # for categorical defer to categories for dtype other_dtype = other.categories.dtype - # extract intervals if we have interval categories with matching closed + # extract intervals if we have interval categories with matching inclusive if is_interval_dtype(other_dtype): if self.inclusive != other.categories.inclusive: return invalid_comparison(self, other, op) @@ -750,7 +751,7 @@ def _cmp_method(self, other, op): other.codes, allow_fill=True, fill_value=other.categories._na_value ) - # interval-like -> need same closed and matching endpoints + # interval-like -> need same inclusive and matching endpoints if is_interval_dtype(other_dtype): if self.inclusive != other.inclusive: return invalid_comparison(self, other, op) @@ -990,7 +991,7 @@ def _concat_same_type( """ inclusive_set = {interval.inclusive for interval in to_concat} if len(inclusive_set) != 1: - raise ValueError("Intervals must all be closed on the same side.") + raise ValueError("Intervals must all be inclusive on the same side.") inclusive = inclusive_set.pop() left = np.concatenate([interval.left for interval in to_concat]) @@ -1116,7 +1117,7 @@ def _validate_listlike(self, value): # list-like of intervals try: array = IntervalArray(value) - self._check_closed_matches(array, name="value") + self._check_inclusive_matches(array, name="value") value_left, value_right = array.left, array.right except TypeError as err: # wrong type: not interval or NA @@ -1136,7 +1137,7 @@ def _validate_listlike(self, value): def _validate_scalar(self, value): if isinstance(value, Interval): - self._check_closed_matches(value, name="value") + self._check_inclusive_matches(value, name="value") left, right = value.left, value.right # TODO: check subdtype match like _validate_setitem_value? elif is_valid_na_for_dtype(value, self.left.dtype): @@ -1162,7 +1163,7 @@ def _validate_setitem_value(self, value): elif isinstance(value, Interval): # scalar - self._check_closed_matches(value, name="value") + self._check_inclusive_matches(value, name="value") value_left, value_right = value.left, value.right self.left._validate_fill_value(value_left) self.left._validate_fill_value(value_right) @@ -1348,7 +1349,7 @@ def overlaps(self, other): msg = f"`other` must be Interval-like, got {type(other).__name__}" raise TypeError(msg) - # equality is okay if both endpoints are closed (overlap at a point) + # equality is okay if both endpoints are inclusive (overlap at a point) op1 = le if (self.closed_left and other.closed_right) else lt op2 = le if (other.closed_left and self.closed_right) else lt @@ -1360,15 +1361,15 @@ def overlaps(self, other): # --------------------------------------------------------------------- @property - def inclusive(self) -> IntervalClosedType: + def inclusive(self) -> IntervalInclusiveType: """ - Whether the intervals are closed on the left-side, right-side, both or + Whether the intervals are inclusive on the left-side, right-side, both or neither. """ return self.dtype.inclusive @property - def closed(self) -> IntervalClosedType: + def closed(self) -> IntervalInclusiveType: """ Whether the intervals are closed on the left-side, right-side, both or neither. @@ -1422,9 +1423,9 @@ def closed(self) -> IntervalClosedType: ) @deprecate_kwarg(old_arg_name="closed", new_arg_name="inclusive") def set_closed( - self: IntervalArrayT, inclusive: IntervalClosedType + self: IntervalArrayT, inclusive: IntervalInclusiveType ) -> IntervalArrayT: - if inclusive not in VALID_CLOSED: + if inclusive not in VALID_INCLUSIVE: msg = f"invalid option for 'inclusive': {inclusive}" raise ValueError(msg) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index ba3474a2513fb..09c9a8a1da186 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -48,7 +48,7 @@ IgnoreRaise, IndexKeyFunc, IndexLabel, - IntervalClosedType, + IntervalInclusiveType, JSONSerializable, Level, Manager, @@ -8066,7 +8066,7 @@ def between_time( end_time, include_start: bool_t | lib.NoDefault = lib.no_default, include_end: bool_t | lib.NoDefault = lib.no_default, - inclusive: IntervalClosedType | None = None, + inclusive: IntervalInclusiveType | None = None, axis=None, ) -> NDFrameT: """ @@ -8172,7 +8172,7 @@ def between_time( left = True if include_start is lib.no_default else include_start right = True if include_end is lib.no_default else include_end - inc_dict: dict[tuple[bool_t, bool_t], IntervalClosedType] = { + inc_dict: dict[tuple[bool_t, bool_t], IntervalInclusiveType] = { (True, True): "both", (True, False): "left", (False, True): "right", diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 18c0d56abbeb4..6aa2ff91ba933 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -35,7 +35,7 @@ from pandas._typing import ( Dtype, DtypeObj, - IntervalClosedType, + IntervalInclusiveType, IntervalLeftRight, npt, ) @@ -920,7 +920,7 @@ def date_range( normalize: bool = False, name: Hashable = None, closed: Literal["left", "right"] | None | lib.NoDefault = lib.no_default, - inclusive: IntervalClosedType | None = None, + inclusive: IntervalInclusiveType | None = None, **kwargs, ) -> DatetimeIndex: """ @@ -1126,7 +1126,7 @@ def bdate_range( weekmask=None, holidays=None, closed: IntervalLeftRight | lib.NoDefault | None = lib.no_default, - inclusive: IntervalClosedType | None = None, + inclusive: IntervalInclusiveType | None = None, **kwargs, ) -> DatetimeIndex: """ diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index 5f48be921f7c6..e8326d03fec7a 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -30,7 +30,7 @@ from pandas._typing import ( Dtype, DtypeObj, - IntervalClosedType, + IntervalInclusiveType, npt, ) from pandas.errors import InvalidIndexError @@ -153,7 +153,7 @@ def _new_IntervalIndex(cls, d): _interval_shared_docs["class"] % { "klass": "IntervalIndex", - "summary": "Immutable index of intervals that are closed on the same side.", + "summary": "Immutable index of intervals that are inclusive on the same side.", "name": _index_doc_kwargs["name"], "versionadded": "0.20.0", "extra_attributes": "is_overlapping\nvalues\n", @@ -198,7 +198,7 @@ class IntervalIndex(ExtensionIndex): _typ = "intervalindex" # annotate properties pinned via inherit_names - inclusive: IntervalClosedType + inclusive: IntervalInclusiveType is_non_overlapping_monotonic: bool closed_left: bool closed_right: bool @@ -473,7 +473,7 @@ def is_overlapping(self) -> bool: >>> index.is_overlapping True - Intervals that share closed endpoints overlap: + Intervals that share inclusive endpoints overlap: >>> index = pd.interval_range(0, 3, inclusive='both') >>> index @@ -989,7 +989,7 @@ def interval_range( periods=None, freq=None, name: Hashable = None, - inclusive: IntervalClosedType | None = None, + inclusive: IntervalInclusiveType | None = None, ) -> IntervalIndex: """ Return a fixed frequency IntervalIndex. @@ -1009,7 +1009,7 @@ def interval_range( 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. + Include boundaries; Whether to set each bound as inclusive or not. .. versionadded:: 1.5.0 closed : {'left', 'right', 'both', 'neither'}, default 'right' @@ -1026,7 +1026,7 @@ def interval_range( See Also -------- - IntervalIndex : An Index of intervals that are all closed on the same side. + IntervalIndex : An Index of intervals that are all inclusive on the same side. Notes ----- @@ -1079,7 +1079,7 @@ def interval_range( dtype='interval[float64, right]') The ``inclusive`` parameter specifies which endpoints of the individual - intervals within the ``IntervalIndex`` are closed. + intervals within the ``IntervalIndex`` are inclusive. >>> pd.interval_range(end=5, periods=4, inclusive='both') IntervalIndex([[1, 2], [2, 3], [3, 4], [4, 5]], From 6810f0a3366944f01aeb568f074c09fec3e89215 Mon Sep 17 00:00:00 2001 From: patrick Date: Thu, 7 Jul 2022 19:39:15 +0200 Subject: [PATCH 2/3] Rename variables in dtypes too --- pandas/core/dtypes/dtypes.py | 10 +++++----- pandas/tests/dtypes/test_dtypes.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pandas/core/dtypes/dtypes.py b/pandas/core/dtypes/dtypes.py index 20fecbb0095c5..8e5098fa7e8f6 100644 --- a/pandas/core/dtypes/dtypes.py +++ b/pandas/core/dtypes/dtypes.py @@ -1120,7 +1120,7 @@ def __new__( # generally for pickle compat u = object.__new__(cls) u._subtype = None - u._closed = inclusive + u._inclusive = inclusive return u elif isinstance(subtype, str) and subtype.lower() == "interval": subtype = None @@ -1158,7 +1158,7 @@ def __new__( except KeyError: u = object.__new__(cls) u._subtype = subtype - u._closed = inclusive + u._inclusive = inclusive cls._cache_dtypes[key] = u return u @@ -1176,7 +1176,7 @@ def _can_hold_na(self) -> bool: @property def inclusive(self): - return self._closed + return self._inclusive @property def closed(self): @@ -1185,7 +1185,7 @@ def closed(self): FutureWarning, stacklevel=find_stack_level(), ) - return self._closed + return self._inclusive @property def subtype(self): @@ -1266,7 +1266,7 @@ def __setstate__(self, state): # pickle -> need to set the settable private ones here (see GH26067) self._subtype = state["subtype"] # backward-compat older pickles won't have "inclusive" key - self._closed = state.pop("inclusive", None) + self._inclusive = state.pop("inclusive", None) @classmethod def is_dtype(cls, dtype: object) -> bool: diff --git a/pandas/tests/dtypes/test_dtypes.py b/pandas/tests/dtypes/test_dtypes.py index e127fe27b6209..695b06690b358 100644 --- a/pandas/tests/dtypes/test_dtypes.py +++ b/pandas/tests/dtypes/test_dtypes.py @@ -826,7 +826,7 @@ def test_unpickling_without_closed(self): # GH#38394 dtype = IntervalDtype("interval") - assert dtype._closed is None + assert dtype._inclusive is None tm.round_trip_pickle(dtype) From 2fe834664416c4ccb0f6639f35dc5bcf8eedde86 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Sat, 9 Jul 2022 23:00:21 +0200 Subject: [PATCH 3/3] Fix tests --- pandas/core/arrays/arrow/_arrow_utils.py | 2 +- pandas/tests/indexes/interval/test_constructors.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/arrays/arrow/_arrow_utils.py b/pandas/core/arrays/arrow/_arrow_utils.py index 3faffa78420c6..79b79a8ae8ff1 100644 --- a/pandas/core/arrays/arrow/_arrow_utils.py +++ b/pandas/core/arrays/arrow/_arrow_utils.py @@ -112,7 +112,7 @@ def __init__(self, subtype, inclusive: IntervalInclusiveType) -> None: # attributes need to be set first before calling # super init (as that calls serialize) assert inclusive in VALID_INCLUSIVE - self._closed: IntervalInclusiveType = inclusive + self._inclusive: IntervalInclusiveType = inclusive if not isinstance(subtype, pyarrow.DataType): subtype = pyarrow.type_for_alias(str(subtype)) self._subtype = subtype diff --git a/pandas/tests/indexes/interval/test_constructors.py b/pandas/tests/indexes/interval/test_constructors.py index 1966f344356a3..8c8998a8e4be9 100644 --- a/pandas/tests/indexes/interval/test_constructors.py +++ b/pandas/tests/indexes/interval/test_constructors.py @@ -401,7 +401,7 @@ def test_constructor_string(self): def test_constructor_errors(self, constructor): # mismatched closed within intervals with no constructor override ivs = [Interval(0, 1, inclusive="right"), Interval(2, 3, inclusive="left")] - msg = "intervals must all be closed on the same side" + msg = "intervals must all be inclusive on the same side" with pytest.raises(ValueError, match=msg): constructor(ivs)