Skip to content

REF: consolidate paths for astype #39900

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
Substitution,
cache_readonly,
)
from pandas.util._exceptions import find_stack_level

from pandas.core.dtypes.common import (
is_categorical_dtype,
Expand Down Expand Up @@ -397,12 +398,13 @@ def astype(self, dtype, copy=True):
elif is_integer_dtype(dtype):
# we deliberately ignore int32 vs. int64 here.
# See https://github.com/pandas-dev/pandas/issues/24381 for more.
level = find_stack_level()
warnings.warn(
f"casting {self.dtype} values to int64 with .astype(...) is "
"deprecated and will raise in a future version. "
"Use .view(...) instead.",
FutureWarning,
stacklevel=3,
stacklevel=level,
)

values = self.asi8
Expand Down
4 changes: 4 additions & 0 deletions pandas/core/arrays/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,10 @@ def astype(self, dtype, copy=True):
elif is_datetime64_ns_dtype(dtype):
return astype_dt64_to_dt64tz(self, dtype, copy, via_utc=False)

elif self.tz is None and is_datetime64_dtype(dtype) and dtype != self.dtype:
# unit conversion e.g. datetime64[s]
return self._data.astype(dtype)

elif is_period_dtype(dtype):
return self.to_period(freq=dtype.freq)
return dtl.DatetimeLikeArrayMixin.astype(self, dtype, copy)
Expand Down
4 changes: 4 additions & 0 deletions pandas/core/indexes/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@ def astype(self, dtype, copy=True):
return self
return self.copy()

if isinstance(dtype, np.dtype) and dtype.kind == "M" and dtype != "M8[ns]":
# For now Datetime supports this by unwrapping ndarray, but DTI doesn't
raise TypeError(f"Cannot cast {type(self._data).__name__} to dtype")

new_values = self._data.astype(dtype, copy=copy)

# pass copy=False because any copying will be done in the
Expand Down
12 changes: 12 additions & 0 deletions pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,18 @@ def astype(self, dtype, copy: bool = False, errors: str = "raise"):

def _astype(self, dtype: DtypeObj, copy: bool) -> ArrayLike:
values = self.values
if values.dtype.kind in ["m", "M"]:
values = self.array_values()

if (
values.dtype.kind in ["m", "M"]
and dtype.kind in ["i", "u"]
and isinstance(dtype, np.dtype)
and dtype.itemsize != 8
):
# TODO(2.0) remove special case once deprecation on DTA/TDA is enforced
msg = rf"cannot astype a datetimelike from [{values.dtype}] to [{dtype}]"
raise TypeError(msg)

if is_datetime64tz_dtype(dtype) and is_datetime64_dtype(values.dtype):
return astype_dt64_to_dt64tz(values, dtype, copy, via_utc=True)
Expand Down
12 changes: 2 additions & 10 deletions pandas/tests/frame/methods/test_astype.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,19 +432,11 @@ def test_astype_to_incorrect_datetimelike(self, unit):
other = f"m8[{unit}]"

df = DataFrame(np.array([[1, 2, 3]], dtype=dtype))
msg = (
fr"cannot astype a datetimelike from \[datetime64\[ns\]\] to "
fr"\[timedelta64\[{unit}\]\]"
fr"|(Cannot cast DatetimeArray to dtype timedelta64\[{unit}\])"
)
msg = fr"Cannot cast DatetimeArray to dtype timedelta64\[{unit}\]"
with pytest.raises(TypeError, match=msg):
df.astype(other)

msg = (
fr"cannot astype a timedelta from \[timedelta64\[ns\]\] to "
fr"\[datetime64\[{unit}\]\]"
fr"|(Cannot cast TimedeltaArray to dtype datetime64\[{unit}\])"
)
msg = fr"Cannot cast TimedeltaArray to dtype datetime64\[{unit}\]"
df = DataFrame(np.array([[1, 2, 3]], dtype=other))
with pytest.raises(TypeError, match=msg):
df.astype(dtype)
Expand Down
6 changes: 3 additions & 3 deletions pandas/tests/indexes/datetimes/methods/test_astype.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_astype(self):
)
tm.assert_index_equal(result, expected)

