diff --git a/pandas/_typing.py b/pandas/_typing.py index 3df9a47a35fca..453de7172cd53 100644 --- a/pandas/_typing.py +++ b/pandas/_typing.py @@ -179,6 +179,7 @@ def __reversed__(self) -> Iterator[_T_co]: # passed in, a DataFrame is always returned. NDFrameT = TypeVar("NDFrameT", bound="NDFrame") +IndexT = TypeVar("IndexT", bound="Index") NumpyIndexT = TypeVar("NumpyIndexT", np.ndarray, "Index") AxisInt = int diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 70b72577dd5d1..0dce7c9714cfa 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -11280,7 +11280,7 @@ def _shift_with_freq(self, periods: int, axis: int, freq) -> Self: f"does not match PeriodIndex freq " f"{freq_to_period_freqstr(orig_freq.n, orig_freq.name)}" ) - new_ax = index.shift(periods) + new_ax: Index = index.shift(periods) else: new_ax = index.shift(periods, freq) diff --git a/pandas/core/indexes/accessors.py b/pandas/core/indexes/accessors.py index 7e3ba4089ff60..57bc9fe6c13cf 100644 --- a/pandas/core/indexes/accessors.py +++ b/pandas/core/indexes/accessors.py @@ -5,6 +5,7 @@ from typing import ( TYPE_CHECKING, + NoReturn, cast, ) import warnings @@ -117,7 +118,7 @@ def _delegate_property_get(self, name: str): return result - def _delegate_property_set(self, name: str, value, *args, **kwargs): + def _delegate_property_set(self, name: str, value, *args, **kwargs) -> NoReturn: raise ValueError( "modifications to a property of a datetimelike object are not supported. " "Change values on the original." @@ -501,7 +502,7 @@ def to_pytimedelta(self) -> np.ndarray: return self._get_values().to_pytimedelta() @property - def components(self): + def components(self) -> DataFrame: """ Return a Dataframe of the components of the Timedeltas. diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index ad39907e7400e..990b8133b5247 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -55,6 +55,7 @@ F, IgnoreRaise, IndexLabel, + IndexT, JoinHow, Level, NaPosition, @@ -2030,7 +2031,7 @@ def sortlevel( ascending: bool | list[bool] = True, sort_remaining=None, na_position: NaPosition = "first", - ): + ) -> tuple[Self, np.ndarray]: """ For internal compatibility with the Index API. @@ -4444,7 +4445,7 @@ def _wrap_reindex_result(self, target, indexer, preserve_names: bool): target = self._maybe_preserve_names(target, preserve_names) return target - def _maybe_preserve_names(self, target: Index, preserve_names: bool): + def _maybe_preserve_names(self, target: IndexT, preserve_names: bool) -> IndexT: if preserve_names and target.nlevels == 1 and target.name != self.name: target = target.copy(deep=False) target.name = self.name @@ -5965,7 +5966,7 @@ def sort(self, *args, **kwargs): """ raise TypeError("cannot sort an Index object in-place, use sort_values instead") - def shift(self, periods: int = 1, freq=None): + def shift(self, periods: int = 1, freq=None) -> Self: """ Shift index by desired number of time frequency increments. diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index cad8737a987d4..008ac71456518 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -272,7 +272,7 @@ def _can_partial_date_slice(self, reso: Resolution) -> bool: def _parsed_string_to_bounds(self, reso: Resolution, parsed): raise NotImplementedError - def _parse_with_reso(self, label: str): + def _parse_with_reso(self, label: str) -> tuple[datetime, Resolution]: # overridden by TimedeltaIndex try: if self.freq is None or hasattr(self.freq, "rule_code"): @@ -294,7 +294,7 @@ def _parse_with_reso(self, label: str): reso = Resolution.from_attrname(reso_str) return parsed, reso - def _get_string_slice(self, key: str): + def _get_string_slice(self, key: str) -> slice | npt.NDArray[np.intp]: # overridden by TimedeltaIndex parsed, reso = self._parse_with_reso(key) try: diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 3204a9c97ee73..66e27c9e3d1dc 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -518,7 +518,9 @@ def snap(self, freq: Frequency = "S") -> DatetimeIndex: # -------------------------------------------------------------------- # Indexing Methods - def _parsed_string_to_bounds(self, reso: Resolution, parsed: dt.datetime): + def _parsed_string_to_bounds( + self, reso: Resolution, parsed: dt.datetime + ) -> tuple[Timestamp, Timestamp]: """ Calculate datetime bounds for parsed time string and its resolution. @@ -555,7 +557,7 @@ def _parsed_string_to_bounds(self, reso: Resolution, parsed: dt.datetime): # which localizes parsed. return start, end - def _parse_with_reso(self, label: str): + def _parse_with_reso(self, label: str) -> tuple[Timestamp, Resolution]: parsed, reso = super()._parse_with_reso(label) parsed = Timestamp(parsed) diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 8954d49649a2b..1412eb6caeb0b 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -37,6 +37,7 @@ F, IgnoreRaise, IndexLabel, + IndexT, Scalar, Self, Shape, @@ -2741,7 +2742,7 @@ def _wrap_reindex_result(self, target, indexer, preserve_names: bool): target = self._maybe_preserve_names(target, preserve_names) return target - def _maybe_preserve_names(self, target: Index, preserve_names: bool) -> Index: + def _maybe_preserve_names(self, target: IndexT, preserve_names: bool) -> IndexT: if ( preserve_names and target.nlevels == self.nlevels diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index 62afcf8badb50..85015b522239f 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -876,7 +876,7 @@ def _difference(self, other, sort=None): def symmetric_difference( self, other, result_name: Hashable | None = None, sort=None - ): + ) -> Index: if not isinstance(other, RangeIndex) or sort is not None: return super().symmetric_difference(other, result_name, sort) diff --git a/pandas/core/indexes/timedeltas.py b/pandas/core/indexes/timedeltas.py index 08a265ba47648..db813b047b2bb 100644 --- a/pandas/core/indexes/timedeltas.py +++ b/pandas/core/indexes/timedeltas.py @@ -32,6 +32,7 @@ from pandas.core.indexes.extension import inherit_names if TYPE_CHECKING: + from pandas._libs import NaTType from pandas._typing import DtypeObj @@ -245,7 +246,10 @@ def get_loc(self, key): return Index.get_loc(self, key) - def _parse_with_reso(self, label: str): + # error: Return type "tuple[Timedelta | NaTType, None]" of "_parse_with_reso" + # incompatible with return type "tuple[datetime, Resolution]" in supertype + # "DatetimeIndexOpsMixin" + def _parse_with_reso(self, label: str) -> tuple[Timedelta | NaTType, None]: # type: ignore[override] # the "with_reso" is a no-op for TimedeltaIndex parsed = Timedelta(label) return parsed, None diff --git a/pyproject.toml b/pyproject.toml index 9f2c7c0c56295..d4f50c8a2bd62 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -812,5 +812,5 @@ exclude_lines = [ directory = "coverage_html_report" [tool.codespell] -ignore-words-list = "blocs, coo, hist, nd, sav, ser, recuse, nin, timere, expec, expecs" +ignore-words-list = "blocs, coo, hist, nd, sav, ser, recuse, nin, timere, expec, expecs, indext" ignore-regex = 'https://([\w/\.])+'