Skip to content

Commit

Permalink
Backport PR #48555 on branch 1.5.x (DEPR: Series.astype(np.datetime64…
Browse files Browse the repository at this point in the history
…)) (#48569)

Backport PR #48555: DEPR: Series.astype(np.datetime64)

Co-authored-by: jbrockmendel <jbrockmendel@gmail.com>
  • Loading branch information
meeseeksmachine and jbrockmendel committed Sep 15, 2022
1 parent 19a3f5a commit 1fb8811
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.5.0.rst
Expand Up @@ -936,6 +936,7 @@ Other Deprecations
- Deprecated the ``sort_columns`` argument in :meth:`DataFrame.plot` and :meth:`Series.plot` (:issue:`47563`).
- Deprecated positional arguments for all but the first argument of :meth:`DataFrame.to_stata` and :func:`read_stata`, use keyword arguments instead (:issue:`48128`).
- Deprecated the ``mangle_dupe_cols`` argument in :func:`read_csv`, :func:`read_fwf`, :func:`read_table` and :func:`read_excel`. The argument was never implemented, and a new argument where the renaming pattern can be specified will be added instead (:issue:`47718`)
- Deprecated allowing ``dtype='datetime64'`` or ``dtype=np.datetime64`` in :meth:`Series.astype`, use "datetime64[ns]" instead (:issue:`47844`)

.. ---------------------------------------------------------------------------
.. _whatsnew_150.performance:
Expand Down
16 changes: 16 additions & 0 deletions pandas/core/arrays/datetimes.py
Expand Up @@ -630,6 +630,22 @@ def astype(self, dtype, copy: bool = True):
return type(self)._simple_new(res_values, dtype=dtype)
# TODO: preserve freq?

elif (
self.tz is None
and is_datetime64_dtype(dtype)
and dtype != self.dtype
and is_unitless(dtype)
):
# TODO(2.0): just fall through to dtl.DatetimeLikeArrayMixin.astype
warnings.warn(
"Passing unit-less datetime64 dtype to .astype is deprecated "
"and will raise in a future version. Pass 'datetime64[ns]' instead",
FutureWarning,
stacklevel=find_stack_level(inspect.currentframe()),
)
# unit conversion e.g. datetime64[s]
return self._ndarray.astype(dtype)

elif is_period_dtype(dtype):
return self.to_period(freq=dtype.freq)
return dtl.DatetimeLikeArrayMixin.astype(self, dtype, copy)
Expand Down
6 changes: 6 additions & 0 deletions pandas/core/indexes/base.py
Expand Up @@ -42,6 +42,7 @@
IncompatibleFrequency,
OutOfBoundsDatetime,
Timestamp,
is_unitless,
tz_compare,
)
from pandas._typing import (
Expand Down Expand Up @@ -1085,6 +1086,11 @@ def astype(self, dtype, copy: bool = True):

values = self._data
if isinstance(values, ExtensionArray):
if isinstance(dtype, np.dtype) and dtype.kind == "M" and is_unitless(dtype):
# TODO(2.0): remove this special-casing once this is enforced
# in DTA.astype
raise TypeError(f"Cannot cast {type(self).__name__} to dtype")

with rewrite_exception(type(values).__name__, type(self).__name__):
new_values = values.astype(dtype, copy=copy)

Expand Down
13 changes: 13 additions & 0 deletions pandas/tests/series/methods/test_astype.py
Expand Up @@ -30,6 +30,19 @@


class TestAstypeAPI:
def test_astype_unitless_dt64_deprecated(self):
# GH#47844
ser = Series(["1970-01-01", "1970-01-01", "1970-01-01"], dtype="datetime64[ns]")

msg = "Passing unit-less datetime64 dtype to .astype is deprecated and "
with tm.assert_produces_warning(FutureWarning, match=msg):
res = ser.astype(np.datetime64)
tm.assert_series_equal(ser, res)

with tm.assert_produces_warning(FutureWarning, match=msg):
res = ser.astype("datetime64")
tm.assert_series_equal(ser, res)

def test_arg_for_errors_in_astype(self):
# see GH#14878
ser = Series([1, 2, 3])
Expand Down

0 comments on commit 1fb8811

Please sign in to comment.