2424 round_nsint64 ,
2525)
2626from pandas ._typing import DatetimeLikeScalar , DtypeObj
27- from pandas .compat import set_function_name
2827from pandas .compat .numpy import function as nv
2928from pandas .errors import AbstractMethodError , NullFrequencyError , PerformanceWarning
3029from pandas .util ._decorators import Appender , Substitution , cache_readonly
5150
5251from pandas .core import nanops , ops
5352from pandas .core .algorithms import checked_add_with_arr , unique1d , value_counts
53+ from pandas .core .arraylike import OpsMixin
5454from pandas .core .arrays ._mixins import NDArrayBackedExtensionArray
55- from pandas .core .arrays .base import ExtensionOpsMixin
5655import pandas .core .common as com
5756from pandas .core .construction import array , extract_array
5857from pandas .core .indexers import check_array_indexer , check_setitem_lengths
@@ -73,46 +72,6 @@ class InvalidComparison(Exception):
7372 pass
7473
7574
76- def _datetimelike_array_cmp (cls , op ):
77- """
78- Wrap comparison operations to convert Timestamp/Timedelta/Period-like to
79- boxed scalars/arrays.
80- """
81- opname = f"__{ op .__name__ } __"
82- nat_result = opname == "__ne__"
83-
84- @unpack_zerodim_and_defer (opname )
85- def wrapper (self , other ):
86- if self .ndim > 1 and getattr (other , "shape" , None ) == self .shape :
87- # TODO: handle 2D-like listlikes
88- return op (self .ravel (), other .ravel ()).reshape (self .shape )
89-
90- try :
91- other = self ._validate_comparison_value (other , opname )
92- except InvalidComparison :
93- return invalid_comparison (self , other , op )
94-
95- dtype = getattr (other , "dtype" , None )
96- if is_object_dtype (dtype ):
97- # We have to use comp_method_OBJECT_ARRAY instead of numpy
98- # comparison otherwise it would fail to raise when
99- # comparing tz-aware and tz-naive
100- with np .errstate (all = "ignore" ):
101- result = ops .comp_method_OBJECT_ARRAY (op , self .astype (object ), other )
102- return result
103-
104- other_i8 = self ._unbox (other )
105- result = op (self .asi8 , other_i8 )
106-
107- o_mask = isna (other )
108- if self ._hasnans | np .any (o_mask ):
109- result [self ._isnan | o_mask ] = nat_result
110-
111- return result
112-
113- return set_function_name (wrapper , opname , cls )
114-
115-
11675class AttributesMixin :
11776 _data : np .ndarray
11877
@@ -426,9 +385,7 @@ def _with_freq(self, freq):
426385DatetimeLikeArrayT = TypeVar ("DatetimeLikeArrayT" , bound = "DatetimeLikeArrayMixin" )
427386
428387
429- class DatetimeLikeArrayMixin (
430- ExtensionOpsMixin , AttributesMixin , NDArrayBackedExtensionArray
431- ):
388+ class DatetimeLikeArrayMixin (OpsMixin , AttributesMixin , NDArrayBackedExtensionArray ):
432389 """
433390 Shared Base/Mixin class for DatetimeArray, TimedeltaArray, PeriodArray
434391
@@ -1093,7 +1050,35 @@ def _is_unique(self):
10931050
10941051 # ------------------------------------------------------------------
10951052 # Arithmetic Methods
1096- _create_comparison_method = classmethod (_datetimelike_array_cmp )
1053+
1054+ def _cmp_method (self , other , op ):
1055+ if self .ndim > 1 and getattr (other , "shape" , None ) == self .shape :
1056+ # TODO: handle 2D-like listlikes
1057+ return op (self .ravel (), other .ravel ()).reshape (self .shape )
1058+
1059+ try :
1060+ other = self ._validate_comparison_value (other , f"__{ op .__name__ } __" )
1061+ except InvalidComparison :
1062+ return invalid_comparison (self , other , op )
1063+
1064+ dtype = getattr (other , "dtype" , None )
1065+ if is_object_dtype (dtype ):
1066+ # We have to use comp_method_OBJECT_ARRAY instead of numpy
1067+ # comparison otherwise it would fail to raise when
1068+ # comparing tz-aware and tz-naive
1069+ with np .errstate (all = "ignore" ):
1070+ result = ops .comp_method_OBJECT_ARRAY (op , self .astype (object ), other )
1071+ return result
1072+
1073+ other_i8 = self ._unbox (other )
1074+ result = op (self .asi8 , other_i8 )
1075+
1076+ o_mask = isna (other )
1077+ if self ._hasnans | np .any (o_mask ):
1078+ nat_result = op is operator .ne
1079+ result [self ._isnan | o_mask ] = nat_result
1080+
1081+ return result
10971082
10981083 # pow is invalid for all three subclasses; TimedeltaArray will override
10991084 # the multiplication and division ops
@@ -1582,8 +1567,6 @@ def median(self, axis: Optional[int] = None, skipna: bool = True, *args, **kwarg
15821567 return self ._from_backing_data (result .astype ("i8" ))
15831568
15841569
1585- DatetimeLikeArrayMixin ._add_comparison_ops ()
1586-
15871570# -------------------------------------------------------------------
15881571# Shared Constructor Helpers
15891572
0 commit comments