|
import re |
|
|
|
import numpy as np |
|
import pytest |
|
|
|
from pandas._libs.tslibs.timedeltas import ( |
|
array_to_timedelta64, |
|
delta_to_nanoseconds, |
|
ints_to_pytimedelta, |
|
) |
|
|
|
from pandas import ( |
|
Timedelta, |
|
offsets, |
|
) |
|
import pandas._testing as tm |
|
|
|
|
|
@pytest.mark.parametrize( |
|
"obj,expected", |
|
[ |
|
(np.timedelta64(14, "D"), 14 * 24 * 3600 * 1e9), |
|
(Timedelta(minutes=-7), -7 * 60 * 1e9), |
|
(Timedelta(minutes=-7).to_pytimedelta(), -7 * 60 * 1e9), |
|
(Timedelta(seconds=1234e-9), 1234), |
|
( |
|
Timedelta(seconds=1e-9, milliseconds=1e-5, microseconds=1e-1), |
|
111, |
|
), |
|
( |
|
Timedelta(days=1, seconds=1e-9, milliseconds=1e-5, microseconds=1e-1), |
|
24 * 3600e9 + 111, |
|
), |
|
(offsets.Nano(125), 125), |
|
], |
|
) |
|
def test_delta_to_nanoseconds(obj, expected): |
|
result = delta_to_nanoseconds(obj) |
|
assert result == expected |
|
|
|
|
|
def test_delta_to_nanoseconds_error(): |
|
obj = np.array([123456789], dtype="m8[ns]") |
|
|
|
with pytest.raises(TypeError, match="<class 'numpy.ndarray'>"): |
|
delta_to_nanoseconds(obj) |
|
|
|
with pytest.raises(TypeError, match="float"): |
|
delta_to_nanoseconds(1.5) |
|
with pytest.raises(TypeError, match="int"): |
|
delta_to_nanoseconds(1) |
|
with pytest.raises(TypeError, match="int"): |
|
delta_to_nanoseconds(np.int64(2)) |
|
with pytest.raises(TypeError, match="int"): |
|
delta_to_nanoseconds(np.int32(3)) |
|
|
|
|
|
def test_delta_to_nanoseconds_td64_MY_raises(): |
|
msg = ( |
|
"delta_to_nanoseconds does not support Y or M units, " |
|
"as their duration in nanoseconds is ambiguous" |
|
) |
|
|
|
td = np.timedelta64(1234, "Y") |
|
|
|
with pytest.raises(ValueError, match=msg): |
|
delta_to_nanoseconds(td) |
|
|
|
td = np.timedelta64(1234, "M") |
|
|
|
with pytest.raises(ValueError, match=msg): |
|
delta_to_nanoseconds(td) |
|
|
|
|
|
@pytest.mark.parametrize("unit", ["Y", "M"]) |
|
def test_unsupported_td64_unit_raises(unit): |
|
|
|
with pytest.raises( |
|
ValueError, |
|
match=f"Unit {unit} is not supported. " |
|
"Only unambiguous timedelta values durations are supported. " |
|
"Allowed units are 'W', 'D', 'h', 'm', 's', 'ms', 'us', 'ns'", |
|
): |
|
Timedelta(np.timedelta64(1, unit)) |
|
|
|
|
|
def test_huge_nanoseconds_overflow(): |
|
|
|
assert delta_to_nanoseconds(Timedelta(1e10)) == 1e10 |
|
assert delta_to_nanoseconds(Timedelta(nanoseconds=1e10)) == 1e10 |
|
|
|
|
|
@pytest.mark.parametrize( |
|
"kwargs", [{"Seconds": 1}, {"seconds": 1, "Nanoseconds": 1}, {"Foo": 2}] |
|
) |
|
def test_kwarg_assertion(kwargs): |
|
err_message = ( |
|
"cannot construct a Timedelta from the passed arguments, " |
|
"allowed keywords are " |
|
"[weeks, days, hours, minutes, seconds, " |
|
"milliseconds, microseconds, nanoseconds]" |
|
) |
|
|
|
with pytest.raises(ValueError, match=re.escape(err_message)): |
|
Timedelta(**kwargs) |
|
|
|
|
|
class TestArrayToTimedelta64: |
|
def test_array_to_timedelta64_string_with_unit_2d_raises(self): |
|
|
|
|
|
values = np.array([["1", 2], [3, "4"]], dtype=object) |
|
with pytest.raises(ValueError, match="unit must not be specified"): |
|
array_to_timedelta64(values, unit="s") |
|
|
|
def test_array_to_timedelta64_non_object_raises(self): |
|
|
|
values = np.arange(5) |
|
|
|
msg = "'values' must have object dtype" |
|
with pytest.raises(TypeError, match=msg): |
|
array_to_timedelta64(values) |
|
|
|
|
|
@pytest.mark.parametrize("unit", ["s", "ms", "us"]) |
|
def test_ints_to_pytimedelta(unit): |
|
|
|
arr = np.arange(6, dtype=np.int64).view(f"m8[{unit}]") |
|
|
|
res = ints_to_pytimedelta(arr, box=False) |
|
|
|
|
|
expected = arr.astype(object) |
|
tm.assert_numpy_array_equal(res, expected) |
|
|
|
res = ints_to_pytimedelta(arr, box=True) |
|
expected = np.array([Timedelta(x) for x in arr], dtype=object) |
|
tm.assert_numpy_array_equal(res, expected) |
|
|
|
|
|
@pytest.mark.parametrize("unit", ["Y", "M", "ps", "fs", "as"]) |
|
def test_ints_to_pytimedelta_unsupported(unit): |
|
arr = np.arange(6, dtype=np.int64).view(f"m8[{unit}]") |
|
|
|
with pytest.raises(NotImplementedError, match=r"\d{1,2}"): |
|
ints_to_pytimedelta(arr, box=False) |
|
msg = "Only resolutions 's', 'ms', 'us', 'ns' are supported" |
|
with pytest.raises(NotImplementedError, match=msg): |
|
ints_to_pytimedelta(arr, box=True) |
|
|