Skip to content

ENH: Improve Pandas scalars #383

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
5c0dc1c
ENH: Improve DatetimeTZDtype
bashtage Oct 11, 2022
9f5058f
ENH: Improve PeriodDtype
bashtage Oct 11, 2022
7ad615a
ENH: Improve IntervalDtype
bashtage Oct 11, 2022
fb6d782
ENH: Improve CategoricalDtype
bashtage Oct 11, 2022
fecd9f9
ENH: Improve StringDtype and StringArray
bashtage Oct 11, 2022
5adba7b
ENH: Improve BooleanDtype and BooleanArray
bashtage Oct 11, 2022
c4dca27
ENH: Improve Timestamp
bashtage Oct 11, 2022
d86adfd
ENH: Improve Timedelta
bashtage Oct 11, 2022
79f56c2
ENH: Further improvements to Timestamp
bashtage Oct 11, 2022
cc390f5
CLN: Additional cleanups to pass tests
bashtage Oct 11, 2022
c044a8c
ENH: Improve Period
bashtage Oct 11, 2022
f58c47c
TST Add tests for dtypes
Oct 11, 2022
fbfa4c1
Merge remote-tracking branch 'upstream/main' into pandas-scalars
Oct 11, 2022
ccbde88
TST: Correct types in tests
Oct 12, 2022
25aa8c9
Merge branch 'pandas-scalars' of github.com:bashtage/pandas-stubs int…
bashtage Oct 12, 2022
290f951
BUG: Correct errors in period and interval
bashtage Oct 12, 2022
e62cc10
TST: Add tests for Period
bashtage Oct 12, 2022
9c6b963
TST: Add tests for timedelta
bashtage Oct 12, 2022
e93ca54
TST: Add tests for arrays
bashtage Oct 13, 2022
9070b0d
TST: Add more scalar tests
Oct 13, 2022
28e127e
ENH: Complete Timedelta
bashtage Oct 13, 2022
f59c689
Merge remote-tracking branch 'upstream/main' into pandas-scalars
bashtage Oct 13, 2022
2f262d4
ENH: Improve Timestamp and enable tests
bashtage Oct 13, 2022
7dd8c56
TST: Add reverse ops
bashtage Oct 14, 2022
9c2d500
ENH/TST: Improve Period and its tests
bashtage Oct 14, 2022
0c2f5ca
ENH/TST: Improve Timestamp, Timedelta and their tests
bashtage Oct 14, 2022
e224537
REF: Move tests to test_scalar
bashtage Oct 14, 2022
08156cc
CLN: Final fixes to passing
bashtage Oct 14, 2022
1672751
BUG: Correct Interval
bashtage Oct 14, 2022
4c3ea13
ENH: Improve array typing
bashtage Oct 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions pandas-stubs/_libs/interval.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -123,24 +123,37 @@ class Interval(IntervalMixin, Generic[_OrderableT]):
@overload
def __mul__(self: Interval[float], y: float) -> Interval[float]: ...
@overload
def __mul__(self: Interval[Timedelta], y: float) -> Interval[Timedelta]: ...
@overload
def __rmul__(
self: Interval[int], y: _OrderableScalarT
) -> Interval[_OrderableScalarT]: ...
@overload
def __rmul__(self: Interval[float], y: float) -> Interval[float]: ...
@overload
def __rmul__(self: Interval[Timedelta], y: float) -> Interval[Timedelta]: ...
@overload
def __truediv__(
self: Interval[int], y: _OrderableScalarT
) -> Interval[_OrderableScalarT]: ...
@overload
def __truediv__(self: Interval[float], y: float) -> Interval[float]: ...
@overload
def __truediv__(self: Interval[Timedelta], y: float) -> Interval[Timedelta]: ...
@overload
def __floordiv__(
self: Interval[int], y: _OrderableScalarT
) -> Interval[_OrderableScalarT]: ...
@overload
def __floordiv__(self: Interval[float], y: float) -> Interval[float]: ...
@overload
def __floordiv__(self: Interval[Timedelta], y: float) -> Interval[Timedelta]: ...
@overload
def overlaps(self: Interval[_OrderableT], other: Interval[_OrderableT]) -> bool: ...
@overload
def overlaps(self: Interval[int], other: Interval[float]) -> bool: ...
@overload
def overlaps(self: Interval[float], other: Interval[int]) -> bool: ...

