25
25
)
26
26
from pandas .core .dtypes .generic import ABCIndex , ABCIndexClass , ABCSeries
27
27
28
- from pandas .core import algorithms , ops
28
+ from pandas .core import algorithms
29
29
from pandas .core .accessor import PandasDelegate
30
30
from pandas .core .arrays import ExtensionArray , ExtensionOpsMixin
31
31
from pandas .core .arrays .datetimelike import (
40
40
41
41
from pandas .tseries .frequencies import DateOffset , to_offset
42
42
43
- from .extension import inherit_names
43
+ from .extension import inherit_names , make_wrapped_arith_op , make_wrapped_comparison_op
44
44
45
45
_index_doc_kwargs = dict (ibase ._index_doc_kwargs )
46
46
47
47
48
- def _make_wrapped_arith_op (opname ):
49
- def method (self , other ):
50
- meth = getattr (self ._data , opname )
51
- result = meth (maybe_unwrap_index (other ))
52
- return wrap_arithmetic_op (self , other , result )
53
-
54
- method .__name__ = opname
55
- return method
56
-
57
-
58
48
def _join_i8_wrapper (joinf , with_indexers : bool = True ):
59
49
"""
60
50
Create the join wrapper methods.
@@ -125,19 +115,7 @@ def _create_comparison_method(cls, op):
125
115
"""
126
116
Create a comparison method that dispatches to ``cls.values``.
127
117
"""
128
-
129
- def wrapper (self , other ):
130
- if isinstance (other , ABCSeries ):
131
- # the arrays defer to Series for comparison ops but the indexes
132
- # don't, so we have to unwrap here.
133
- other = other ._values
134
-
135
- result = op (self ._data , maybe_unwrap_index (other ))
136
- return result
137
-
138
- wrapper .__doc__ = op .__doc__
139
- wrapper .__name__ = f"__{ op .__name__ } __"
140
- return wrapper
118
+ return make_wrapped_comparison_op (f"__{ op .__name__ } __" )
141
119
142
120
# ------------------------------------------------------------------------
143
121
# Abstract data attributes
@@ -467,22 +445,22 @@ def _convert_scalar_indexer(self, key, kind=None):
467
445
468
446
return super ()._convert_scalar_indexer (key , kind = kind )
469
447
470
- __add__ = _make_wrapped_arith_op ("__add__" )
471
- __radd__ = _make_wrapped_arith_op ("__radd__" )
472
- __sub__ = _make_wrapped_arith_op ("__sub__" )
473
- __rsub__ = _make_wrapped_arith_op ("__rsub__" )
474
- __pow__ = _make_wrapped_arith_op ("__pow__" )
475
- __rpow__ = _make_wrapped_arith_op ("__rpow__" )
476
- __mul__ = _make_wrapped_arith_op ("__mul__" )
477
- __rmul__ = _make_wrapped_arith_op ("__rmul__" )
478
- __floordiv__ = _make_wrapped_arith_op ("__floordiv__" )
479
- __rfloordiv__ = _make_wrapped_arith_op ("__rfloordiv__" )
480
- __mod__ = _make_wrapped_arith_op ("__mod__" )
481
- __rmod__ = _make_wrapped_arith_op ("__rmod__" )
482
- __divmod__ = _make_wrapped_arith_op ("__divmod__" )
483
- __rdivmod__ = _make_wrapped_arith_op ("__rdivmod__" )
484
- __truediv__ = _make_wrapped_arith_op ("__truediv__" )
485
- __rtruediv__ = _make_wrapped_arith_op ("__rtruediv__" )
448
+ __add__ = make_wrapped_arith_op ("__add__" )
449
+ __radd__ = make_wrapped_arith_op ("__radd__" )
450
+ __sub__ = make_wrapped_arith_op ("__sub__" )
451
+ __rsub__ = make_wrapped_arith_op ("__rsub__" )
452
+ __pow__ = make_wrapped_arith_op ("__pow__" )
453
+ __rpow__ = make_wrapped_arith_op ("__rpow__" )
454
+ __mul__ = make_wrapped_arith_op ("__mul__" )
455
+ __rmul__ = make_wrapped_arith_op ("__rmul__" )
456
+ __floordiv__ = make_wrapped_arith_op ("__floordiv__" )
457
+ __rfloordiv__ = make_wrapped_arith_op ("__rfloordiv__" )
458
+ __mod__ = make_wrapped_arith_op ("__mod__" )
459
+ __rmod__ = make_wrapped_arith_op ("__rmod__" )
460
+ __divmod__ = make_wrapped_arith_op ("__divmod__" )
461
+ __rdivmod__ = make_wrapped_arith_op ("__rdivmod__" )
462
+ __truediv__ = make_wrapped_arith_op ("__truediv__" )
463
+ __rtruediv__ = make_wrapped_arith_op ("__rtruediv__" )
486
464
487
465
def isin (self , values , level = None ):
488
466
"""
@@ -864,55 +842,13 @@ def _wrap_joined_index(self, joined, other):
864
842
return self ._simple_new (joined , name , ** kwargs )
865
843
866
844
867
- def wrap_arithmetic_op (self , other , result ):
868
- if result is NotImplemented :
869
- return NotImplemented
870
-
871
- if isinstance (result , tuple ):
872
- # divmod, rdivmod
873
- assert len (result ) == 2
874
- return (
875
- wrap_arithmetic_op (self , other , result [0 ]),
876
- wrap_arithmetic_op (self , other , result [1 ]),
877
- )
878
-
879
- if not isinstance (result , Index ):
880
- # Index.__new__ will choose appropriate subclass for dtype
881
- result = Index (result )
882
-
883
- res_name = ops .get_op_result_name (self , other )
884
- result .name = res_name
885
- return result
886
-
887
-
888
- def maybe_unwrap_index (obj ):
889
- """
890
- If operating against another Index object, we need to unwrap the underlying
891
- data before deferring to the DatetimeArray/TimedeltaArray/PeriodArray
892
- implementation, otherwise we will incorrectly return NotImplemented.
893
-
894
- Parameters
895
- ----------
896
- obj : object
897
-
898
- Returns
899
- -------
900
- unwrapped object
901
- """
902
- if isinstance (obj , ABCIndexClass ):
903
- return obj ._data
904
- return obj
905
-
906
-
907
845
class DatetimelikeDelegateMixin (PandasDelegate ):
908
846
"""
909
847
Delegation mechanism, specific for Datetime, Timedelta, and Period types.
910
848
911
849
Functionality is delegated from the Index class to an Array class. A
912
850
few things can be customized
913
851
914
- * _delegate_class : type
915
- The class being delegated to.
916
852
* _delegated_methods, delegated_properties : List
917
853
The list of property / method names being delagated.
918
854
* raw_methods : Set
@@ -929,10 +865,6 @@ class DatetimelikeDelegateMixin(PandasDelegate):
929
865
_raw_properties : Set [str ] = set ()
930
866
_data : ExtensionArray
931
867
932
- @property
933
- def _delegate_class (self ):
934
- raise AbstractMethodError
935
-
936
868
def _delegate_property_get (self , name , * args , ** kwargs ):
937
869
result = getattr (self ._data , name )
938
870
if name not in self ._raw_properties :
0 commit comments