with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
with tm.assert_produces_warning(FutureWarning):
result = idx.astype(int)
expected = Int64Index(
[1463356800000000000] + [-9223372036854775808] * 3,
Expand All @@ -39,7 +39,7 @@ def test_astype(self):
tm.assert_index_equal(result, expected)

rng = date_range("1/1/2000", periods=10, name="idx")
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
with tm.assert_produces_warning(FutureWarning):
result = rng.astype("i8")
tm.assert_index_equal(result, Index(rng.asi8, name="idx"))
tm.assert_numpy_array_equal(result.values, rng.asi8)
Expand All @@ -50,7 +50,7 @@ def test_astype_uint(self):
np.array([946684800000000000, 946771200000000000], dtype="uint64"),
name="idx",
)
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
with tm.assert_produces_warning(FutureWarning):
tm.assert_index_equal(arr.astype("uint64"), expected)
tm.assert_index_equal(arr.astype("uint32"), expected)

Expand Down
6 changes: 3 additions & 3 deletions pandas/tests/indexes/period/methods/test_astype.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def test_astype_conversion(self):
)
tm.assert_index_equal(result, expected)

with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
with tm.assert_produces_warning(FutureWarning):
result = idx.astype(np.int64)
expected = Int64Index(
[16937] + [-9223372036854775808] * 3, dtype=np.int64, name="idx"
Expand All @@ -49,15 +49,15 @@ def test_astype_conversion(self):
tm.assert_index_equal(result, expected)

idx = period_range("1990", "2009", freq="A", name="idx")
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
with tm.assert_produces_warning(FutureWarning):
result = idx.astype("i8")
tm.assert_index_equal(result, Index(idx.asi8, name="idx"))
tm.assert_numpy_array_equal(result.values, idx.asi8)

def test_astype_uint(self):
arr = period_range("2000", periods=2, name="idx")
expected = UInt64Index(np.array([10957, 10958], dtype="uint64"), name="idx")
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
with tm.assert_produces_warning(FutureWarning):
tm.assert_index_equal(arr.astype("uint64"), expected)
tm.assert_index_equal(arr.astype("uint32"), expected)

Expand Down
6 changes: 3 additions & 3 deletions pandas/tests/indexes/timedeltas/methods/test_astype.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def test_astype(self):
)
tm.assert_index_equal(result, expected)

with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
with tm.assert_produces_warning(FutureWarning):
result = idx.astype(int)
expected = Int64Index(
[100000000000000] + [-9223372036854775808] * 3, dtype=np.int64, name="idx"
Expand All @@ -67,7 +67,7 @@ def test_astype(self):
tm.assert_index_equal(result, expected)

rng = timedelta_range("1 days", periods=10)
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
with tm.assert_produces_warning(FutureWarning):
result = rng.astype("i8")
tm.assert_index_equal(result, Index(rng.asi8))
tm.assert_numpy_array_equal(rng.asi8, result.values)
Expand All @@ -77,7 +77,7 @@ def test_astype_uint(self):
expected = pd.UInt64Index(
np.array([3600000000000, 90000000000000], dtype="uint64")
)
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
with tm.assert_produces_warning(FutureWarning):
tm.assert_index_equal(arr.astype("uint64"), expected)
tm.assert_index_equal(arr.astype("uint32"), expected)

Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/series/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -1318,7 +1318,7 @@ def test_constructor_dtype_timedelta64(self):
td.astype("int64")

# invalid casting
msg = r"cannot astype a timedelta from \[timedelta64\[ns\]\] to \[int32\]"
msg = r"cannot astype a datetimelike from \[timedelta64\[ns\]\] to \[int32\]"
with pytest.raises(TypeError, match=msg):
td.astype("int32")

Expand Down