File tree Expand file tree Collapse file tree 5 files changed +32
-19
lines changed Expand file tree Collapse file tree 5 files changed +32
-19
lines changed Original file line number Diff line number Diff line change @@ -73,7 +73,6 @@ def array_to_timedelta64(
73
73
) -> np .ndarray : ... # np.ndarray[m8ns]
74
74
def parse_timedelta_unit (unit : str | None ) -> UnitChoices : ...
75
75
def delta_to_nanoseconds (delta : np .timedelta64 | timedelta | Tick ) -> int : ...
76
- def calculate (op , left : int , right : int ) -> int : ...
77
76
78
77
class Timedelta (timedelta ):
79
78
min : ClassVar [Timedelta ]
Original file line number Diff line number Diff line change @@ -684,13 +684,23 @@ def _op_unary_method(func, name):
684
684
return f
685
685
686
686
687
- cpdef int64_t calculate(object op, int64_t a, int64_t b) except ? - 1 :
687
+ @ cython.overflowcheck (True )
688
+ cpdef int64_t _calculate(object op, int64_t a, int64_t b) except ? - 1 :
689
+ """
690
+ Calculate op(a, b) and return the result. Raises OverflowError if either operand
691
+ or the result would overflow on conversion to int64_t.
692
+ """
693
+ return op(a, b)
694
+
695
+
696
+ cpdef int64_t calculate(object op, object a, object b) except ? - 1 :
688
697
"""
689
- Calculate op(a, b) and return the result, or raise if the operation would overflow .
698
+ As above, but raises an OutOfBoundsTimedelta .
690
699
"""
700
+ cdef int64_t int_a, int_b
701
+
691
702
try :
692
- with cython.overflowcheck(True ):
693
- return op(a, b)
703
+ return _calculate(op, a, b)
694
704
except OverflowError as ex:
695
705
msg = f" outside allowed range [{TIMEDELTA_MIN_NS}ns, {TIMEDELTA_MAX_NS}ns]"
696
706
raise OutOfBoundsTimedelta(msg) from ex
Original file line number Diff line number Diff line change @@ -86,7 +86,7 @@ from pandas._libs.tslibs.np_datetime cimport (
86
86
pydatetime_to_dt64,
87
87
)
88
88
89
- from pandas._libs.tslibs.np_datetime import OutOfBoundsDatetime
89
+ from pandas._libs.tslibs.np_datetime import OutOfBoundsDatetime, OutOfBoundsTimedelta
90
90
91
91
from pandas._libs.tslibs.offsets cimport (
92
92
BaseOffset,
@@ -431,14 +431,13 @@ cdef class _Timestamp(ABCTimestamp):
431
431
# Timedelta
432
432
try :
433
433
return Timedelta(self .value - other.value)
434
- except (OverflowError , OutOfBoundsDatetime) as err:
435
- if isinstance (other, _Timestamp):
436
- if both_timestamps:
437
- raise OutOfBoundsDatetime(
438
- " Result is too large for pandas.Timedelta. Convert inputs "
439
- " to datetime.datetime with 'Timestamp.to_pydatetime()' "
440
- " before subtracting."
441
- ) from err
434
+ except OutOfBoundsTimedelta as err:
435
+ if both_timestamps:
436
+ raise OutOfBoundsTimedelta(
437
+ " Result is too large for pandas.Timedelta. Convert inputs "
438
+ " to datetime.datetime with 'Timestamp.to_pydatetime()' "
439
+ " before subtracting."
440
+ ) from err
442
441
# We get here in stata tests, fall back to stdlib datetime
443
442
# method and return stdlib timedelta object
444
443
pass
File renamed without changes.
Original file line number Diff line number Diff line change @@ -72,17 +72,22 @@ def test_overflow_offset_raises(self):
72
72
with pytest .raises (OverflowError , match = lmsg ):
73
73
stamp - offset_overflow
74
74
75
- def test_overflow_timestamp_raises (self ):
75
+ def test_sub_can_return_stdlib_timedelta_to_avoid_overflow (self , timedelta_overflow ):
76
76
# https://github.com/pandas-dev/pandas/issues/31774
77
- msg = "Result is too large"
77
+ msg = "Result is too large for pandas.Timedelta "
78
78
a = Timestamp ("2101-01-01 00:00:00" )
79
79
b = Timestamp ("1688-01-01 00:00:00" )
80
80
81
- with pytest .raises (OutOfBoundsDatetime , match = msg ):
81
+ with pytest .raises (timedelta_overflow [ "expected_exception" ] , match = msg ):
82
82
a - b
83
83
84
- # but we're OK for timestamp and datetime.datetime
85
- assert (a - b .to_pydatetime ()) == (a .to_pydatetime () - b )
84
+ # but we're OK for Timestamp and datetime.datetime
85
+ r0 = a - b .to_pydatetime ()
86
+ r1 = a .to_pydatetime () - b
87
+ assert r0 == r1
88
+ assert isinstance (r0 , timedelta )
89
+ assert isinstance (r1 , timedelta )
90
+
86
91
87
92
def test_delta_preserve_nanos (self ):
88
93
val = Timestamp (1337299200000000123 )
You can’t perform that action at this time.
0 commit comments