Skip to content

REF: share comparison methods between ExtensionIndex subclasses #30817

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 1 addition & 22 deletions pandas/core/indexes/category.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import operator
from typing import Any, List
import warnings

Expand All @@ -9,7 +8,6 @@
from pandas._libs import index as libindex
from pandas._libs.hashtable import duplicated_int64
from pandas._typing import AnyArrayLike
import pandas.compat as compat
from pandas.util._decorators import Appender, cache_readonly

from pandas.core.dtypes.common import (
Expand All @@ -29,7 +27,7 @@
import pandas.core.common as com
import pandas.core.indexes.base as ibase
from pandas.core.indexes.base import Index, _index_shared_docs, maybe_extract_name
from pandas.core.indexes.extension import ExtensionIndex, make_wrapped_comparison_op
from pandas.core.indexes.extension import ExtensionIndex
import pandas.core.missing as missing
from pandas.core.ops import get_op_result_name

Expand Down Expand Up @@ -858,24 +856,6 @@ def _concat_same_dtype(self, to_concat, name):
result.name = name
return result

@classmethod
def _add_comparison_methods(cls):
""" add in comparison methods """

def _make_compare(op):
opname = f"__{op.__name__}__"

_evaluate_compare = make_wrapped_comparison_op(opname)

return compat.set_function_name(_evaluate_compare, opname, cls)

cls.__eq__ = _make_compare(operator.eq)
cls.__ne__ = _make_compare(operator.ne)
cls.__lt__ = _make_compare(operator.lt)
cls.__gt__ = _make_compare(operator.gt)
cls.__le__ = _make_compare(operator.le)
cls.__ge__ = _make_compare(operator.ge)

def _delegate_property_get(self, name, *args, **kwargs):
""" method delegation to the ._values """
prop = getattr(self._values, name)
Expand All @@ -895,4 +875,3 @@ def _delegate_method(self, name, *args, **kwargs):
CategoricalIndex._add_numeric_methods_add_sub_disabled()
CategoricalIndex._add_numeric_methods_disabled()
CategoricalIndex._add_logical_methods_disabled()
CategoricalIndex._add_comparison_methods()
17 changes: 2 additions & 15 deletions pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,14 @@

from pandas.core import algorithms
from pandas.core.accessor import PandasDelegate
from pandas.core.arrays import (
DatetimeArray,
ExtensionArray,
ExtensionOpsMixin,
TimedeltaArray,
)
from pandas.core.arrays import DatetimeArray, ExtensionArray, TimedeltaArray
from pandas.core.arrays.datetimelike import DatetimeLikeArrayMixin
import pandas.core.indexes.base as ibase
from pandas.core.indexes.base import Index, _index_shared_docs
from pandas.core.indexes.extension import (
ExtensionIndex,
inherit_names,
make_wrapped_arith_op,
make_wrapped_comparison_op,
)
from pandas.core.indexes.numeric import Int64Index
from pandas.core.ops import get_op_result_name
Expand Down Expand Up @@ -90,7 +84,7 @@ def wrapper(left, right):
["__iter__", "mean", "freq", "freqstr", "_ndarray_values", "asi8", "_box_values"],
DatetimeLikeArrayMixin,
)
class DatetimeIndexOpsMixin(ExtensionIndex, ExtensionOpsMixin):
class DatetimeIndexOpsMixin(ExtensionIndex):
"""
Common ops mixin to support a unified interface datetimelike Index.
"""
Expand All @@ -109,13 +103,6 @@ class DatetimeIndexOpsMixin(ExtensionIndex, ExtensionOpsMixin):
def is_all_dates(self) -> bool:
return True

@classmethod
def _create_comparison_method(cls, op):
"""
Create a comparison method that dispatches to ``cls.values``.
"""
return make_wrapped_comparison_op(f"__{op.__name__}__")

# ------------------------------------------------------------------------
# Abstract data attributes

Expand Down
1 change: 0 additions & 1 deletion pandas/core/indexes/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1013,7 +1013,6 @@ def indexer_between_time(
return mask.nonzero()[0]


DatetimeIndex._add_comparison_ops()
DatetimeIndex._add_numeric_methods_disabled()
DatetimeIndex._add_logical_methods_disabled()

Expand Down
9 changes: 8 additions & 1 deletion pandas/core/indexes/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def wrapper(cls):
return wrapper


def make_wrapped_comparison_op(opname):
def _make_wrapped_comparison_op(opname):
"""
Create a comparison method that dispatches to ``._data``.
"""
Expand Down Expand Up @@ -163,6 +163,13 @@ class ExtensionIndex(Index):

_data: ExtensionArray

__eq__ = _make_wrapped_comparison_op("__eq__")
__ne__ = _make_wrapped_comparison_op("__ne__")
__lt__ = _make_wrapped_comparison_op("__lt__")
__gt__ = _make_wrapped_comparison_op("__gt__")
__le__ = _make_wrapped_comparison_op("__le__")
__ge__ = _make_wrapped_comparison_op("__ge__")

def repeat(self, repeats, axis=None):
nv.validate_repeat(tuple(), dict(axis=axis))
result = self._data.repeat(repeats, axis=axis)
Expand Down
24 changes: 13 additions & 11 deletions pandas/core/indexes/interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,7 @@
maybe_extract_name,
)
from pandas.core.indexes.datetimes import DatetimeIndex, date_range
from pandas.core.indexes.extension import (
ExtensionIndex,
inherit_names,
make_wrapped_comparison_op,
)
from pandas.core.indexes.extension import ExtensionIndex, inherit_names
from pandas.core.indexes.multi import MultiIndex
from pandas.core.indexes.timedeltas import TimedeltaIndex, timedelta_range
from pandas.core.ops import get_op_result_name
Expand Down Expand Up @@ -1195,14 +1191,20 @@ def _delegate_method(self, name, *args, **kwargs):
return type(self)._simple_new(res, name=self.name)
return Index(res)

@classmethod
def _add_comparison_methods(cls):
""" add in comparison methods """
cls.__eq__ = make_wrapped_comparison_op("__eq__")
cls.__ne__ = make_wrapped_comparison_op("__ne__")
# GH#30817 until IntervalArray implements inequalities, get them from Index
def __lt__(self, other):
return Index.__lt__(self, other)

def __le__(self, other):
return Index.__le__(self, other)

def __gt__(self, other):
return Index.__gt__(self, other)

def __ge__(self, other):
return Index.__ge__(self, other)


IntervalIndex._add_comparison_methods()
IntervalIndex._add_logical_methods_disabled()


Expand Down
1 change: 0 additions & 1 deletion pandas/core/indexes/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,6 @@ def memory_usage(self, deep=False):
return result


PeriodIndex._add_comparison_ops()
PeriodIndex._add_numeric_methods_disabled()
PeriodIndex._add_logical_methods_disabled()

Expand Down
1 change: 0 additions & 1 deletion pandas/core/indexes/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,6 @@ def insert(self, loc, item):
raise TypeError("cannot insert TimedeltaIndex with incompatible label")


TimedeltaIndex._add_comparison_ops()
TimedeltaIndex._add_logical_methods_disabled()


Expand Down