Skip to content

Commit dc9a094

Browse files
authored
ENH: Improve typing for Interval (#391)
* ENH: Improve typing for Interval * ENH: Further refinements of interval * Attempt to make IntervalIndex generic * ENH: Add more generic support * ENH: Improve interval * ENH: Improve from tuples * CLN: Final clean ups * CLN: Final clean ups * CLN: Final fixes * CLN: Final fixes
1 parent 4e9f8c7 commit dc9a094

File tree

8 files changed

+979
-134
lines changed

8 files changed

+979
-134
lines changed

pandas-stubs/_libs/interval.pyi

+57-7
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
from typing import (
22
Any,
33
Generic,
4+
Literal,
45
TypeVar,
56
overload,
67
)
78

89
import numpy as np
910
from pandas import (
11+
IntervalIndex,
12+
Series,
1013
Timedelta,
1114
Timestamp,
1215
)
1316

1417
from pandas._typing import (
1518
IntervalClosedType,
19+
IntervalT,
20+
np_ndarray_bool,
1621
npt,
1722
)
1823

@@ -123,28 +128,73 @@ class Interval(IntervalMixin, Generic[_OrderableT]):
123128
@overload
124129
def __mul__(self: Interval[float], y: float) -> Interval[float]: ...
125130
@overload
131+
def __mul__(self: Interval[Timedelta], y: float) -> Interval[Timedelta]: ...
132+
@overload
126133
def __rmul__(
127134
self: Interval[int], y: _OrderableScalarT
128135
) -> Interval[_OrderableScalarT]: ...
129136
@overload
130137
def __rmul__(self: Interval[float], y: float) -> Interval[float]: ...
131138
@overload
132-
def __truediv__(
133-
self: Interval[int], y: _OrderableScalarT
134-
) -> Interval[_OrderableScalarT]: ...
139+
def __rmul__(self: Interval[Timedelta], y: float) -> Interval[Timedelta]: ...
140+
@overload
141+
def __truediv__(self: Interval[int], y: _OrderableScalarT) -> Interval[float]: ...
135142
@overload
136143
def __truediv__(self: Interval[float], y: float) -> Interval[float]: ...
137144
@overload
145+
def __truediv__(self: Interval[Timedelta], y: float) -> Interval[Timedelta]: ...
146+
@overload
138147
def __floordiv__(
139148
self: Interval[int], y: _OrderableScalarT
140149
) -> Interval[_OrderableScalarT]: ...
141150
@overload
142151
def __floordiv__(self: Interval[float], y: float) -> Interval[float]: ...
152+
@overload
153+
def __floordiv__(self: Interval[Timedelta], y: float) -> Interval[Timedelta]: ...
154+
@overload
143155
def overlaps(self: Interval[_OrderableT], other: Interval[_OrderableT]) -> bool: ...
144-
145-
def intervals_to_interval_bounds(
146-
intervals: np.ndarray, validate_closed: bool = ...
147-
) -> tuple[np.ndarray, np.ndarray, str]: ...
156+
@overload
157+
def overlaps(self: Interval[int], other: Interval[float]) -> bool: ...
158+
@overload
159+
def overlaps(self: Interval[float], other: Interval[int]) -> bool: ...
160+
@overload
161+
def __gt__(self, other: Interval[_OrderableT]) -> bool: ...
162+
@overload
163+
def __gt__(self: IntervalT, other: IntervalIndex[IntervalT]) -> np_ndarray_bool: ...
164+
@overload
165+
def __gt__(self, other: Series[_OrderableT]) -> Series[bool]: ...
166+
@overload
167+
def __lt__(self, other: Interval[_OrderableT]) -> bool: ...
168+
@overload
169+
def __lt__(self: IntervalT, other: IntervalIndex[IntervalT]) -> np_ndarray_bool: ...
170+
@overload
171+
def __lt__(self, other: Series[_OrderableT]) -> Series[bool]: ...
172+
@overload
173+
def __ge__(self, other: Interval[_OrderableT]) -> bool: ...
174+
@overload
175+
def __ge__(self: IntervalT, other: IntervalIndex[IntervalT]) -> np_ndarray_bool: ...
176+
@overload
177+
def __ge__(self, other: Series[_OrderableT]) -> Series[bool]: ...
178+
@overload
179+
def __le__(self, other: Interval[_OrderableT]) -> bool: ...
180+
@overload
181+
def __le__(self: IntervalT, other: IntervalIndex[IntervalT]) -> np_ndarray_bool: ...
182+
@overload
183+
def __eq__(self, other: Interval[_OrderableT]) -> bool: ... # type: ignore[misc]
184+
@overload
185+
def __eq__(self: IntervalT, other: IntervalIndex[IntervalT]) -> np_ndarray_bool: ... # type: ignore[misc]
186+
@overload
187+
def __eq__(self, other: Series[_OrderableT]) -> Series[bool]: ... # type: ignore[misc]
188+
@overload
189+
def __eq__(self, other: object) -> Literal[False]: ...
190+
@overload
191+
def __ne__(self, other: Interval[_OrderableT]) -> bool: ... # type: ignore[misc]
192+
@overload
193+
def __ne__(self: IntervalT, other: IntervalIndex[IntervalT]) -> np_ndarray_bool: ... # type: ignore[misc]
194+
@overload
195+
def __ne__(self, other: Series[_OrderableT]) -> Series[bool]: ... # type: ignore[misc]
196+
@overload
197+
def __ne__(self, other: object) -> Literal[True]: ...
148198

149199
class IntervalTree(IntervalMixin):
150200
def __init__(

pandas-stubs/_typing.pyi

+12-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ from pandas.core.indexes.base import Index
2626
from pandas.core.series import Series
2727
from typing_extensions import TypeAlias
2828

29+
from pandas._libs.interval import Interval
2930
from pandas._libs.tslibs import (
3031
Period,
3132
Timedelta,
@@ -196,6 +197,10 @@ S1 = TypeVar(
196197
Timedelta,
197198
np.datetime64,
198199
Period,
200+
Interval[int],
201+
Interval[float],
202+
Interval[Timestamp],
203+
Interval[Timedelta],
199204
)
200205
T1 = TypeVar(
201206
"T1", str, int, np.int64, np.uint64, np.float64, float, np.dtype[np.generic]
@@ -220,7 +225,13 @@ NDFrameT = TypeVar("NDFrameT", bound=NDFrame)
220225
IndexT = TypeVar("IndexT", bound=Index)
221226

222227
# Interval closed type
223-
228+
IntervalT = TypeVar(
229+
"IntervalT",
230+
Interval[int],
231+
Interval[float],
232+
Interval[Timestamp],
233+
Interval[Timedelta],
234+
)
224235
IntervalClosedType: TypeAlias = Literal["left", "right", "both", "neither"]
225236

226237
IgnoreRaiseCoerce: TypeAlias = Literal["ignore", "raise", "coerce"]

pandas-stubs/core/algorithms.pyi

+6-2
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,20 @@ from pandas import (
1414
)
1515
from pandas.api.extensions import ExtensionArray
1616

17-
from pandas._typing import AnyArrayLike
17+
from pandas._typing import (
18+
AnyArrayLike,
19+
IntervalT,
20+
)
1821

1922
# These are type: ignored because the Index types overlap due to inheritance but indices
2023
# with extension types return the same type while standard type return ndarray
24+
2125
@overload
2226
def unique(values: PeriodIndex) -> PeriodIndex: ... # type: ignore[misc]
2327
@overload
2428
def unique(values: CategoricalIndex) -> CategoricalIndex: ... # type: ignore[misc]
2529
@overload
26-
def unique(values: IntervalIndex) -> IntervalIndex: ... # type: ignore[misc]
30+
def unique(values: IntervalIndex[IntervalT]) -> IntervalIndex[IntervalT]: ... # type: ignore[misc]
2731
@overload
2832
def unique(values: Index) -> np.ndarray: ...
2933
@overload

0 commit comments

Comments
 (0)