Skip to content

Commit 1bc2741

Browse files
describe current organization, PR feedback
1 parent 4a73340 commit 1bc2741

File tree

9 files changed

+38
-124
lines changed

9 files changed

+38
-124
lines changed

pandas/_libs/ops.pxd

-4
This file was deleted.

pandas/_libs/ops.pyi

-1
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,3 @@ def maybe_convert_bool(
4848
*,
4949
convert_to_masked_nullable: Literal[True],
5050
) -> tuple[np.ndarray, np.ndarray]: ...
51-
def calc_int_int(op, left: int, right: int) -> int: ...

pandas/_libs/ops.pyx

-10
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import numpy as np
1616

1717
from numpy cimport (
1818
import_array,
19-
int64_t,
2019
ndarray,
2120
uint8_t,
2221
)
@@ -309,12 +308,3 @@ def maybe_convert_bool(ndarray[object] arr,
309308
return (arr, None)
310309
else:
311310
return (result.view(np.bool_), None)
312-
313-
314-
@cython.overflowcheck(True)
315-
cpdef int64_t calc_int_int(object op, int64_t a, int64_t b) except? -1:
316-
"""
317-
Calculate op(a, b) and return the result. Raises OverflowError if converting either
318-
operand or the result to an int64_t would overflow.
319-
"""
320-
return op(a, b)

pandas/_libs/tslibs/timedeltas.pyx

+11-22
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ import_datetime()
3131

3232

3333
cimport pandas._libs.tslibs.util as util
34-
from pandas._libs cimport ops
35-
from pandas._libs.missing cimport C_NA
3634
from pandas._libs.tslibs.base cimport ABCTimestamp
3735
from pandas._libs.tslibs.conversion cimport (
3836
cast_from_unit,
@@ -217,12 +215,11 @@ cpdef int64_t delta_to_nanoseconds(delta) except? -1:
217215
return get_timedelta64_value(ensure_td64ns(delta))
218216

219217
if PyDelta_Check(delta):
220-
microseconds = (
218+
return (
221219
delta.days * 24 * 3600 * 1_000_000
222220
+ delta.seconds * 1_000_000
223221
+ delta.microseconds
224-
)
225-
return calc_int_int(operator.mul, microseconds, 1000)
222+
) * 1000
226223

227224
raise TypeError(type(delta))
228225

@@ -245,14 +242,20 @@ cdef object ensure_td64ns(object ts):
245242
str unitstr
246243

247244
td64_unit = get_datetime64_unit(ts)
248-
if td64_unit in (NPY_DATETIMEUNIT.NPY_FR_ns, NPY_DATETIMEUNIT.NPY_FR_GENERIC):
245+
if td64_unit == NPY_DATETIMEUNIT.NPY_FR_ns or td64_unit == NPY_DATETIMEUNIT.NPY_FR_GENERIC:
249246
return ts
250247

251248
unitstr = npy_unit_to_abbrev(td64_unit)
252249
mult = precision_from_unit(unitstr)[0]
253-
ns = calc_int_int(operator.mul, get_timedelta64_value(ts), mult)
254250

255-
return np.timedelta64(ns, "ns")
251+
with cython.overflowcheck(True):
252+
try:
253+
td64_value = get_timedelta64_value(ts) * mult
254+
except OverflowError as ex:
255+
msg = f"{ts} outside allowed range [{TIMEDELTA_MIN_NS}ns, {TIMEDELTA_MAX_NS}ns]"
256+
raise OutOfBoundsTimedelta(msg) from ex
257+
258+
return np.timedelta64(td64_value, "ns")
256259

257260

258261
cdef convert_to_timedelta64(object ts, str unit):
@@ -673,18 +676,6 @@ def _op_unary_method(func, name):
673676
return f
674677

675678

676-
cdef int64_t calc_int_int(object op, object a, object b) except? -1:
677-
"""
678-
Calculate op(a, b), raising if either operand or the result cannot be safely cast
679-
to an int64_t.
680-
"""
681-
try:
682-
return ops.calc_int_int(op, a, b)
683-
except OverflowError as ex:
684-
msg = f"outside allowed range [{TIMEDELTA_MIN_NS}ns, {TIMEDELTA_MAX_NS}ns]"
685-
raise OutOfBoundsTimedelta(msg) from ex
686-
687-
688679
def _binary_op_method_timedeltalike(op, name):
689680
# define a binary operation that only works if the other argument is
690681
# timedelta like or an array of timedeltalike
@@ -907,8 +898,6 @@ cdef object create_timedelta(object value, str in_unit, NPY_DATETIMEUNIT out_res
907898

908899
if isinstance(value, _Timedelta):
909900
return value
910-
if value is C_NA:
911-
raise ValueError("Not supported")
912901

913902
try:
914903
# if unit == "ns", no need to create an m8[ns] just to read the (same) value back

pandas/tests/libs/test_ops.py

-67
This file was deleted.
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import re
2+
3+
import pytest
4+
5+
6+
@pytest.fixture(name="td_overflow_msg")
7+
def fixture_td_overflow_msg() -> str:
8+
return re.escape(
9+
"outside allowed range [-9223372036854775807ns, 9223372036854775807ns]"
10+
)

pandas/tests/scalar/timedelta/test_arithmetic.py

+7-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
"""
2-
Tests for arithmetic ops between a Timedelta scalar and another scalar, or a Timedelta
3-
scalar and a Array/Index/Series/DataFrame.
2+
Tests of binary ops between a Timedelta scalar and another scalar or a
3+
Array/Index/Series/DataFrame.
4+
5+
See test_timedelta.py, in this same directory, for tests against the rest of the public
6+
Timedelta API.
47
"""
58

69
from __future__ import annotations
@@ -26,6 +29,7 @@
2629
NaT,
2730
Timedelta,
2831
Timestamp,
32+
compat,
2933
offsets,
3034
)
3135
import pandas._testing as tm
@@ -115,13 +119,6 @@ def fixture_floor_mod_divmod_op(request):
115119
return request.param
116120

117121

118-
@pytest.fixture(name="td_overflow_msg")
119-
def fixture_td_overflow_msg() -> str:
120-
return re.escape(
121-
"outside allowed range [-9223372036854775807ns, 9223372036854775807ns]"
122-
)
123-
124-
125122
@pytest.fixture(name="invalid_op_msg")
126123
def fixture_invalid_op_msg() -> str:
127124
messages = (
@@ -447,7 +444,7 @@ def test_numeric(self, ten_days, mul_op, factor, expected, box_with_array):
447444
)
448445
tm.assert_equal(result, expected)
449446

450-
@pytest.mark.xfail(reason="no overflow check", raises=AssertionError, strict=True)
447+
@pytest.mark.xfail(compat.IS64, reason="no overflow check", raises=AssertionError)
451448
@pytest.mark.parametrize("factor", (1.01, 2), ids=("int", "float"))
452449
def test_returns_nat_if_result_overflows(self, mul_op, factor, box_with_array):
453450
numeric_box = tm.box_expected((1, factor), box_with_array, transpose=False)

pandas/tests/scalar/timedelta/test_timedelta.py

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""
2-
Most Timedelta scalar tests; See test_arithmetic for tests of binary operations with a
3-
Timedelta scalar.
2+
Tests against (most of) the public Timedelta API.
3+
4+
See test_arithmetic.py, in this same directory, for tests of binary ops between a
5+
Timedelta scalar and another scalar or a Array/Index/Series/DataFrame.
46
"""
57

68
from __future__ import annotations
@@ -12,7 +14,6 @@
1214
zip_longest,
1315
)
1416
import operator
15-
import re
1617

1718
from hypothesis import (
1819
given,
@@ -158,13 +159,6 @@ def fixture_td64_min_per_unit(request) -> tuple:
158159
return unit, TD64_MIN_PER_UNIT[unit]
159160

160161

161-
@pytest.fixture(name="td_overflow_msg")
162-
def fixture_td_overflow_msg() -> str:
163-
return re.escape(
164-
"outside allowed range [-9223372036854775807ns, 9223372036854775807ns]"
165-
)
166-
167-
168162
@pytest.fixture(name="non_nano_reso", params=(7, 8, 9))
169163
def fixture_non_nano_reso(request):
170164
"""7, 8, 9 correspond to second, millisecond, and microsecond, respectively"""

pandas/tests/tslibs/test_timedeltas.py

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
"""
2+
Tests against the for-internal-use-only functions in pandas._libs.tslibs.timedeltas.
3+
4+
For tests against the public Timedelta API, see pandas/tests/scalar/timedelta/
5+
"""
6+
17
import numpy as np
28
import pytest
39

0 commit comments

Comments
 (0)