From bf2ef650fb672221b5295b77c0f934a33642649d Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sat, 4 Jan 2020 11:37:46 -0800 Subject: [PATCH 1/3] commit so i can rebase --- pandas/core/indexes/base.py | 2 +- pandas/core/indexes/category.py | 4 +--- pandas/core/indexes/datetimelike.py | 6 ------ pandas/core/indexes/datetimes.py | 12 +++--------- pandas/core/indexes/timedeltas.py | 26 ++++++++++++++------------ 5 files changed, 19 insertions(+), 31 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index ed5c6b450b05e..5a8bc719a36da 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -4660,7 +4660,7 @@ def isin(self, values, level=None): self._validate_index_level(level) return algos.isin(self, values) - def _get_string_slice(self, key, use_lhs=True, use_rhs=True): + def _get_string_slice(self, key: str, use_lhs=True, use_rhs=True): # this is for partial string indexing, # overridden in DatetimeIndex, TimedeltaIndex and PeriodIndex raise NotImplementedError diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index 96bfff9a0a09f..9ece919dff03d 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -268,14 +268,12 @@ def _create_categorical(cls, data, dtype=None): return data @classmethod - def _simple_new(cls, values, name=None, dtype=None, **kwargs): + def _simple_new(cls, values, name=None, dtype=None): result = object.__new__(cls) values = cls._create_categorical(values, dtype=dtype) result._data = values result.name = name - for k, v in kwargs.items(): - setattr(result, k, v) result._reset_identity() result._no_setting_name = False diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 7bf1a601a0ab6..1c5171645303b 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -186,12 +186,6 @@ def equals(self, other): # have different timezone return False - elif is_period_dtype(self): - if not is_period_dtype(other): - return False - if self.freq != other.freq: - return False - return np.array_equal(self.asi8, other.asi8) def _ensure_localized( diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index bc6b8ff845a56..a04175ebcedcb 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -388,18 +388,12 @@ def _formatter_func(self): # -------------------------------------------------------------------- # Set Operation Methods - def _union(self, other, sort): + def _union(self, other: "DatetimeIndex", sort): if not len(other) or self.equals(other) or not len(self): return super()._union(other, sort=sort) - if len(other) == 0 or self.equals(other) or len(self) == 0: - return super().union(other, sort=sort) - - if not isinstance(other, DatetimeIndex): - try: - other = DatetimeIndex(other) - except TypeError: - pass + # We are called by `union`, which is responsible for this validation + assert isinstance(other, DatetimeIndex) this, other = self._maybe_utc_convert(other) diff --git a/pandas/core/indexes/timedeltas.py b/pandas/core/indexes/timedeltas.py index 894b430f1c4fd..8c8bbcc7909de 100644 --- a/pandas/core/indexes/timedeltas.py +++ b/pandas/core/indexes/timedeltas.py @@ -249,15 +249,13 @@ def astype(self, dtype, copy=True): return Index(result.astype("i8"), name=self.name) return DatetimeIndexOpsMixin.astype(self, dtype, copy=copy) - def _union(self, other, sort): + def _union(self, other: "TimedeltaIndex", sort): if len(other) == 0 or self.equals(other) or len(self) == 0: return super()._union(other, sort=sort) - if not isinstance(other, TimedeltaIndex): - try: - other = TimedeltaIndex(other) - except (TypeError, ValueError): - pass + # We are called by `union`, which is responsible for this validation + assert isinstance(other, TimedeltaIndex) + this, other = self, other if this._can_fast_union(other): @@ -310,7 +308,7 @@ def get_value(self, series, key): return self.get_value_maybe_box(series, key) try: - return com.maybe_box(self, Index.get_value(self, series, key), series, key) + value = Index.get_value(self, series, key) except KeyError: try: loc = self._get_string_slice(key) @@ -322,10 +320,10 @@ def get_value(self, series, key): return self.get_value_maybe_box(series, key) except (TypeError, ValueError, KeyError): raise KeyError(key) + else: + return com.maybe_box(self, value, series, key) - def get_value_maybe_box(self, series, key): - if not isinstance(key, Timedelta): - key = Timedelta(key) + def get_value_maybe_box(self, series, key: Timedelta): values = self._engine.get_value(com.values_from_object(series), key) return com.maybe_box(self, values, series, key) @@ -356,6 +354,7 @@ def get_loc(self, key, method=None, tolerance=None): key = Timedelta(key) return Index.get_loc(self, key, method, tolerance) + return Index.get_loc(self, key, method, tolerance) try: return Index.get_loc(self, key, method, tolerance) except (KeyError, ValueError, TypeError): @@ -366,7 +365,9 @@ def get_loc(self, key, method=None, tolerance=None): try: stamp = Timedelta(key) - return Index.get_loc(self, stamp, method, tolerance) + result = Index.get_loc(self, stamp, method, tolerance) + assert False, (key, stamp, result) + return result except (KeyError, ValueError): raise KeyError(key) @@ -398,7 +399,8 @@ def _maybe_cast_slice_bound(self, label, side, kind): return label - def _get_string_slice(self, key): + def _get_string_slice(self, key: str): + # FIXME: we should never get integer or float or NaT here if is_integer(key) or is_float(key) or key is NaT: self._invalid_indexer("slice", key) loc = self._partial_td_slice(key) From a0e4ec18d9078c021fc75da403063c3ddb543a6e Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sat, 4 Jan 2020 11:52:27 -0800 Subject: [PATCH 2/3] cleanup --- pandas/core/indexes/base.py | 2 +- pandas/core/indexes/timedeltas.py | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 6f55d072931f3..ce4715dd5bbf3 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -4649,7 +4649,7 @@ def isin(self, values, level=None): self._validate_index_level(level) return algos.isin(self, values) - def _get_string_slice(self, key: str, use_lhs=True, use_rhs=True): + def _get_string_slice(self, key, use_lhs=True, use_rhs=True): # this is for partial string indexing, # overridden in DatetimeIndex, TimedeltaIndex and PeriodIndex raise NotImplementedError diff --git a/pandas/core/indexes/timedeltas.py b/pandas/core/indexes/timedeltas.py index f78f59e9bda03..6cb4410d6a305 100644 --- a/pandas/core/indexes/timedeltas.py +++ b/pandas/core/indexes/timedeltas.py @@ -353,7 +353,6 @@ def get_loc(self, key, method=None, tolerance=None): key = Timedelta(key) return Index.get_loc(self, key, method, tolerance) - return Index.get_loc(self, key, method, tolerance) try: return Index.get_loc(self, key, method, tolerance) except (KeyError, ValueError, TypeError): @@ -364,9 +363,7 @@ def get_loc(self, key, method=None, tolerance=None): try: stamp = Timedelta(key) - result = Index.get_loc(self, stamp, method, tolerance) - assert False, (key, stamp, result) - return result + return Index.get_loc(self, stamp, method, tolerance) except (KeyError, ValueError): raise KeyError(key) @@ -398,8 +395,7 @@ def _maybe_cast_slice_bound(self, label, side, kind): return label - def _get_string_slice(self, key: str): - # FIXME: we should never get integer or float or NaT here + def _get_string_slice(self, key): if is_integer(key) or is_float(key) or key is NaT: self._invalid_indexer("slice", key) loc = self._partial_td_slice(key) From 41cb09e2f87f93412ecc11b897927dcfc1e4d574 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sat, 4 Jan 2020 12:45:24 -0800 Subject: [PATCH 3/3] remove kludge, fixes mypy --- pandas/core/indexes/datetimes.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 1ebe9a7081cd0..64bbb2a53725f 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -401,9 +401,7 @@ def _union(self, other: "DatetimeIndex", sort): else: result = Index._union(this, other, sort=sort) if isinstance(result, DatetimeIndex): - # TODO: we shouldn't be setting attributes like this; - # in all the tests this equality already holds - result._data._dtype = this.dtype + assert result._data.dtype == this.dtype if result.freq is None and ( this.freq is not None or other.freq is not None ):