From 9ce85dd532b6e18ba2f2f761af603a613211d245 Mon Sep 17 00:00:00 2001 From: Brock Date: Fri, 2 Apr 2021 21:25:30 -0700 Subject: [PATCH 1/2] TYP: timedeltas.pyi --- pandas/_libs/tslibs/timedeltas.pyi | 106 +++++++++++++++++++++++++++++ pandas/core/reshape/tile.py | 7 ++ pandas/core/tools/timedeltas.py | 7 +- 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 pandas/_libs/tslibs/timedeltas.pyi diff --git a/pandas/_libs/tslibs/timedeltas.pyi b/pandas/_libs/tslibs/timedeltas.pyi new file mode 100644 index 0000000000000..8c2bb9d88ed2d --- /dev/null +++ b/pandas/_libs/tslibs/timedeltas.pyi @@ -0,0 +1,106 @@ +from datetime import timedelta +from time import struct_time +from typing import ( + AnyStr, + ClassVar, + Optional, + SupportsAbs, + Tuple, + Type, + TypeVar, + Union, + overload, +) + +import numpy as np + +from pandas._libs.tslibs import ( + NaT, + NaTType, + Tick, +) + +_S = TypeVar("_S") + + +def ints_to_pytimedelta( + arr: np.ndarray, # const int64_t[:] + box: bool = ..., +) -> np.ndarray: ... # np.ndarray[object] + + +def array_to_timedelta64( + values: np.ndarray, # ndarray[object] + unit: str | None = ..., + errors: str = ..., +) -> np.ndarray: ... # np.ndarray[m8ns] + + +def parse_timedelta_unit(unit: str | None) -> str: ... + + +def delta_to_nanoseconds(delta: Tick | np.timedelta64 | timedelta | int) -> int: ... + + +class Timedelta(timedelta): + min: ClassVar[Timedelta] + max: ClassVar[Timedelta] + resolution: ClassVar[Timedelta] + value: int # np.int64 + + def __new__( + cls: Type[_S], + value=..., + unit=..., + **kwargs + ) -> _S | NaTType: ... + + @property + def days(self) -> int: ... + @property + def seconds(self) -> int: ... + @property + def microseconds(self) -> int: ... + def total_seconds(self) -> float: ... + + def to_pytimedelta(self) -> timedelta: ... + def to_timedelta64(self) -> np.timedelta64: ... + + @property + def asm8(self) -> np.timedelta64: ... + + # TODO: round/floor/ceil could return NaT? + def round(self: _S, freq) -> _S: ... + def floor(self: _S, freq) -> _S: ... + def ceil(self: _S, freq) -> _S: ... + + @property + def resolution_string(self) -> str: ... + + def __add__(self, other: timedelta) -> timedelta: ... + def __radd__(self, other: timedelta) -> timedelta: ... + def __sub__(self, other: timedelta) -> timedelta: ... + def __rsub__(self, other: timedelta) -> timedelta: ... + def __neg__(self) -> timedelta: ... + def __pos__(self) -> timedelta: ... + def __abs__(self) -> timedelta: ... + def __mul__(self, other: float) -> timedelta: ... + def __rmul__(self, other: float) -> timedelta: ... + + @overload + def __floordiv__(self, other: timedelta) -> int: ... + @overload + def __floordiv__(self, other: int) -> timedelta: ... + + @overload + def __truediv__(self, other: timedelta) -> float: ... + @overload + def __truediv__(self, other: float) -> timedelta: ... + def __mod__(self, other: timedelta) -> timedelta: ... + 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: ... + def __hash__(self) -> int: ... diff --git a/pandas/core/reshape/tile.py b/pandas/core/reshape/tile.py index 89eba5bf41c78..2bea17bfa689c 100644 --- a/pandas/core/reshape/tile.py +++ b/pandas/core/reshape/tile.py @@ -1,6 +1,11 @@ """ Quantilization functions and related stuff """ +from typing import ( + Any, + Callable, +) + import numpy as np from pandas._libs import ( @@ -550,6 +555,8 @@ def _format_labels( """ based on the dtype, return our labels """ closed = "right" if right else "left" + formatter: Callable[[Any], Timestamp] | Callable[[Any], Timedelta] + if is_datetime64tz_dtype(dtype): formatter = lambda x: Timestamp(x, tz=dtype.tz) adjust = lambda x: x - Timedelta("1ns") diff --git a/pandas/core/tools/timedeltas.py b/pandas/core/tools/timedeltas.py index 047cec6501627..cbdd02aad1dd0 100644 --- a/pandas/core/tools/timedeltas.py +++ b/pandas/core/tools/timedeltas.py @@ -5,7 +5,10 @@ import numpy as np from pandas._libs import lib -from pandas._libs.tslibs import NaT +from pandas._libs.tslibs import ( + NaT, + NaTType, +) from pandas._libs.tslibs.timedeltas import ( Timedelta, parse_timedelta_unit, @@ -141,6 +144,8 @@ def to_timedelta(arg, unit=None, errors="raise"): def _coerce_scalar_to_timedelta_type(r, unit="ns", errors="raise"): """Convert string 'r' to a timedelta object.""" + result: Timedelta | NaTType # TODO: alias? + try: result = Timedelta(r, unit) except ValueError: From 3f6906a419e7030cbd6b1c93ea50d889325b2d3f Mon Sep 17 00:00:00 2001 From: Brock Date: Sun, 11 Apr 2021 12:29:20 -0700 Subject: [PATCH 2/2] ignores --- pandas/_libs/tslibs/timedeltas.pyi | 12 +++--------- pandas/core/dtypes/cast.py | 17 ++++++++++++++--- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/pandas/_libs/tslibs/timedeltas.pyi b/pandas/_libs/tslibs/timedeltas.pyi index 8c2bb9d88ed2d..9ccc3a8ed5fa4 100644 --- a/pandas/_libs/tslibs/timedeltas.pyi +++ b/pandas/_libs/tslibs/timedeltas.pyi @@ -1,21 +1,14 @@ from datetime import timedelta -from time import struct_time from typing import ( - AnyStr, ClassVar, - Optional, - SupportsAbs, - Tuple, Type, TypeVar, - Union, overload, ) import numpy as np from pandas._libs.tslibs import ( - NaT, NaTType, Tick, ) @@ -48,7 +41,8 @@ class Timedelta(timedelta): resolution: ClassVar[Timedelta] value: int # np.int64 - def __new__( + # error: "__new__" must return a class instance (got "Union[Timedelta, NaTType]") + def __new__( # type: ignore[misc] cls: Type[_S], value=..., unit=..., @@ -97,7 +91,7 @@ class Timedelta(timedelta): @overload def __truediv__(self, other: float) -> timedelta: ... def __mod__(self, other: timedelta) -> timedelta: ... - def __divmod__(self, other: timedelta) -> Tuple[int, timedelta]: ... + def __divmod__(self, other: timedelta) -> tuple[int, timedelta]: ... def __le__(self, other: timedelta) -> bool: ... def __lt__(self, other: timedelta) -> bool: ... diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index f62aa95e1e814..f7110062f15af 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -192,9 +192,15 @@ def maybe_box_native(value: Scalar) -> Scalar: if is_datetime_or_timedelta_dtype(value): value = maybe_box_datetimelike(value) elif is_float(value): - value = float(value) + # error: Argument 1 to "float" has incompatible type + # "Union[Union[str, int, float, bool], Union[Any, Any, Timedelta, Any]]"; + # expected "Union[SupportsFloat, _SupportsIndex, str]" + value = float(value) # type: ignore[arg-type] elif is_integer(value): - value = int(value) + # error: Argument 1 to "int" has incompatible type + # "Union[Union[str, int, float, bool], Union[Any, Any, Timedelta, Any]]"; + # pected "Union[str, SupportsInt, _SupportsIndex, _SupportsTrunc]" + value = int(value) # type: ignore[arg-type] elif is_bool(value): value = bool(value) return value @@ -2100,10 +2106,15 @@ def validate_numeric_casting(dtype: np.dtype, value: Scalar) -> None: ------ ValueError """ + # error: Argument 1 to "__call__" of "ufunc" has incompatible type + # "Union[Union[str, int, float, bool], Union[Any, Any, Timedelta, Any]]"; + # expected "Union[Union[int, float, complex, str, bytes, generic], + # Sequence[Union[int, float, complex, str, bytes, generic]], + # Sequence[Sequence[Any]], _SupportsArray]" if ( issubclass(dtype.type, (np.integer, np.bool_)) and is_float(value) - and np.isnan(value) + and np.isnan(value) # type: ignore[arg-type] ): raise ValueError("Cannot assign nan to integer series")