From b33a6d0e7af2f8f26a92bab6eb8216882f5dd50a Mon Sep 17 00:00:00 2001 From: tp Date: Mon, 12 Oct 2020 23:08:21 +0100 Subject: [PATCH 1/4] CLN: clean Index._id --- pandas/core/indexes/base.py | 8 ++++---- pandas/core/indexes/multi.py | 4 +++- pandas/tests/arithmetic/test_object.py | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index b3f5fb6f0291a..6495eb891bc0c 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -238,7 +238,7 @@ def _outer_indexer(self, left, right): _typ = "index" _data: Union[ExtensionArray, np.ndarray] - _id = None + _id: _Identity _name: Label = None # MultiIndex.levels previously allowed setting the index name. We # don't allow this anymore, and raise if it happens rather than @@ -453,8 +453,9 @@ def _simple_new(cls, values, name: Label = None): result._index_data = values result._name = name result._cache = {} + result._reset_identity() - return result._reset_identity() + return result @cache_readonly def _constructor(self): @@ -561,12 +562,11 @@ def is_(self, other) -> bool: # use something other than None to be clearer return self._id is getattr(other, "_id", Ellipsis) and self._id is not None - def _reset_identity(self): + def _reset_identity(self) -> None: """ Initializes or resets ``_id`` attribute with new object. """ self._id = _Identity() - return self def _cleanup(self): self._engine.clear_mapping() diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 2ce4538a63d25..38a0d18ac732d 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -316,7 +316,9 @@ def __new__( new_codes = result._verify_integrity() result._codes = new_codes - return result._reset_identity() + result._reset_identity() + + return result def _validate_codes(self, level: List, code: List): """ diff --git a/pandas/tests/arithmetic/test_object.py b/pandas/tests/arithmetic/test_object.py index 02cb4f4d7a606..e0c03f28f7af5 100644 --- a/pandas/tests/arithmetic/test_object.py +++ b/pandas/tests/arithmetic/test_object.py @@ -343,8 +343,9 @@ def _simple_new(cls, values, name=None, dtype=None): result._index_data = values result._name = name result._calls = 0 + result._reset_identity() - return result._reset_identity() + return result def __add__(self, other): self._calls += 1 From 0f5fc5dd384536664e9908f0e0cadcd2a76f5079 Mon Sep 17 00:00:00 2001 From: tp Date: Mon, 12 Oct 2020 23:59:57 +0100 Subject: [PATCH 2/4] add id class --- pandas/core/indexes/base.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 6495eb891bc0c..c365078f8a5d7 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -139,7 +139,10 @@ def index_arithmetic_method(self, other): _o_dtype = np.dtype(object) -_Identity = object + + +class _Identity: + pass def _new_Index(cls, d): From f49c97e82b57fd1d14a5de4e719251f2a9aa81fb Mon Sep 17 00:00:00 2001 From: tp Date: Tue, 13 Oct 2020 09:00:26 +0100 Subject: [PATCH 3/4] use typing.NewType --- pandas/core/indexes/base.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index c365078f8a5d7..aa1f304916a32 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -9,6 +9,7 @@ FrozenSet, Hashable, List, + NewType, Optional, Sequence, Tuple, @@ -141,8 +142,7 @@ def index_arithmetic_method(self, other): _o_dtype = np.dtype(object) -class _Identity: - pass +_Identity = NewType("_Identity", object) def _new_Index(cls, d): @@ -562,14 +562,13 @@ def is_(self, other) -> bool: -------- Index.identical : Works like ``Index.is_`` but also checks metadata. """ - # use something other than None to be clearer - return self._id is getattr(other, "_id", Ellipsis) and self._id is not None + return self._id is getattr(other, "_id", None) def _reset_identity(self) -> None: """ Initializes or resets ``_id`` attribute with new object. """ - self._id = _Identity() + self._id = _Identity(object()) def _cleanup(self): self._engine.clear_mapping() From 851c797361b226a9557e174210ca82fa6043d0ef Mon Sep 17 00:00:00 2001 From: tp Date: Tue, 13 Oct 2020 09:12:52 +0100 Subject: [PATCH 4/4] avoid getattr in Index.is_ --- pandas/core/indexes/base.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index aa1f304916a32..d180945d85d00 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -562,7 +562,10 @@ def is_(self, other) -> bool: -------- Index.identical : Works like ``Index.is_`` but also checks metadata. """ - return self._id is getattr(other, "_id", None) + try: + return self._id is other._id + except AttributeError: + return False def _reset_identity(self) -> None: """