|
49 | 49 | from pandas.util._exceptions import find_stack_level
|
50 | 50 | from pandas.util._validators import validate_bool_kwarg
|
51 | 51 |
|
52 |
| -from pandas.core.dtypes.astype import astype_nansafe |
53 | 52 | from pandas.core.dtypes.common import (
|
54 | 53 | DT64NS_DTYPE,
|
55 | 54 | TD64NS_DTYPE,
|
@@ -311,6 +310,7 @@ def maybe_downcast_to_dtype(result: ArrayLike, dtype: str | np.dtype) -> ArrayLi
|
311 | 310 | result = array_to_timedelta64(result)
|
312 | 311 |
|
313 | 312 | elif dtype == np.dtype("M8[ns]") and result.dtype == _dtype_obj:
|
| 313 | + result = cast(np.ndarray, result) |
314 | 314 | return np.asarray(maybe_cast_to_datetime(result, dtype=dtype))
|
315 | 315 |
|
316 | 316 | return result
|
@@ -1234,82 +1234,58 @@ def maybe_infer_to_datetimelike(
|
1234 | 1234 |
|
1235 | 1235 |
|
1236 | 1236 | def maybe_cast_to_datetime(
|
1237 |
| - value: ExtensionArray | np.ndarray | list, dtype: np.dtype | None |
| 1237 | + value: np.ndarray | list, dtype: np.dtype |
1238 | 1238 | ) -> ExtensionArray | np.ndarray:
|
1239 | 1239 | """
|
1240 | 1240 | try to cast the array/value to a datetimelike dtype, converting float
|
1241 | 1241 | nan to iNaT
|
1242 | 1242 |
|
1243 |
| - We allow a list *only* when dtype is not None. |
1244 |
| -
|
1245 |
| - Caller is responsible for handling ExtensionDtype cases. |
| 1243 | + Caller is responsible for handling ExtensionDtype cases and non dt64/td64 |
| 1244 | + cases. |
1246 | 1245 | """
|
1247 | 1246 | from pandas.core.arrays.datetimes import sequence_to_datetimes
|
1248 | 1247 | from pandas.core.arrays.timedeltas import TimedeltaArray
|
1249 | 1248 |
|
| 1249 | + assert dtype.kind in ["m", "M"] |
1250 | 1250 | if not is_list_like(value):
|
1251 | 1251 | raise TypeError("value must be listlike")
|
1252 | 1252 |
|
1253 | 1253 | if is_timedelta64_dtype(dtype):
|
1254 | 1254 | # TODO: _from_sequence would raise ValueError in cases where
|
1255 | 1255 | # _ensure_nanosecond_dtype raises TypeError
|
1256 |
| - dtype = cast(np.dtype, dtype) |
1257 | 1256 | # Incompatible types in assignment (expression has type "Union[dtype[Any],
|
1258 | 1257 | # ExtensionDtype]", variable has type "Optional[dtype[Any]]")
|
1259 | 1258 | dtype = _ensure_nanosecond_dtype(dtype) # type: ignore[assignment]
|
1260 | 1259 | res = TimedeltaArray._from_sequence(value, dtype=dtype)
|
1261 | 1260 | return res
|
1262 | 1261 |
|
1263 |
| - if dtype is not None: |
1264 |
| - is_datetime64 = is_datetime64_dtype(dtype) |
1265 |
| - |
1266 |
| - vdtype = getattr(value, "dtype", None) |
1267 |
| - |
1268 |
| - if is_datetime64: |
1269 |
| - # Incompatible types in assignment (expression has type |
1270 |
| - # "Union[dtype[Any], ExtensionDtype]", variable has type |
1271 |
| - # "Optional[dtype[Any]]") |
1272 |
| - dtype = _ensure_nanosecond_dtype(dtype) # type: ignore[assignment] |
1273 |
| - |
1274 |
| - value = np.array(value, copy=False) |
1275 |
| - |
1276 |
| - # we have an array of datetime or timedeltas & nulls |
1277 |
| - if value.size or not is_dtype_equal(value.dtype, dtype): |
1278 |
| - _disallow_mismatched_datetimelike(value, dtype) |
1279 |
| - |
1280 |
| - dta = sequence_to_datetimes(value) |
1281 |
| - # GH 25843: Remove tz information since the dtype |
1282 |
| - # didn't specify one |
1283 |
| - |
1284 |
| - if dta.tz is not None: |
1285 |
| - raise ValueError( |
1286 |
| - "Cannot convert timezone-aware data to " |
1287 |
| - "timezone-naive dtype. Use " |
1288 |
| - "pd.Series(values).dt.tz_localize(None) instead." |
1289 |
| - ) |
1290 |
| - |
1291 |
| - # TODO(2.0): Do this astype in sequence_to_datetimes to |
1292 |
| - # avoid potential extra copy? |
1293 |
| - dta = dta.astype(dtype, copy=False) |
1294 |
| - value = dta |
1295 |
| - |
1296 |
| - elif getattr(vdtype, "kind", None) in ["m", "M"]: |
1297 |
| - # we are already datetimelike and want to coerce to non-datetimelike; |
1298 |
| - # astype_nansafe will raise for anything other than object, then upcast. |
1299 |
| - # see test_datetimelike_values_with_object_dtype |
1300 |
| - # error: Argument 2 to "astype_nansafe" has incompatible type |
1301 |
| - # "Union[dtype[Any], ExtensionDtype]"; expected "dtype[Any]" |
1302 |
| - return astype_nansafe(value, dtype) # type: ignore[arg-type] |
1303 |
| - |
1304 |
| - elif isinstance(value, np.ndarray): |
1305 |
| - if value.dtype == _dtype_obj: |
1306 |
| - value = maybe_infer_to_datetimelike(value) |
1307 |
| - |
1308 |
| - elif isinstance(value, list): |
1309 |
| - # we only get here with dtype=None, which we do not allow |
1310 |
| - raise ValueError( |
1311 |
| - "maybe_cast_to_datetime allows a list *only* if dtype is not None" |
1312 |
| - ) |
| 1262 | + if is_datetime64_dtype(dtype): |
| 1263 | + # Incompatible types in assignment (expression has type |
| 1264 | + # "Union[dtype[Any], ExtensionDtype]", variable has type |
| 1265 | + # "Optional[dtype[Any]]") |
| 1266 | + dtype = _ensure_nanosecond_dtype(dtype) # type: ignore[assignment] |
| 1267 | + |
| 1268 | + value = np.array(value, copy=False) |
| 1269 | + |
| 1270 | + # we have an array of datetime or timedeltas & nulls |
| 1271 | + if value.size or not is_dtype_equal(value.dtype, dtype): |
| 1272 | + _disallow_mismatched_datetimelike(value, dtype) |
| 1273 | + |
| 1274 | + dta = sequence_to_datetimes(value) |
| 1275 | + # GH 25843: Remove tz information since the dtype |
| 1276 | + # didn't specify one |
| 1277 | + |
| 1278 | + if dta.tz is not None: |
| 1279 | + raise ValueError( |
| 1280 | + "Cannot convert timezone-aware data to " |
| 1281 | + "timezone-naive dtype. Use " |
| 1282 | + "pd.Series(values).dt.tz_localize(None) instead." |
| 1283 | + ) |
| 1284 | + |
| 1285 | + # TODO(2.0): Do this astype in sequence_to_datetimes to |
| 1286 | + # avoid potential extra copy? |
| 1287 | + dta = dta.astype(dtype, copy=False) |
| 1288 | + return dta |
1313 | 1289 |
|
1314 | 1290 | # at this point we have converted or raised in all cases where we had a list
|
1315 | 1291 | return cast(ArrayLike, value)
|
|
0 commit comments