class IntervalTree(IntervalMixin):
def __init__(
Expand Down
34 changes: 23 additions & 11 deletions pandas-stubs/_libs/tslibs/period.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ from typing import (

import numpy as np
from pandas import (
DatetimeIndex,
Index,
PeriodIndex,
Timedelta,
)
from pandas.core.series import (
PeriodSeries,
TimedeltaSeries,
)
from typing_extensions import TypeAlias

from pandas._typing import npt
Expand All @@ -23,11 +26,7 @@ class IncompatibleFrequency(ValueError): ...
from pandas._libs.tslibs.offsets import BaseOffset

_PeriodAddSub: TypeAlias = Union[
Timedelta, datetime.timedelta, np.timedelta64, np.int64, int
]

_PeriodEqualityComparison: TypeAlias = Union[
Period, datetime.datetime, datetime.date, Timestamp, np.datetime64, int, np.int64
Timedelta, datetime.timedelta, np.timedelta64, np.int64, int, BaseOffset
]

_PeriodFreqHow: TypeAlias = Literal[
Expand Down Expand Up @@ -72,13 +71,17 @@ class Period(PeriodMixin):
@overload
def __sub__(self, other: PeriodIndex) -> Index: ...
@overload
def __sub__(self, other: TimedeltaSeries) -> PeriodSeries: ...
@overload
def __add__(self, other: _PeriodAddSub) -> Period: ...
@overload
def __add__(self, other: Index) -> Period: ...
def __add__(self, other: Index) -> PeriodIndex: ...
@overload
def __add__(self, other: TimedeltaSeries) -> PeriodSeries: ...
@overload # type: ignore[override]
def __eq__(self, other: _PeriodEqualityComparison) -> bool: ...
def __eq__(self, other: Period) -> bool: ...
@overload
def __eq__(self, other: PeriodIndex | DatetimeIndex) -> npt.NDArray[np.bool_]: ...
def __eq__(self, other: PeriodIndex) -> npt.NDArray[np.bool_]: ...
@overload
def __ge__(self, other: Period) -> bool: ...
@overload
Expand All @@ -97,12 +100,21 @@ class Period(PeriodMixin):
@overload
def __lt__(self, other: PeriodIndex) -> npt.NDArray[np.bool_]: ...
@overload # type: ignore[override]
def __ne__(self, other: _PeriodEqualityComparison) -> bool: ...
def __ne__(self, other: Period) -> bool: ...
@overload
def __ne__(self, other: PeriodIndex | DatetimeIndex) -> npt.NDArray[np.bool_]: ...
def __ne__(self, other: PeriodIndex) -> npt.NDArray[np.bool_]: ...
# Ignored due to indecipherable error from mypy:
# Forward operator "__add__" is not callable [misc]
@overload
def __radd__(self, other: _PeriodAddSub) -> Period: ... # type: ignore[misc]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the error might be due to having conflicts between one of the __add__() declarations allowing Period. So try __radd__() with each one of the types in _PeriodAddSub to narrow down the possible cause.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is because Period + Index -> PeriodIndex here but Index + Period -> Index there.

# Real signature is -> PeriodIndex, but conflicts with Index.__add__
# Changing Index is very hard due to Index inheritance
# Signatures of "__radd__" of "Period" and "__add__" of "Index"
# are unsafely overlapping
@overload
def __radd__(self, other: Index) -> Index: ...
@overload
def __radd__(self, other: TimedeltaSeries) -> PeriodSeries: ...
@property
def day(self) -> int: ...
@property
Expand Down
160 changes: 148 additions & 12 deletions pandas-stubs/_libs/tslibs/timedeltas.pyi
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import datetime as dt
from datetime import timedelta
from typing import (
ClassVar,
Expand All @@ -9,13 +10,23 @@ from typing import (
)

import numpy as np
from pandas import (
DatetimeIndex,
Float64Index,
Int64Index,
PeriodIndex,
Series,
TimedeltaIndex,
)
from pandas.core.series import TimedeltaSeries
from typing_extensions import TypeAlias

from pandas._libs.tslibs import (
BaseOffset,
NaTType,
Tick,
)
from pandas._libs.tslibs.period import Period
from pandas._libs.tslibs.timestamps import Timestamp
from pandas._typing import npt

class Components(NamedTuple):
Expand Down Expand Up @@ -121,44 +132,169 @@ class Timedelta(timedelta):
def ceil(self: _S, freq: str | BaseOffset) -> _S: ...
@property
def resolution_string(self) -> str: ...
def __add__(self, other: timedelta) -> Timedelta: ...
@overload # type: ignore[override]
def __add__(self, other: timedelta | np.timedelta64) -> Timedelta: ...
@overload
def __add__(self, other: dt.datetime | np.datetime64 | Timestamp) -> Timestamp: ...
@overload
def __add__(self, other: Period) -> Period: ...
@overload
def __add__(self, other: dt.date) -> dt.date: ...
@overload
def __add__(self, other: PeriodIndex) -> PeriodIndex: ...
@overload
def __add__(self, other: DatetimeIndex) -> DatetimeIndex: ...
@overload
def __add__(
self, other: npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.timedelta64]: ...
@overload
def __add__(
self, other: npt.NDArray[np.datetime64]
) -> npt.NDArray[np.datetime64]: ...
@overload
def __radd__(self, other: timedelta) -> Timedelta: ...
def __sub__(self, other: timedelta) -> Timedelta: ...
def __rsub__(self, other: timedelta) -> Timedelta: ...
@overload
def __radd__(
self, other: npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.timedelta64]: ...
@overload
def __radd__(
self, other: npt.NDArray[np.datetime64]
) -> npt.NDArray[np.datetime64]: ...
@overload # type: ignore[override]
def __sub__(self, other: timedelta | np.timedelta64) -> Timedelta: ...
@overload
def __sub__(
self, other: npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.timedelta64]: ...
@overload
def __rsub__(self, other: timedelta | np.timedelta64) -> Timedelta: ...
@overload
def __rsub__(self, other: Timestamp | np.datetime64) -> Timestamp: ...
@overload
def __rsub__(self, other: PeriodIndex) -> PeriodIndex: ...
@overload
def __rsub__(self, other: DatetimeIndex) -> DatetimeIndex: ...
@overload
def __rsub__(
self, other: npt.NDArray[np.datetime64]
) -> npt.NDArray[np.datetime64]: ...
@overload
def __rsub__(
self, other: npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.timedelta64]: ...
def __neg__(self) -> Timedelta: ...
def __pos__(self) -> Timedelta: ...
def __abs__(self) -> Timedelta: ...
@overload # type: ignore[override]
def __mul__(self, other: float) -> Timedelta: ...
@overload
def __mul__(self, other: np.ndarray) -> np.ndarray: ...
@overload
def __mul__(self, other: Series) -> Series: ...
@overload
def __mul__(self, other: Int64Index | Float64Index) -> TimedeltaIndex: ...
@overload
def __rmul__(self, other: float) -> Timedelta: ...
@overload
def __rmul__(self, other: np.ndarray) -> np.ndarray: ...
@overload
def __rmul__(self, other: Series) -> Series: ...
@overload
def __rmul__(self, other: Int64Index | Float64Index) -> TimedeltaIndex: ...
# error: Signature of "__floordiv__" incompatible with supertype "timedelta"
@overload # type: ignore[override]
def __floordiv__(self, other: timedelta) -> int: ...
@overload
def __floordiv__(self, other: float) -> Timedelta: ...
@overload
def __floordiv__(
self, other: npt.NDArray[np.integer] | npt.NDArray[np.floating]
) -> npt.NDArray[np.timedelta64]: ...
@overload
def __floordiv__(
self, other: npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.intp]: ...
@overload
def __floordiv__(
self, other: npt.NDArray[np.number]
) -> npt.NDArray[np.timedelta64] | Timedelta: ...
def __floordiv__(self, other: Int64Index | Float64Index) -> TimedeltaIndex: ...
@overload
def __floordiv__(self, other: Series) -> Series: ...
@overload
def __rfloordiv__(self, other: timedelta | str) -> int: ...
@overload
def __rfloordiv__(self, other: NaTType | None) -> NaTType: ...
@overload
def __rfloordiv__(self, other: np.ndarray) -> npt.NDArray[np.timedelta64]: ...
@overload
@overload # type: ignore[override]
def __truediv__(self, other: timedelta) -> float: ...
@overload
def __truediv__(self, other: float) -> Timedelta: ...
@overload
def __truediv__(
self, other: npt.NDArray[np.integer] | npt.NDArray[np.floating]
) -> npt.NDArray[np.timedelta64]: ...
@overload
def __truediv__(self, other: TimedeltaSeries) -> Series[float]: ...
@overload
def __truediv__(self, other: Series) -> Series: ...
@overload
def __truediv__(self, other: Int64Index | Float64Index) -> TimedeltaIndex: ...
@overload # type: ignore[override]
def __eq__(self, other: timedelta | np.timedelta64) -> bool: ...
@overload
def __eq__(self, other: Series) -> Series: ...
@overload
def __eq__(
self, other: TimedeltaIndex | npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.bool_]: ...
@overload # type: ignore[override]
def __ne__(self, other: timedelta | np.timedelta64) -> bool: ...
@overload
def __ne__(self, other: Series) -> Series: ...
@overload
def __ne__(
self, other: TimedeltaIndex | npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.bool_]: ...
@overload # type: ignore[override]
def __mod__(self, other: timedelta) -> Timedelta: ...
@overload
def __mod__(self, other: float) -> Timedelta: ...
@overload
def __mod__(
self, other: npt.NDArray[np.integer] | npt.NDArray[np.floating]
) -> npt.NDArray[np.timedelta64]: ...
@overload
def __mod__(self, other: Series) -> Series: ...
@overload
def __mod__(self, other: Int64Index | Float64Index) -> TimedeltaIndex: ...
def __divmod__(self, other: timedelta) -> tuple[int, Timedelta]: ...
def __le__(self, other: timedelta) -> bool: ...
def __lt__(self, other: timedelta) -> bool: ...
def __ge__(self, other: timedelta) -> bool: ...
def __gt__(self, other: timedelta) -> bool: ...
# Mypy complains Forward operator "<inequality op>" is not callable, so ignore misc
# for le, lt ge and gt
@overload # type: ignore[override]
def __le__(self, other: timedelta | np.timedelta64) -> bool: ... # type: ignore[misc]
@overload
def __le__(
self, other: TimedeltaIndex | npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.bool_]: ...
@overload # type: ignore[override]
def __lt__(self, other: timedelta | np.timedelta64) -> bool: ... # type: ignore[misc]
@overload
def __lt__(
self, other: TimedeltaIndex | npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.bool_]: ...
@overload # type: ignore[override]
def __ge__(self, other: timedelta | np.timedelta64) -> bool: ... # type: ignore[misc]
@overload
def __ge__(
self, other: TimedeltaIndex | npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.bool_]: ...
@overload # type: ignore[override]
def __gt__(self, other: timedelta | np.timedelta64) -> bool: ... # type: ignore[misc]
@overload
def __gt__(
self, other: TimedeltaIndex | npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.bool_]: ...
def __hash__(self) -> int: ...
def isoformat(self) -> str: ...
def to_numpy(self) -> np.timedelta64: ...
Expand Down
Loading