Skip to content

Commit b74bf14

Browse files
authored
REF: simplify maybe_infer_to_datetimelike (#49344)
* REF: simplify maybe_infer_to_datetimelike * simplify sequence_to_datetimes
1 parent 6b4fa02 commit b74bf14

File tree

2 files changed

+20
-31
lines changed

2 files changed

+20
-31
lines changed

pandas/core/arrays/datetimes.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1985,14 +1985,13 @@ def std(
19851985
# Constructor Helpers
19861986

19871987

1988-
def sequence_to_datetimes(data, require_iso8601: bool = False) -> DatetimeArray:
1988+
def sequence_to_datetimes(data) -> DatetimeArray:
19891989
"""
19901990
Parse/convert the passed data to either DatetimeArray or np.ndarray[object].
19911991
"""
19921992
result, tz, freq = _sequence_to_dt64ns(
19931993
data,
19941994
allow_mixed=True,
1995-
require_iso8601=require_iso8601,
19961995
)
19971996

19981997
unit = np.datetime_data(result.dtype)[0]

pandas/core/dtypes/cast.py

+19-29
Original file line numberDiff line numberDiff line change
@@ -1232,22 +1232,20 @@ def maybe_infer_to_datetimelike(
12321232
if not len(v):
12331233
return value
12341234

1235-
def try_datetime(v: np.ndarray) -> ArrayLike:
1235+
def try_datetime(v: np.ndarray) -> np.ndarray | DatetimeArray:
12361236
# Coerce to datetime64, datetime64tz, or in corner cases
12371237
# object[datetimes]
12381238
from pandas.core.arrays.datetimes import sequence_to_datetimes
12391239

12401240
try:
1241-
# GH#19671 we pass require_iso8601 to be relatively strict
1242-
# when parsing strings.
1243-
dta = sequence_to_datetimes(v, require_iso8601=True)
1244-
except (ValueError, TypeError):
1245-
# e.g. <class 'numpy.timedelta64'> is not convertible to datetime
1246-
return v.reshape(shape)
1247-
else:
1241+
dta = sequence_to_datetimes(v)
1242+
except (ValueError, OutOfBoundsDatetime):
1243+
# ValueError for e.g. mixed tzs
12481244
# GH#19761 we may have mixed timezones, in which cast 'dta' is
12491245
# an ndarray[object]. Only 1 test
12501246
# relies on this behavior, see GH#40111
1247+
return v.reshape(shape)
1248+
else:
12511249
return dta.reshape(shape)
12521250

12531251
def try_timedelta(v: np.ndarray) -> np.ndarray:
@@ -1259,12 +1257,14 @@ def try_timedelta(v: np.ndarray) -> np.ndarray:
12591257
# `np.asarray(to_timedelta(v))`, but using a lower-level API that
12601258
# does not require a circular import.
12611259
td_values = array_to_timedelta64(v).view("m8[ns]")
1262-
except (ValueError, OverflowError):
1260+
except OutOfBoundsTimedelta:
12631261
return v.reshape(shape)
12641262
else:
12651263
return td_values.reshape(shape)
12661264

1267-
# TODO: can we just do lib.maybe_convert_objects for this entire function?
1265+
# TODO: this is _almost_ equivalent to lib.maybe_convert_objects,
1266+
# the main differences are described in GH#49340 and GH#49341
1267+
# and maybe_convert_objects doesn't catch OutOfBoundsDatetime
12681268
inferred_type = lib.infer_datetimelike_array(ensure_object(v))
12691269

12701270
if inferred_type in ["period", "interval"]:
@@ -1276,31 +1276,21 @@ def try_timedelta(v: np.ndarray) -> np.ndarray:
12761276
)
12771277

12781278
if inferred_type == "datetime":
1279-
# error: Incompatible types in assignment (expression has type "ExtensionArray",
1280-
# variable has type "Union[ndarray, List[Any]]")
1279+
# Incompatible types in assignment (expression has type
1280+
# "Union[ndarray[Any, Any], DatetimeArray]", variable has type
1281+
# "ndarray[Any, Any]")
12811282
value = try_datetime(v) # type: ignore[assignment]
12821283
elif inferred_type == "timedelta":
12831284
value = try_timedelta(v)
12841285
elif inferred_type == "nat":
1286+
# if all NaT, return as datetime
12851287
# only reached if we have at least 1 NaT and the rest (NaT or None or np.nan)
12861288

1287-
# if all NaT, return as datetime
1288-
if isna(v).all():
1289-
# error: Incompatible types in assignment (expression has type
1290-
# "ExtensionArray", variable has type "Union[ndarray, List[Any]]")
1291-
value = try_datetime(v) # type: ignore[assignment]
1292-
else:
1293-
# We have at least a NaT and a string
1294-
# try timedelta first to avoid spurious datetime conversions
1295-
# e.g. '00:00:01' is a timedelta but technically is also a datetime
1296-
value = try_timedelta(v)
1297-
if lib.infer_dtype(value, skipna=False) in ["mixed"]:
1298-
# cannot skip missing values, as NaT implies that the string
1299-
# is actually a datetime
1300-
1301-
# error: Incompatible types in assignment (expression has type
1302-
# "ExtensionArray", variable has type "Union[ndarray, List[Any]]")
1303-
value = try_datetime(v) # type: ignore[assignment]
1289+
# Incompatible types in assignment (expression has type
1290+
# "Union[ndarray[Any, Any], DatetimeArray]", variable has type
1291+
# "ndarray[Any, Any]")
1292+
value = try_datetime(v) # type: ignore[assignment]
1293+
assert value.dtype == "M8[ns]"
13041294

13051295
return value
13061296

0 commit comments

Comments
 (0)