Skip to content

ENH: Improve typing for Timestamp #389

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

Merged
merged 15 commits into from
Nov 4, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
99 changes: 74 additions & 25 deletions pandas-stubs/_libs/tslibs/timestamps.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@ from datetime import (
from time import struct_time
from typing import (
ClassVar,
Literal,
TypeVar,
overload,
)

import numpy as np
from pandas import Index
from pandas import (
DatetimeIndex,
Index,
TimedeltaIndex,
)
from pandas.core.series import (
Series,
TimedeltaSeries,
TimestampSeries,
)

Expand All @@ -25,21 +31,24 @@ from pandas._libs.tslibs import (
Tick,
Timedelta,
)
from pandas._typing import np_ndarray_bool
from pandas._typing import (
np_ndarray_bool,
npt,
)

_DatetimeT = TypeVar("_DatetimeT", bound=datetime)

def integer_op_not_supported(obj: object) -> TypeError: ...

class Timestamp(datetime):
min: ClassVar[Timestamp]
max: ClassVar[Timestamp]

resolution: ClassVar[Timedelta]
value: int # np.int64
value: int
def __new__(
cls: type[_DatetimeT],
ts_input: np.integer | float | str | _date | datetime | np.datetime64 = ...,
# Freq is deprecated but is left in to allow code like Timestamp(2000,1,1)
# Removing it would make the other arguments position only
freq: int | str | BaseOffset | None = ...,
tz: str | _tzinfo | int | None = ...,
unit: str | int | None = ...,
Expand All @@ -52,8 +61,7 @@ class Timestamp(datetime):
microsecond: int | None = ...,
nanosecond: int | None = ...,
tzinfo: _tzinfo | None = ...,
*,
fold: int | None = ...,
fold: Literal[0, 1] | None = ...,
) -> _DatetimeT: ...
# GH 46171
# While Timestamp can return pd.NaT, having the constructor return
Expand All @@ -73,6 +81,8 @@ class Timestamp(datetime):
@property
def microsecond(self) -> int: ...
@property
def nanosecond(self) -> int: ...
@property
def tzinfo(self) -> _tzinfo | None: ...
@property
def tz(self) -> _tzinfo | None: ...
Expand Down Expand Up @@ -111,17 +121,19 @@ class Timestamp(datetime):
def date(self) -> _date: ...
def time(self) -> _time: ...
def timetz(self) -> _time: ...
def replace(
# Override since fold is more precise than datetime.replace(fold:int)
# Violation of Liskov substitution principle
def replace( # type:ignore[override]
self,
year: int = ...,
month: int = ...,
day: int = ...,
hour: int = ...,
minute: int = ...,
second: int = ...,
microsecond: int = ...,
year: int | None = ...,
month: int | None = ...,
day: int | None = ...,
hour: int | None = ...,
minute: int | None = ...,
second: int | None = ...,
microsecond: int | None = ...,
tzinfo: _tzinfo | None = ...,
fold: int = ...,
fold: Literal[0, 1] | None = ...,
) -> Timestamp: ...
def astimezone(self: _DatetimeT, tz: _tzinfo | None = ...) -> _DatetimeT: ...
def ctime(self) -> str: ...
Expand All @@ -131,44 +143,79 @@ class Timestamp(datetime):
def utcoffset(self) -> timedelta | None: ...
def tzname(self) -> str | None: ...
def dst(self) -> timedelta | None: ...
# 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: datetime) -> bool: ...
def __le__(self, other: datetime | np.datetime64) -> bool: ... # type: ignore[misc]
@overload
def __le__(self, other: Index) -> np_ndarray_bool: ...
def __le__(self, other: Index | npt.NDArray[np.datetime64]) -> np_ndarray_bool: ...
@overload
def __le__(self, other: TimestampSeries) -> Series[bool]: ...
@overload # type: ignore[override]
def __lt__(self, other: datetime) -> bool: ...
def __lt__(self, other: datetime | np.datetime64) -> bool: ... # type: ignore[misc]
@overload
def __lt__(self, other: Index) -> np_ndarray_bool: ...
def __lt__(self, other: Index | npt.NDArray[np.datetime64]) -> np_ndarray_bool: ...
@overload
def __lt__(self, other: TimestampSeries) -> Series[bool]: ...
@overload # type: ignore[override]
def __ge__(self, other: datetime) -> bool: ...
def __ge__(self, other: datetime | np.datetime64) -> bool: ... # type: ignore[misc]
@overload
def __ge__(self, other: Index) -> np_ndarray_bool: ...
def __ge__(self, other: Index | npt.NDArray[np.datetime64]) -> np_ndarray_bool: ...
@overload
def __ge__(self, other: TimestampSeries) -> Series[bool]: ...
@overload # type: ignore[override]
def __gt__(self, other: datetime) -> bool: ...
def __gt__(self, other: datetime | np.datetime64) -> bool: ... # type: ignore[misc]
@overload
def __gt__(self, other: Index) -> np_ndarray_bool: ...
def __gt__(self, other: Index | npt.NDArray[np.datetime64]) -> np_ndarray_bool: ...
@overload
def __gt__(self, other: TimestampSeries) -> Series[bool]: ...
# error: Signature of "__add__" incompatible with supertype "date"/"datetime"
@overload # type: ignore[override]
def __add__(self, other: np.ndarray) -> np.ndarray: ...
def __add__(
self, other: npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.datetime64]: ...
@overload
def __add__(
self: _DatetimeT, other: timedelta | np.timedelta64 | Tick
) -> _DatetimeT: ...
@overload
def __add__(self, other: Series) -> TimestampSeries: ...
@overload
def __add__(self, other: TimedeltaIndex) -> DatetimeIndex: ...
@overload
def __radd__(self: _DatetimeT, other: timedelta) -> _DatetimeT: ...
@overload
def __radd__(self, other: TimedeltaIndex) -> DatetimeIndex: ...
@overload
def __radd__(
self, other: npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.datetime64]: ...
@overload # type: ignore[override]
def __sub__(self, other: datetime) -> Timedelta: ...
@overload
def __sub__(
self: _DatetimeT, other: timedelta | np.timedelta64 | Tick
) -> _DatetimeT: ...
@overload
def __sub__(self, other: TimedeltaIndex) -> DatetimeIndex: ...
@overload
def __sub__(self, other: TimedeltaSeries) -> TimestampSeries: ...
@overload
def __sub__(
self, other: npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.datetime64]: ...
@overload # type: ignore[override]
def __eq__(self, other: Timestamp | np.datetime64 | datetime) -> bool: ...
@overload
def __eq__(self, other: TimestampSeries) -> Series[bool]: ...
@overload
def __eq__(self, other: npt.NDArray[np.datetime64] | Index) -> np_ndarray_bool: ...
@overload # type: ignore[override]
def __ne__(self, other: Timestamp | np.datetime64 | datetime) -> bool: ...
@overload
def __ne__(self, other: TimestampSeries) -> Series[bool]: ...
@overload
def __ne__(self, other: npt.NDArray[np.datetime64] | Index) -> np_ndarray_bool: ...
def __hash__(self) -> int: ...
def weekday(self) -> int: ...
def isoweekday(self) -> int: ...
Expand Down Expand Up @@ -223,6 +270,8 @@ class Timestamp(datetime):
@property
def dayofyear(self) -> int: ...
@property
def weekofyear(self) -> int: ...
@property
def quarter(self) -> int: ...
@property
def week(self) -> int: ...
Expand Down
10 changes: 10 additions & 0 deletions pandas-stubs/core/series.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,16 @@ class Series(IndexOpsMixin, NDFrame, Generic[S1]):
fastpath: bool = ...,
) -> TimestampSeries: ...
@overload
def __new__(
cls,
data: TimedeltaIndex,
index: Axes | None = ...,
dtype=...,
name: Hashable | None = ...,
copy: bool = ...,
fastpath: bool = ...,
) -> TimedeltaSeries: ...
@overload
def __new__(
cls,
data: PeriodIndex,
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ tabulate = ">=0.8.10"
jinja2 = "^3.1"
scipy = ">=1.9.1"
SQLAlchemy = "^1.4.41"
types-python-dateutil = ">=2.8.19"

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand Down
Loading