Skip to content

Commit

Permalink
Typeinterval part2 (pandas-dev#46098)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dr-Irv authored Feb 27, 2022
1 parent 661d88e commit 66a5de3
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 9 deletions.
174 changes: 174 additions & 0 deletions pandas/_libs/interval.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
from __future__ import annotations

from typing import (
Any,
Generic,
TypeVar,
Union,
overload,
)

import numpy as np
import numpy.typing as npt

from pandas._typing import (
IntervalClosedType,
Timedelta,
Timestamp,
)

VALID_CLOSED: frozenset[str]

_OrderableScalarT = TypeVar("_OrderableScalarT", int, float)
_OrderableTimesT = TypeVar("_OrderableTimesT", Timestamp, Timedelta)
_OrderableT = TypeVar("_OrderableT", int, float, Timestamp, Timedelta)

class _LengthDescriptor:
@overload
def __get__(
self, instance: Interval[_OrderableScalarT], owner: Any
) -> _OrderableScalarT: ...
@overload
def __get__(
self, instance: Interval[_OrderableTimesT], owner: Any
) -> Timedelta: ...
@overload
def __get__(self, instance: IntervalTree, owner: Any) -> np.ndarray: ...

class _MidDescriptor:
@overload
def __get__(self, instance: Interval[_OrderableScalarT], owner: Any) -> float: ...
@overload
def __get__(
self, instance: Interval[_OrderableTimesT], owner: Any
) -> _OrderableTimesT: ...
@overload
def __get__(self, instance: IntervalTree, owner: Any) -> np.ndarray: ...

class IntervalMixin:
@property
def closed_left(self) -> bool: ...
@property
def closed_right(self) -> bool: ...
@property
def open_left(self) -> bool: ...
@property
def open_right(self) -> bool: ...
mid: _MidDescriptor
length: _LengthDescriptor
@property
def is_empty(self) -> bool: ...
def _check_closed_matches(self, other: IntervalMixin, name: str = ...) -> None: ...

class Interval(IntervalMixin, Generic[_OrderableT]):
@property
def left(self: Interval[_OrderableT]) -> _OrderableT: ...
@property
def right(self: Interval[_OrderableT]) -> _OrderableT: ...
@property
def closed(self) -> IntervalClosedType: ...
def __init__(
self,
left: _OrderableT,
right: _OrderableT,
closed: IntervalClosedType = ...,
): ...
def __hash__(self) -> int: ...
@overload
def __contains__(self: Interval[_OrderableTimesT], _OrderableTimesT) -> bool: ...
@overload
def __contains__(
self: Interval[_OrderableScalarT], key: Union[int, float]
) -> bool: ...
def __repr__(self) -> str: ...
def __str__(self) -> str: ...
@overload
def __add__(
self: Interval[_OrderableTimesT], y: Timedelta
) -> Interval[_OrderableTimesT]: ...
@overload
def __add__(self: Interval[int], y: int) -> Interval[int]: ...
@overload
def __add__(self: Interval[int], y: float) -> Interval[float]: ...
@overload
def __add__(self: Interval[float], y: Union[int, float]) -> Interval[float]: ...
@overload
def __radd__(
self: Interval[_OrderableTimesT], y: Timedelta
) -> Interval[_OrderableTimesT]: ...
@overload
def __radd__(self: Interval[int], y: int) -> Interval[int]: ...
@overload
def __radd__(self: Interval[int], y: float) -> Interval[float]: ...
@overload
def __radd__(self: Interval[float], y: Union[int, float]) -> Interval[float]: ...
@overload
def __sub__(
self: Interval[_OrderableTimesT], y: Timedelta
) -> Interval[_OrderableTimesT]: ...
@overload
def __sub__(self: Interval[int], y: int) -> Interval[int]: ...
@overload
def __sub__(self: Interval[int], y: float) -> Interval[float]: ...
@overload
def __sub__(self: Interval[float], y: Union[int, float]) -> Interval[float]: ...
@overload
def __rsub__(
self: Interval[_OrderableTimesT], y: Timedelta
) -> Interval[_OrderableTimesT]: ...
@overload
def __rsub__(self: Interval[int], y: int) -> Interval[int]: ...
@overload
def __rsub__(self: Interval[int], y: float) -> Interval[float]: ...
@overload
def __rsub__(self: Interval[float], y: Union[int, float]) -> Interval[float]: ...
@overload
def __mul__(self: Interval[int], y: int) -> Interval[int]: ...
@overload
def __mul__(self: Interval[int], y: float) -> Interval[float]: ...
@overload
def __mul__(self: Interval[float], y: Union[int, float]) -> Interval[float]: ...
@overload
def __rmul__(self: Interval[int], y: int) -> Interval[int]: ...
@overload
def __rmul__(self: Interval[int], y: float) -> Interval[float]: ...
@overload
def __rmul__(self: Interval[float], y: Union[int, float]) -> Interval[float]: ...
@overload
def __truediv__(self: Interval[int], y: int) -> Interval[int]: ...
@overload
def __truediv__(self: Interval[int], y: float) -> Interval[float]: ...
@overload
def __truediv__(self: Interval[float], y: Union[int, float]) -> Interval[float]: ...
@overload
def __floordiv__(self: Interval[int], y: int) -> Interval[int]: ...
@overload
def __floordiv__(self: Interval[int], y: float) -> Interval[float]: ...
@overload
def __floordiv__(
self: Interval[float], y: Union[int, float]
) -> Interval[float]: ...
def overlaps(self: Interval[_OrderableT], other: Interval[_OrderableT]) -> bool: ...

def intervals_to_interval_bounds(
intervals: np.ndarray, validate_closed: bool = ...
) -> tuple[np.ndarray, np.ndarray, str]: ...

class IntervalTree(IntervalMixin):
def __init__(
self,
left: np.ndarray,
right: np.ndarray,
closed: IntervalClosedType = ...,
leaf_size: int = ...,
): ...
def get_indexer(self, target) -> npt.NDArray[np.intp]: ...
def get_indexer_non_unique(
self, target
) -> tuple[npt.NDArray[np.intp], npt.NDArray[np.intp]]: ...
_na_count: int
@property
def is_overlapping(self) -> bool: ...
@property
def is_monotonic_increasing(self) -> bool: ...
def clear_mapping(self) -> None: ...
10 changes: 7 additions & 3 deletions pandas/core/indexes/interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,9 +321,10 @@ def from_tuples(
return cls._simple_new(arr, name=name)

# --------------------------------------------------------------------

# error: Return type "IntervalTree" of "_engine" incompatible with return type
# "Union[IndexEngine, ExtensionEngine]" in supertype "Index"
@cache_readonly
def _engine(self) -> IntervalTree:
def _engine(self) -> IntervalTree: # type: ignore[override]
left = self._maybe_convert_i8(self.left)
right = self._maybe_convert_i8(self.right)
return IntervalTree(left, right, closed=self.closed)
Expand Down Expand Up @@ -515,7 +516,10 @@ def _maybe_convert_i8(self, key):
left = self._maybe_convert_i8(key.left)
right = self._maybe_convert_i8(key.right)
constructor = Interval if scalar else IntervalIndex.from_arrays
return constructor(left, right, closed=self.closed)
# error: "object" not callable
return constructor(
left, right, closed=self.closed
) # type: ignore[operator]

if scalar:
# Timestamp/Timedelta
Expand Down
8 changes: 2 additions & 6 deletions pandas/io/formats/style.py
Original file line number Diff line number Diff line change
Expand Up @@ -3810,14 +3810,10 @@ def _highlight_between(
Return an array of css props based on condition of data values within given range.
"""
if np.iterable(left) and not isinstance(left, str):
left = _validate_apply_axis_arg(
left, "left", None, data # type: ignore[arg-type]
)
left = _validate_apply_axis_arg(left, "left", None, data)

if np.iterable(right) and not isinstance(right, str):
right = _validate_apply_axis_arg(
right, "right", None, data # type: ignore[arg-type]
)
right = _validate_apply_axis_arg(right, "right", None, data)

# get ops with correct boundary attribution
if inclusive == "both":
Expand Down

0 comments on commit 66a5de3

Please sign in to comment.