@@ -854,173 +854,159 @@ def _time_shift(self, periods, freq=None):
854854 return self ._generate_range (start = start , end = end , periods = None ,
855855 freq = self .freq )
856856
857- @classmethod
858- def _add_datetimelike_methods (cls ):
859- """
860- add in the datetimelike methods (as we may have to override the
861- superclass)
862- """
857+ def __add__ (self , other ):
858+ other = lib .item_from_zerodim (other )
859+ if isinstance (other , (ABCSeries , ABCDataFrame )):
860+ return NotImplemented
863861
864- def __add__ (self , other ):
865- other = lib .item_from_zerodim (other )
866- if isinstance (other , (ABCSeries , ABCDataFrame )):
867- return NotImplemented
868-
869- # scalar others
870- elif other is NaT :
871- result = self ._add_nat ()
872- elif isinstance (other , (Tick , timedelta , np .timedelta64 )):
873- result = self ._add_delta (other )
874- elif isinstance (other , DateOffset ):
875- # specifically _not_ a Tick
876- result = self ._add_offset (other )
877- elif isinstance (other , (datetime , np .datetime64 )):
878- result = self ._add_datetimelike_scalar (other )
879- elif lib .is_integer (other ):
880- # This check must come after the check for np.timedelta64
881- # as is_integer returns True for these
882- maybe_integer_op_deprecated (self )
883- result = self ._time_shift (other )
884-
885- # array-like others
886- elif is_timedelta64_dtype (other ):
887- # TimedeltaIndex, ndarray[timedelta64]
888- result = self ._add_delta (other )
889- elif is_offsetlike (other ):
890- # Array/Index of DateOffset objects
891- result = self ._addsub_offset_array (other , operator .add )
892- elif is_datetime64_dtype (other ) or is_datetime64tz_dtype (other ):
893- # DatetimeIndex, ndarray[datetime64]
894- return self ._add_datetime_arraylike (other )
895- elif is_integer_dtype (other ):
896- maybe_integer_op_deprecated (self )
897- result = self ._addsub_int_array (other , operator .add )
898- elif is_float_dtype (other ):
899- # Explicitly catch invalid dtypes
900- raise TypeError ("cannot add {dtype}-dtype to {cls}"
901- .format (dtype = other .dtype ,
902- cls = type (self ).__name__ ))
903- elif is_period_dtype (other ):
904- # if self is a TimedeltaArray and other is a PeriodArray with
905- # a timedelta-like (i.e. Tick) freq, this operation is valid.
906- # Defer to the PeriodArray implementation.
907- # In remaining cases, this will end up raising TypeError.
908- return NotImplemented
909- elif is_extension_array_dtype (other ):
910- # Categorical op will raise; defer explicitly
911- return NotImplemented
912- else : # pragma: no cover
913- return NotImplemented
914-
915- if is_timedelta64_dtype (result ) and isinstance (result , np .ndarray ):
916- from pandas .core .arrays import TimedeltaArrayMixin
917- # TODO: infer freq?
918- return TimedeltaArrayMixin (result )
919- return result
862+ # scalar others
863+ elif other is NaT :
864+ result = self ._add_nat ()
865+ elif isinstance (other , (Tick , timedelta , np .timedelta64 )):
866+ result = self ._add_delta (other )
867+ elif isinstance (other , DateOffset ):
868+ # specifically _not_ a Tick
869+ result = self ._add_offset (other )
870+ elif isinstance (other , (datetime , np .datetime64 )):
871+ result = self ._add_datetimelike_scalar (other )
872+ elif lib .is_integer (other ):
873+ # This check must come after the check for np.timedelta64
874+ # as is_integer returns True for these
875+ maybe_integer_op_deprecated (self )
876+ result = self ._time_shift (other )
877+
878+ # array-like others
879+ elif is_timedelta64_dtype (other ):
880+ # TimedeltaIndex, ndarray[timedelta64]
881+ result = self ._add_delta (other )
882+ elif is_offsetlike (other ):
883+ # Array/Index of DateOffset objects
884+ result = self ._addsub_offset_array (other , operator .add )
885+ elif is_datetime64_dtype (other ) or is_datetime64tz_dtype (other ):
886+ # DatetimeIndex, ndarray[datetime64]
887+ return self ._add_datetime_arraylike (other )
888+ elif is_integer_dtype (other ):
889+ maybe_integer_op_deprecated (self )
890+ result = self ._addsub_int_array (other , operator .add )
891+ elif is_float_dtype (other ):
892+ # Explicitly catch invalid dtypes
893+ raise TypeError ("cannot add {dtype}-dtype to {cls}"
894+ .format (dtype = other .dtype ,
895+ cls = type (self ).__name__ ))
896+ elif is_period_dtype (other ):
897+ # if self is a TimedeltaArray and other is a PeriodArray with
898+ # a timedelta-like (i.e. Tick) freq, this operation is valid.
899+ # Defer to the PeriodArray implementation.
900+ # In remaining cases, this will end up raising TypeError.
901+ return NotImplemented
902+ elif is_extension_array_dtype (other ):
903+ # Categorical op will raise; defer explicitly
904+ return NotImplemented
905+ else : # pragma: no cover
906+ return NotImplemented
920907
921- cls .__add__ = __add__
922-
923- def __radd__ (self , other ):
924- # alias for __add__
925- return self .__add__ (other )
926- cls .__radd__ = __radd__
927-
928- def __sub__ (self , other ):
929- other = lib .item_from_zerodim (other )
930- if isinstance (other , (ABCSeries , ABCDataFrame )):
931- return NotImplemented
932-
933- # scalar others
934- elif other is NaT :
935- result = self ._sub_nat ()
936- elif isinstance (other , (Tick , timedelta , np .timedelta64 )):
937- result = self ._add_delta (- other )
938- elif isinstance (other , DateOffset ):
939- # specifically _not_ a Tick
940- result = self ._add_offset (- other )
941- elif isinstance (other , (datetime , np .datetime64 )):
942- result = self ._sub_datetimelike_scalar (other )
943- elif lib .is_integer (other ):
944- # This check must come after the check for np.timedelta64
945- # as is_integer returns True for these
946- maybe_integer_op_deprecated (self )
947- result = self ._time_shift (- other )
948-
949- elif isinstance (other , Period ):
950- result = self ._sub_period (other )
951-
952- # array-like others
953- elif is_timedelta64_dtype (other ):
954- # TimedeltaIndex, ndarray[timedelta64]
955- result = self ._add_delta (- other )
956- elif is_offsetlike (other ):
957- # Array/Index of DateOffset objects
958- result = self ._addsub_offset_array (other , operator .sub )
959- elif is_datetime64_dtype (other ) or is_datetime64tz_dtype (other ):
960- # DatetimeIndex, ndarray[datetime64]
961- result = self ._sub_datetime_arraylike (other )
962- elif is_period_dtype (other ):
963- # PeriodIndex
964- result = self ._sub_period_array (other )
965- elif is_integer_dtype (other ):
966- maybe_integer_op_deprecated (self )
967- result = self ._addsub_int_array (other , operator .sub )
968- elif isinstance (other , ABCIndexClass ):
969- raise TypeError ("cannot subtract {cls} and {typ}"
970- .format (cls = type (self ).__name__ ,
971- typ = type (other ).__name__ ))
972- elif is_float_dtype (other ):
973- # Explicitly catch invalid dtypes
974- raise TypeError ("cannot subtract {dtype}-dtype from {cls}"
975- .format (dtype = other .dtype ,
976- cls = type (self ).__name__ ))
977- elif is_extension_array_dtype (other ):
978- # Categorical op will raise; defer explicitly
979- return NotImplemented
980- else : # pragma: no cover
981- return NotImplemented
982-
983- if is_timedelta64_dtype (result ) and isinstance (result , np .ndarray ):
984- from pandas .core .arrays import TimedeltaArrayMixin
985- # TODO: infer freq?
986- return TimedeltaArrayMixin (result )
987- return result
908+ if is_timedelta64_dtype (result ) and isinstance (result , np .ndarray ):
909+ from pandas .core .arrays import TimedeltaArrayMixin
910+ # TODO: infer freq?
911+ return TimedeltaArrayMixin (result )
912+ return result
913+
914+ def __radd__ (self , other ):
915+ # alias for __add__
916+ return self .__add__ (other )
917+
918+ def __sub__ (self , other ):
919+ other = lib .item_from_zerodim (other )
920+ if isinstance (other , (ABCSeries , ABCDataFrame )):
921+ return NotImplemented
922+
923+ # scalar others
924+ elif other is NaT :
925+ result = self ._sub_nat ()
926+ elif isinstance (other , (Tick , timedelta , np .timedelta64 )):
927+ result = self ._add_delta (- other )
928+ elif isinstance (other , DateOffset ):
929+ # specifically _not_ a Tick
930+ result = self ._add_offset (- other )
931+ elif isinstance (other , (datetime , np .datetime64 )):
932+ result = self ._sub_datetimelike_scalar (other )
933+ elif lib .is_integer (other ):
934+ # This check must come after the check for np.timedelta64
935+ # as is_integer returns True for these
936+ maybe_integer_op_deprecated (self )
937+ result = self ._time_shift (- other )
938+
939+ elif isinstance (other , Period ):
940+ result = self ._sub_period (other )
941+
942+ # array-like others
943+ elif is_timedelta64_dtype (other ):
944+ # TimedeltaIndex, ndarray[timedelta64]
945+ result = self ._add_delta (- other )
946+ elif is_offsetlike (other ):
947+ # Array/Index of DateOffset objects
948+ result = self ._addsub_offset_array (other , operator .sub )
949+ elif is_datetime64_dtype (other ) or is_datetime64tz_dtype (other ):
950+ # DatetimeIndex, ndarray[datetime64]
951+ result = self ._sub_datetime_arraylike (other )
952+ elif is_period_dtype (other ):
953+ # PeriodIndex
954+ result = self ._sub_period_array (other )
955+ elif is_integer_dtype (other ):
956+ maybe_integer_op_deprecated (self )
957+ result = self ._addsub_int_array (other , operator .sub )
958+ elif isinstance (other , ABCIndexClass ):
959+ raise TypeError ("cannot subtract {cls} and {typ}"
960+ .format (cls = type (self ).__name__ ,
961+ typ = type (other ).__name__ ))
962+ elif is_float_dtype (other ):
963+ # Explicitly catch invalid dtypes
964+ raise TypeError ("cannot subtract {dtype}-dtype from {cls}"
965+ .format (dtype = other .dtype ,
966+ cls = type (self ).__name__ ))
967+ elif is_extension_array_dtype (other ):
968+ # Categorical op will raise; defer explicitly
969+ return NotImplemented
970+ else : # pragma: no cover
971+ return NotImplemented
972+
973+ if is_timedelta64_dtype (result ) and isinstance (result , np .ndarray ):
974+ from pandas .core .arrays import TimedeltaArrayMixin
975+ # TODO: infer freq?
976+ return TimedeltaArrayMixin (result )
977+ return result
978+
979+ def __rsub__ (self , other ):
980+ if is_datetime64_dtype (other ) and is_timedelta64_dtype (self ):
981+ # ndarray[datetime64] cannot be subtracted from self, so
982+ # we need to wrap in DatetimeArray/Index and flip the operation
983+ if not isinstance (other , DatetimeLikeArrayMixin ):
984+ # Avoid down-casting DatetimeIndex
985+ from pandas .core .arrays import DatetimeArrayMixin
986+ other = DatetimeArrayMixin (other )
987+ return other - self
988+ elif (is_datetime64_any_dtype (self ) and hasattr (other , 'dtype' ) and
989+ not is_datetime64_any_dtype (other )):
990+ # GH#19959 datetime - datetime is well-defined as timedelta,
991+ # but any other type - datetime is not well-defined.
992+ raise TypeError ("cannot subtract {cls} from {typ}"
993+ .format (cls = type (self ).__name__ ,
994+ typ = type (other ).__name__ ))
995+ elif is_period_dtype (self ) and is_timedelta64_dtype (other ):
996+ # TODO: Can we simplify/generalize these cases at all?
997+ raise TypeError ("cannot subtract {cls} from {dtype}"
998+ .format (cls = type (self ).__name__ ,
999+ dtype = other .dtype ))
1000+ return - (self - other )
1001+
1002+ # FIXME: DTA/TDA/PA inplace methods should actually be inplace, GH#24115
1003+ def __iadd__ (self , other ):
1004+ # alias for __add__
1005+ return self .__add__ (other )
9881006
989- cls .__sub__ = __sub__
990-
991- def __rsub__ (self , other ):
992- if is_datetime64_dtype (other ) and is_timedelta64_dtype (self ):
993- # ndarray[datetime64] cannot be subtracted from self, so
994- # we need to wrap in DatetimeArray/Index and flip the operation
995- if not isinstance (other , DatetimeLikeArrayMixin ):
996- # Avoid down-casting DatetimeIndex
997- from pandas .core .arrays import DatetimeArrayMixin
998- other = DatetimeArrayMixin (other )
999- return other - self
1000- elif (is_datetime64_any_dtype (self ) and hasattr (other , 'dtype' ) and
1001- not is_datetime64_any_dtype (other )):
1002- # GH#19959 datetime - datetime is well-defined as timedelta,
1003- # but any other type - datetime is not well-defined.
1004- raise TypeError ("cannot subtract {cls} from {typ}"
1005- .format (cls = type (self ).__name__ ,
1006- typ = type (other ).__name__ ))
1007- elif is_period_dtype (self ) and is_timedelta64_dtype (other ):
1008- # TODO: Can we simplify/generalize these cases at all?
1009- raise TypeError ("cannot subtract {cls} from {dtype}"
1010- .format (cls = type (self ).__name__ ,
1011- dtype = other .dtype ))
1012- return - (self - other )
1013- cls .__rsub__ = __rsub__
1014-
1015- def __iadd__ (self , other ):
1016- # alias for __add__
1017- return self .__add__ (other )
1018- cls .__iadd__ = __iadd__
1019-
1020- def __isub__ (self , other ):
1021- # alias for __sub__
1022- return self .__sub__ (other )
1023- cls .__isub__ = __isub__
1007+ def __isub__ (self , other ):
1008+ # alias for __sub__
1009+ return self .__sub__ (other )
10241010
10251011 # --------------------------------------------------------------
10261012 # Comparison Methods
0 commit comments