Skip to content

Commit 2958ff7

Browse files
jbrockmendelyehoshuadimarsky
authored andcommitted
REF: remove ensure_datetime64ns, ensure_timedelta64ns (pandas-dev#47219)
1 parent 69945d1 commit 2958ff7

File tree

10 files changed

+23
-68
lines changed

10 files changed

+23
-68
lines changed

pandas/_libs/tslibs/conversion.pyi

-10
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,7 @@ from pandas._typing import npt
1010
DT64NS_DTYPE: np.dtype
1111
TD64NS_DTYPE: np.dtype
1212

13-
class OutOfBoundsTimedelta(ValueError): ...
14-
1513
def precision_from_unit(
1614
unit: str,
1715
) -> tuple[int, int]: ... # (int64_t, _)
18-
def ensure_datetime64ns(
19-
arr: np.ndarray, # np.ndarray[datetime64[ANY]]
20-
copy: bool = ...,
21-
) -> np.ndarray: ... # np.ndarray[datetime64ns]
22-
def ensure_timedelta64ns(
23-
arr: np.ndarray, # np.ndarray[timedelta64[ANY]]
24-
copy: bool = ...,
25-
) -> np.ndarray: ... # np.ndarray[timedelta64ns]
2616
def localize_pydatetime(dt: datetime, tz: tzinfo | None) -> datetime: ...

pandas/_libs/tslibs/conversion.pyx

-39
Original file line numberDiff line numberDiff line change
@@ -193,45 +193,6 @@ cdef inline int64_t get_datetime64_nanos(object val) except? -1:
193193
return ival
194194

195195

196-
def ensure_datetime64ns(arr: ndarray, copy: bool = True):
197-
"""
198-
Ensure a np.datetime64 array has dtype specifically 'datetime64[ns]'
199-
200-
Parameters
201-
----------
202-
arr : ndarray
203-
copy : bool, default True
204-
205-
Returns
206-
-------
207-
ndarray with dtype datetime64[ns]
208-
"""
209-
if (<object>arr).dtype.byteorder == ">":
210-
# GH#29684 we incorrectly get OutOfBoundsDatetime if we dont swap
211-
dtype = arr.dtype
212-
arr = arr.astype(dtype.newbyteorder("<"))
213-
214-
return astype_overflowsafe(arr, DT64NS_DTYPE, copy=copy)
215-
216-
217-
def ensure_timedelta64ns(arr: ndarray, copy: bool = True):
218-
"""
219-
Ensure a np.timedelta64 array has dtype specifically 'timedelta64[ns]'
220-
221-
Parameters
222-
----------
223-
arr : ndarray
224-
copy : bool, default True
225-
226-
Returns
227-
-------
228-
ndarray[timedelta64[ns]]
229-
"""
230-
assert arr.dtype.kind == "m", arr.dtype
231-
232-
return astype_overflowsafe(arr, dtype=TD64NS_DTYPE, copy=copy)
233-
234-
235196
# ----------------------------------------------------------------------
236197
# _TSObject Conversion
237198

pandas/_libs/tslibs/np_datetime.pyx

+4
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,10 @@ cpdef ndarray astype_overflowsafe(
319319
"datetime64/timedelta64 values and dtype must have a unit specified"
320320
)
321321

322+
if (<object>values).dtype.byteorder == ">":
323+
# GH#29684 we incorrectly get OutOfBoundsDatetime if we dont swap
324+
values = values.astype(values.dtype.newbyteorder("<"))
325+
322326
if from_unit == to_unit:
323327
# Check this before allocating result for perf, might save some memory
324328
if copy:

pandas/_libs/tslibs/period.pyx

+3-2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ from pandas._libs.tslibs.np_datetime cimport (
4747
NPY_DATETIMEUNIT,
4848
NPY_FR_D,
4949
NPY_FR_us,
50+
astype_overflowsafe,
5051
check_dts_bounds,
5152
dt64_to_dtstruct,
5253
dtstruct_to_dt64,
@@ -71,7 +72,7 @@ from pandas._libs.tslibs.timedeltas cimport (
7172
is_any_td_scalar,
7273
)
7374

74-
from pandas._libs.tslibs.conversion import ensure_datetime64ns
75+
from pandas._libs.tslibs.conversion import DT64NS_DTYPE
7576

7677
from pandas._libs.tslibs.dtypes cimport (
7778
FR_ANN,
@@ -981,7 +982,7 @@ def periodarr_to_dt64arr(const int64_t[:] periodarr, int freq):
981982
dta = periodarr.base.view("M8[h]")
982983
elif freq == FR_DAY:
983984
dta = periodarr.base.view("M8[D]")
984-
return ensure_datetime64ns(dta)
985+
return astype_overflowsafe(dta, dtype=DT64NS_DTYPE)
985986

986987

987988
cdef void get_asfreq_info(int from_freq, int to_freq,

pandas/core/arrays/datetimes.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
NaTType,
2626
Resolution,
2727
Timestamp,
28-
conversion,
28+
astype_overflowsafe,
2929
fields,
3030
get_resolution,
3131
iNaT,
@@ -2169,7 +2169,7 @@ def _sequence_to_dt64ns(
21692169
# tz-naive DatetimeArray or ndarray[datetime64]
21702170
data = getattr(data, "_ndarray", data)
21712171
if data.dtype != DT64NS_DTYPE:
2172-
data = conversion.ensure_datetime64ns(data)
2172+
data = astype_overflowsafe(data, dtype=DT64NS_DTYPE)
21732173
copy = False
21742174

21752175
if tz is not None:

pandas/core/arrays/timedeltas.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,11 @@
2121
Tick,
2222
Timedelta,
2323
Timestamp,
24+
astype_overflowsafe,
2425
iNaT,
2526
to_offset,
2627
)
27-
from pandas._libs.tslibs.conversion import (
28-
ensure_timedelta64ns,
29-
precision_from_unit,
30-
)
28+
from pandas._libs.tslibs.conversion import precision_from_unit
3129
from pandas._libs.tslibs.fields import get_timedelta_field
3230
from pandas._libs.tslibs.timedeltas import (
3331
array_to_timedelta64,
@@ -1044,7 +1042,7 @@ def sequence_to_td64ns(
10441042
elif is_timedelta64_dtype(data.dtype):
10451043
if data.dtype != TD64NS_DTYPE:
10461044
# non-nano unit
1047-
data = ensure_timedelta64ns(data)
1045+
data = astype_overflowsafe(data, dtype=TD64NS_DTYPE)
10481046
copy = False
10491047

10501048
else:
@@ -1086,7 +1084,7 @@ def ints_to_td64ns(data, unit="ns"):
10861084
dtype_str = f"timedelta64[{unit}]"
10871085
data = data.view(dtype_str)
10881086

1089-
data = ensure_timedelta64ns(data)
1087+
data = astype_overflowsafe(data, dtype=TD64NS_DTYPE)
10901088

10911089
# the astype conversion makes a copy, so we can avoid re-copying later
10921090
copy_made = True

pandas/core/dtypes/cast.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
OutOfBoundsTimedelta,
3131
Timedelta,
3232
Timestamp,
33-
conversion,
33+
astype_overflowsafe,
3434
)
3535
from pandas._libs.tslibs.timedeltas import array_to_timedelta64
3636
from pandas._typing import (
@@ -1419,10 +1419,10 @@ def sanitize_to_nanoseconds(values: np.ndarray, copy: bool = False) -> np.ndarra
14191419
"""
14201420
dtype = values.dtype
14211421
if dtype.kind == "M" and dtype != DT64NS_DTYPE:
1422-
values = conversion.ensure_datetime64ns(values)
1422+
values = astype_overflowsafe(values, dtype=DT64NS_DTYPE)
14231423

14241424
elif dtype.kind == "m" and dtype != TD64NS_DTYPE:
1425-
values = conversion.ensure_timedelta64ns(values)
1425+
values = astype_overflowsafe(values, dtype=TD64NS_DTYPE)
14261426

14271427
elif copy:
14281428
values = values.copy()

pandas/tests/arrays/categorical/test_constructors.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ def test_from_sequence_copy(self):
751751

752752
@pytest.mark.xfail(
753753
not IS64 or is_platform_windows(),
754-
reason="Incorrectly raising in ensure_datetime64ns",
754+
reason="Incorrectly raising in astype_overflowsafe",
755755
)
756756
def test_constructor_datetime64_non_nano(self):
757757
categories = np.arange(10).view("M8[D]")

pandas/tests/indexes/datetimes/test_constructors.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from pandas._libs.tslibs import (
1515
OutOfBoundsDatetime,
16-
conversion,
16+
astype_overflowsafe,
1717
)
1818
from pandas.compat import PY39
1919

@@ -975,7 +975,7 @@ def test_index_cast_datetime64_other_units(self):
975975
arr = np.arange(0, 100, 10, dtype=np.int64).view("M8[D]")
976976
idx = Index(arr)
977977

978-
assert (idx.values == conversion.ensure_datetime64ns(arr)).all()
978+
assert (idx.values == astype_overflowsafe(arr, dtype=np.dtype("M8[ns]"))).all()
979979

980980
def test_constructor_int64_nocopy(self):
981981
# GH#1624

pandas/tests/tslibs/test_conversion.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from pandas._libs.tslibs import (
88
OutOfBoundsTimedelta,
9+
astype_overflowsafe,
910
conversion,
1011
iNaT,
1112
timezones,
@@ -106,7 +107,7 @@ def test_tz_convert_readonly():
106107
@pytest.mark.parametrize("dtype", ["M8[ns]", "M8[s]"])
107108
def test_length_zero_copy(dtype, copy):
108109
arr = np.array([], dtype=dtype)
109-
result = conversion.ensure_datetime64ns(arr, copy=copy)
110+
result = astype_overflowsafe(arr, copy=copy, dtype=np.dtype("M8[ns]"))
110111
if copy:
111112
assert not np.shares_memory(result, arr)
112113
else:
@@ -119,7 +120,7 @@ def test_length_zero_copy(dtype, copy):
119120
def test_ensure_datetime64ns_bigendian():
120121
# GH#29684
121122
arr = np.array([np.datetime64(1, "ms")], dtype=">M8[ms]")
122-
result = conversion.ensure_datetime64ns(arr)
123+
result = astype_overflowsafe(arr, dtype=np.dtype("M8[ns]"))
123124

124125
expected = np.array([np.datetime64(1, "ms")], dtype="M8[ns]")
125126
tm.assert_numpy_array_equal(result, expected)
@@ -129,7 +130,7 @@ def test_ensure_timedelta64ns_overflows():
129130
arr = np.arange(10).astype("m8[Y]") * 100
130131
msg = r"Cannot convert 300 years to timedelta64\[ns\] without overflow"
131132
with pytest.raises(OutOfBoundsTimedelta, match=msg):
132-
conversion.ensure_timedelta64ns(arr)
133+
astype_overflowsafe(arr, dtype=np.dtype("m8[ns]"))
133134

134135

135136
class SubDatetime(datetime):

0 commit comments

Comments
 (0)