2929 precision_from_unit ,
3030)
3131from pandas ._libs .tslibs .fields import get_timedelta_field
32+ from pandas ._libs .tslibs .np_datetime import py_get_unit_from_dtype
3233from pandas ._libs .tslibs .timedeltas import (
3334 array_to_timedelta64 ,
3435 ints_to_pytimedelta ,
4041 npt ,
4142)
4243from pandas .compat .numpy import function as nv
44+ from pandas .util ._decorators import cache_readonly
4345from pandas .util ._validators import validate_endpoints
4446
4547from pandas .core .dtypes .astype import astype_td64_unit_conversion
@@ -154,8 +156,15 @@ class TimedeltaArray(dtl.TimelikeOps):
154156 # Note: ndim must be defined to ensure NaT.__richcmp__(TimedeltaArray)
155157 # operates pointwise.
156158
159+ @cache_readonly
160+ def _reso (self ):
161+ return py_get_unit_from_dtype (self .dtype )
162+
157163 def _box_func (self , x : np .timedelta64 ) -> Timedelta | NaTType :
158- return Timedelta (x , unit = "ns" )
164+ y = x .view ("i8" )
165+ if y == NaT .value :
166+ return NaT
167+ return Timedelta ._from_value_and_reso (y , reso = self ._reso )
159168
160169 @property
161170 # error: Return type "dtype" of "dtype" incompatible with return type
@@ -174,7 +183,7 @@ def dtype(self) -> np.dtype: # type: ignore[override]
174183 -------
175184 numpy.dtype
176185 """
177- return TD64NS_DTYPE
186+ return self . _ndarray . dtype
178187
179188 # ----------------------------------------------------------------
180189 # Constructors
@@ -244,11 +253,13 @@ def __init__(
244253 def _simple_new ( # type: ignore[override]
245254 cls , values : np .ndarray , freq : BaseOffset | None = None , dtype = TD64NS_DTYPE
246255 ) -> TimedeltaArray :
247- assert dtype == TD64NS_DTYPE , dtype
256+ # Require td64 dtype, not unit-less, matching values.dtype
257+ assert isinstance (dtype , np .dtype ) and dtype .kind == "m"
258+ assert not tslibs .is_unitless (dtype )
248259 assert isinstance (values , np .ndarray ), type (values )
249- assert values . dtype == TD64NS_DTYPE
260+ assert dtype == values . dtype
250261
251- result = super ()._simple_new (values = values , dtype = TD64NS_DTYPE )
262+ result = super ()._simple_new (values = values , dtype = dtype )
252263 result ._freq = freq
253264 return result
254265
@@ -262,7 +273,7 @@ def _from_sequence(
262273 data , inferred_freq = sequence_to_td64ns (data , copy = copy , unit = None )
263274 freq , _ = dtl .validate_inferred_freq (None , inferred_freq , False )
264275
265- return cls ._simple_new (data , freq = freq )
276+ return cls ._simple_new (data , dtype = data . dtype , freq = freq )
266277
267278 @classmethod
268279 def _from_sequence_not_strict (
@@ -286,7 +297,7 @@ def _from_sequence_not_strict(
286297 if explicit_none :
287298 freq = None
288299
289- result = cls ._simple_new (data , freq = freq )
300+ result = cls ._simple_new (data , dtype = data . dtype , freq = freq )
290301
291302 if inferred_freq is None and freq is not None :
292303 # this condition precludes `freq_infer`
@@ -330,7 +341,8 @@ def _generate_range(cls, start, end, periods, freq, closed=None):
330341 if not right_closed :
331342 index = index [:- 1 ]
332343
333- return cls ._simple_new (index .view ("m8[ns]" ), freq = freq )
344+ td64values = index .view ("m8[ns]" )
345+ return cls ._simple_new (td64values , dtype = td64values .dtype , freq = freq )
334346
335347 # ----------------------------------------------------------------
336348 # DatetimeLike Interface
0 commit comments