From a5e661a6a0f60abf50357de3ff8a76f0d92d30c7 Mon Sep 17 00:00:00 2001 From: tp Date: Tue, 27 Apr 2021 15:28:44 +0100 Subject: [PATCH 1/3] TYP: cleanup typing in core.indexes.range.py --- pandas/core/indexes/base.py | 2 +- pandas/core/indexes/numeric.py | 2 +- pandas/core/indexes/range.py | 37 +++++++++------------------------- 3 files changed, 12 insertions(+), 29 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 9b3f2d191831d..1bae9947bd875 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -5874,7 +5874,7 @@ def slice_locs(self, start=None, end=None, step=None, kind=None): return start_slice, end_slice - def delete(self, loc) -> Index: + def delete(self: _IndexT, loc) -> _IndexT: """ Make new Index with passed location(-s) deleted. diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index 3e8b44dcee831..28f563764ef10 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -98,7 +98,7 @@ def _ensure_array(cls, data, dtype, copy: bool): return subarr @classmethod - def _validate_dtype(cls, dtype: Dtype) -> None: + def _validate_dtype(cls, dtype: Dtype | None) -> None: if dtype is None: return diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index 0a2c0820f20a3..f53f0bed91a05 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -8,6 +8,7 @@ Any, Callable, Hashable, + cast, ) import warnings @@ -110,13 +111,7 @@ def __new__( copy: bool = False, name: Hashable = None, ) -> RangeIndex: - - # error: Argument 1 to "_validate_dtype" of "NumericIndex" has incompatible type - # "Union[ExtensionDtype, str, dtype[Any], Type[str], Type[float], Type[int], - # Type[complex], Type[bool], Type[object], None]"; expected - # "Union[ExtensionDtype, Union[str, dtype[Any]], Type[str], Type[float], - # Type[int], Type[complex], Type[bool], Type[object]]" - cls._validate_dtype(dtype) # type: ignore[arg-type] + cls._validate_dtype(dtype) name = maybe_extract_name(name, start, cls) # RangeIndex @@ -159,13 +154,7 @@ def from_range( f"{cls.__name__}(...) must be called with object coercible to a " f"range, {repr(data)} was passed" ) - - # error: Argument 1 to "_validate_dtype" of "NumericIndex" has incompatible type - # "Union[ExtensionDtype, str, dtype[Any], Type[str], Type[float], Type[int], - # Type[complex], Type[bool], Type[object], None]"; expected - # "Union[ExtensionDtype, Union[str, dtype[Any]], Type[str], Type[float], - # Type[int], Type[complex], Type[bool], Type[object]]" - cls._validate_dtype(dtype) # type: ignore[arg-type] + cls._validate_dtype(dtype) return cls._simple_new(data, name=name) @classmethod @@ -440,8 +429,7 @@ def repeat(self, repeats, axis=None) -> Int64Index: return self._int64index.repeat(repeats, axis=axis) def delete(self, loc) -> Int64Index: - # error: Incompatible return value type (got "Index", expected "Int64Index") - return self._int64index.delete(loc) # type: ignore[return-value] + return self._int64index.delete(loc) def take( self, indices, axis: int = 0, allow_fill: bool = True, fill_value=None, **kwargs @@ -779,11 +767,13 @@ def _concat(self, indexes: list[Index], name: Hashable): start = step = next_ = None # Filter the empty indexes - non_empty_indexes = [obj for obj in indexes if len(obj)] + assert all(isinstance(x, RangeIndex) for x in indexes) + non_empty_indexes: list[RangeIndex] = [ + cast(RangeIndex, obj) for obj in indexes if len(obj) + ] for obj in non_empty_indexes: - # error: "Index" has no attribute "_range" - rng: range = obj._range # type: ignore[attr-defined] + rng = obj._range if start is None: # This is set by the first non-empty index @@ -809,14 +799,7 @@ def _concat(self, indexes: list[Index], name: Hashable): next_ = rng[-1] + step if non_empty_indexes: - # Get the stop value from "next" or alternatively - # from the last non-empty index - # error: "Index" has no attribute "stop" - stop = ( - non_empty_indexes[-1].stop # type: ignore[attr-defined] - if next_ is None - else next_ - ) + stop = non_empty_indexes[-1].stop if next_ is None else next_ return RangeIndex(start, stop, step).rename(name) # Here all "indexes" had 0 length, i.e. were empty. From 0fc8740ba5a0ea3d92600fa94a920530b2303432 Mon Sep 17 00:00:00 2001 From: tp Date: Tue, 27 Apr 2021 15:54:03 +0100 Subject: [PATCH 2/3] fixes --- pandas/core/indexes/range.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index f53f0bed91a05..fc723aea45aa2 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -428,7 +428,7 @@ def _get_indexer( def repeat(self, repeats, axis=None) -> Int64Index: return self._int64index.repeat(repeats, axis=axis) - def delete(self, loc) -> Int64Index: + def delete(self, loc) -> Int64Index: # type: ignore[override] return self._int64index.delete(loc) def take( @@ -749,7 +749,7 @@ def symmetric_difference(self, other, result_name: Hashable = None, sort=None): # -------------------------------------------------------------------- - def _concat(self, indexes: list[Index], name: Hashable): + def _concat(self, indexes: list[Index], name: Hashable) -> Index: """ Overriding parent method for the case of all RangeIndex instances. @@ -761,16 +761,15 @@ def _concat(self, indexes: list[Index], name: Hashable): if not all(isinstance(x, RangeIndex) for x in indexes): return super()._concat(indexes, name) - elif len(indexes) == 1: - return indexes[0] + rng_indexes: list[RangeIndex] = [cast(RangeIndex, obj) for obj in indexes] + + if len(indexes) == 1: + return rng_indexes[0] start = step = next_ = None # Filter the empty indexes - assert all(isinstance(x, RangeIndex) for x in indexes) - non_empty_indexes: list[RangeIndex] = [ - cast(RangeIndex, obj) for obj in indexes if len(obj) - ] + non_empty_indexes = [obj for obj in rng_indexes if len(obj)] for obj in non_empty_indexes: rng = obj._range @@ -783,7 +782,9 @@ def _concat(self, indexes: list[Index], name: Hashable): elif step is None: # First non-empty index had only one element if rng.start == start: - result = Int64Index(np.concatenate([x._values for x in indexes])) + result = Int64Index( + np.concatenate([x._values for x in rng_indexes]) + ) return result.rename(name) step = rng.start - start @@ -792,7 +793,7 @@ def _concat(self, indexes: list[Index], name: Hashable): next_ is not None and rng.start != next_ ) if non_consecutive: - result = Int64Index(np.concatenate([x._values for x in indexes])) + result = Int64Index(np.concatenate([x._values for x in rng_indexes])) return result.rename(name) if step is not None: From 7d09951a6e99b1b275d87d84baa776205941cf9b Mon Sep 17 00:00:00 2001 From: tp Date: Wed, 28 Apr 2021 23:21:35 +0100 Subject: [PATCH 3/3] better casting --- pandas/core/indexes/range.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index fc723aea45aa2..8a91ba22fcba1 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -8,6 +8,7 @@ Any, Callable, Hashable, + List, cast, ) import warnings @@ -761,10 +762,10 @@ def _concat(self, indexes: list[Index], name: Hashable) -> Index: if not all(isinstance(x, RangeIndex) for x in indexes): return super()._concat(indexes, name) - rng_indexes: list[RangeIndex] = [cast(RangeIndex, obj) for obj in indexes] + elif len(indexes) == 1: + return indexes[0] - if len(indexes) == 1: - return rng_indexes[0] + rng_indexes = cast(List[RangeIndex], indexes) start = step = next_ = None @@ -782,9 +783,8 @@ def _concat(self, indexes: list[Index], name: Hashable) -> Index: elif step is None: # First non-empty index had only one element if rng.start == start: - result = Int64Index( - np.concatenate([x._values for x in rng_indexes]) - ) + values = np.concatenate([x._values for x in rng_indexes]) + result = Int64Index(values) return result.rename(name) step = rng.start - start @@ -800,6 +800,8 @@ def _concat(self, indexes: list[Index], name: Hashable) -> Index: next_ = rng[-1] + step if non_empty_indexes: + # Get the stop value from "next" or alternatively + # from the last non-empty index stop = non_empty_indexes[-1].stop if next_ is None else next_ return RangeIndex(start, stop, step).rename(name)