From 6a23a3cf95ee7e630de88835aa9bfd757fa73b58 Mon Sep 17 00:00:00 2001 From: Brock Date: Wed, 16 Dec 2020 19:05:07 -0800 Subject: [PATCH 1/4] CLN: use .view(i8) instead of .astype(i8) --- pandas/core/window/ewm.py | 5 ++++- pandas/io/formats/format.py | 2 +- pandas/io/stata.py | 6 +++--- pandas/tests/indexes/period/test_constructors.py | 2 +- pandas/tests/io/json/test_pandas.py | 4 ++-- pandas/tests/io/test_sql.py | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/pandas/core/window/ewm.py b/pandas/core/window/ewm.py index f8237a436f436..0fc6c8a23f5f2 100644 --- a/pandas/core/window/ewm.py +++ b/pandas/core/window/ewm.py @@ -12,6 +12,7 @@ from pandas.util._decorators import Appender, Substitution, doc from pandas.core.dtypes.common import is_datetime64_ns_dtype +from pandas.core.dtypes.missing import isna import pandas.core.common as common from pandas.core.util.numba_ import maybe_use_numba @@ -252,7 +253,9 @@ def __init__( raise ValueError( "halflife must be a string or datetime.timedelta object" ) - self.times = np.asarray(times.astype(np.int64)) + if isna(times).any(): + raise ValueError("Cannot convert NaT values to integer") + self.times = np.asarray(times.view(np.int64)) self.halflife = Timedelta(halflife).value # Halflife is no longer applicable when calculating COM # But allow COM to still be calculated if the user passes other decay args diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 527ee51873631..2620c562aefeb 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1739,7 +1739,7 @@ def get_format_timedelta64( If box, then show the return in quotes """ - values_int = values.astype(np.int64) + values_int = values.view(np.int64) consider_values = values_int != iNaT diff --git a/pandas/io/stata.py b/pandas/io/stata.py index 853a982536d40..88485f99c07aa 100644 --- a/pandas/io/stata.py +++ b/pandas/io/stata.py @@ -371,15 +371,15 @@ def parse_dates_safe(dates, delta=False, year=False, days=False): if is_datetime64_dtype(dates.dtype): if delta: time_delta = dates - stata_epoch - d["delta"] = time_delta._values.astype(np.int64) // 1000 # microseconds + d["delta"] = time_delta._values.view(np.int64) // 1000 # microseconds if days or year: date_index = DatetimeIndex(dates) d["year"] = date_index._data.year d["month"] = date_index._data.month if days: - days_in_ns = dates.astype(np.int64) - to_datetime( + days_in_ns = dates.view(np.int64) - to_datetime( d["year"], format="%Y" - ).astype(np.int64) + ).view(np.int64) d["days"] = days_in_ns // NS_PER_DAY elif infer_dtype(dates, skipna=False) == "datetime": diff --git a/pandas/tests/indexes/period/test_constructors.py b/pandas/tests/indexes/period/test_constructors.py index 678967db72a0b..75c8c766b0e67 100644 --- a/pandas/tests/indexes/period/test_constructors.py +++ b/pandas/tests/indexes/period/test_constructors.py @@ -329,7 +329,7 @@ def test_constructor_simple_new(self): msg = "Should be numpy array of type i8" with pytest.raises(AssertionError, match=msg): # Need ndarray, not Int64Index - type(idx._data)._simple_new(idx.astype("i8"), freq=idx.freq) + type(idx._data)._simple_new(idx._int64index, freq=idx.freq) arr = type(idx._data)._simple_new(idx.asi8, freq=idx.freq) result = idx._simple_new(arr, name="p") diff --git a/pandas/tests/io/json/test_pandas.py b/pandas/tests/io/json/test_pandas.py index ce95eb59ed3c4..8f9b6699503ee 100644 --- a/pandas/tests/io/json/test_pandas.py +++ b/pandas/tests/io/json/test_pandas.py @@ -112,7 +112,7 @@ def test_frame_non_unique_columns(self, orient, data): # in milliseconds; these are internally stored in nanosecond, # so divide to get where we need # TODO: a to_epoch method would also solve; see GH 14772 - expected.iloc[:, 0] = expected.iloc[:, 0].astype(np.int64) // 1000000 + expected.iloc[:, 0] = expected.iloc[:, 0].view(np.int64) // 1000000 elif orient == "split": expected = df @@ -254,7 +254,7 @@ def test_roundtrip_timestamp(self, orient, convert_axes, numpy, datetime_frame): if not convert_axes: # one off for ts handling # DTI gets converted to epoch values - idx = expected.index.astype(np.int64) // 1000000 + idx = expected.index.view(np.int64) // 1000000 if orient != "split": # TODO: handle consistently across orients idx = idx.astype(str) diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py index 497039de99196..4442d47c9f535 100644 --- a/pandas/tests/io/test_sql.py +++ b/pandas/tests/io/test_sql.py @@ -841,7 +841,7 @@ def test_timedelta(self): with tm.assert_produces_warning(UserWarning): df.to_sql("test_timedelta", self.conn) result = sql.read_sql_query("SELECT * FROM test_timedelta", self.conn) - tm.assert_series_equal(result["foo"], df["foo"].astype("int64")) + tm.assert_series_equal(result["foo"], df["foo"].view("int64")) def test_complex_raises(self): df = DataFrame({"a": [1 + 1j, 2j]}) From 93d8b2541ba6c7918cba0660139f21891686dd05 Mon Sep 17 00:00:00 2001 From: Brock Date: Thu, 17 Dec 2020 08:46:18 -0800 Subject: [PATCH 2/4] DEPR: datetimelike.astype(int) --- doc/source/whatsnew/v1.3.0.rst | 2 +- pandas/core/arrays/datetimelike.py | 8 ++++++ pandas/core/dtypes/cast.py | 18 ++++++++++++- pandas/tests/arrays/test_datetimes.py | 9 +++++-- pandas/tests/arrays/test_period.py | 18 ++++++++++--- pandas/tests/arrays/test_timedeltas.py | 9 +++++-- pandas/tests/dtypes/test_common.py | 4 ++- pandas/tests/indexes/datetimes/test_astype.py | 12 +++++---- pandas/tests/indexes/interval/test_astype.py | 11 +++++--- .../indexes/interval/test_constructors.py | 12 +++++++-- pandas/tests/indexes/period/test_astype.py | 11 +++++--- pandas/tests/indexes/test_common.py | 7 +++++- .../tests/indexes/timedeltas/test_astype.py | 12 +++++---- pandas/tests/internals/test_internals.py | 6 ++++- pandas/tests/series/test_constructors.py | 25 +++++++++++++------ 15 files changed, 124 insertions(+), 40 deletions(-) diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index 57dd1d05a274e..ae397ff86a05d 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -142,7 +142,7 @@ Other API changes Deprecations ~~~~~~~~~~~~ - +- Deprecated casting of datetimelike (``timedelta64[ns]``, ``datetime64[ns]``, ``Datetime64TZDtype``, ``PeriodDtype``) to integer dtypes, use ``values.view(...)`` instead (:issue:`???`) - - diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index be9864731842d..577993e331d1b 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -352,6 +352,14 @@ 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. + 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, + ) + values = self.asi8 if is_unsigned_integer_dtype(dtype): diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index abcc60a15c641..fae172c9c2ba3 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -1,7 +1,6 @@ """ Routines for casting. """ - from contextlib import suppress from datetime import datetime, timedelta from typing import ( @@ -17,6 +16,7 @@ Type, Union, ) +import warnings import numpy as np @@ -996,6 +996,14 @@ def astype_nansafe( if is_object_dtype(dtype): return ints_to_pydatetime(arr.view(np.int64)) elif dtype == np.int64: + warnings.warn( + f"casting {arr.dtype} values to int64 with .astype(...) " + "is deprecated and will raise in a future version. " + "Use .view(...) instead.", + FutureWarning, + # stacklevel chosen to be correct when reached via Series.astype + stacklevel=7, + ) if isna(arr).any(): raise ValueError("Cannot convert NaT values to integer") return arr.view(dtype) @@ -1010,6 +1018,14 @@ def astype_nansafe( if is_object_dtype(dtype): return ints_to_pytimedelta(arr.view(np.int64)) elif dtype == np.int64: + warnings.warn( + f"casting {arr.dtype} values to int64 with .astype(...) " + "is deprecated and will raise in a future version. " + "Use .view(...) instead.", + FutureWarning, + # stacklevel chosen to be correct when reached via Series.astype + stacklevel=7, + ) if isna(arr).any(): raise ValueError("Cannot convert NaT values to integer") return arr.view(dtype) diff --git a/pandas/tests/arrays/test_datetimes.py b/pandas/tests/arrays/test_datetimes.py index 1d8ee9cf2b73b..deb3e154d62fd 100644 --- a/pandas/tests/arrays/test_datetimes.py +++ b/pandas/tests/arrays/test_datetimes.py @@ -184,13 +184,18 @@ def test_astype_copies(self, dtype, other): @pytest.mark.parametrize("dtype", [int, np.int32, np.int64, "uint32", "uint64"]) def test_astype_int(self, dtype): arr = DatetimeArray._from_sequence([pd.Timestamp("2000"), pd.Timestamp("2001")]) - result = arr.astype(dtype) + with tm.assert_produces_warning(FutureWarning): + # astype(int..) deprecated + result = arr.astype(dtype) if np.dtype(dtype).kind == "u": expected_dtype = np.dtype("uint64") else: expected_dtype = np.dtype("int64") - expected = arr.astype(expected_dtype) + + with tm.assert_produces_warning(FutureWarning): + # astype(int..) deprecated + expected = arr.astype(expected_dtype) assert result.dtype == expected_dtype tm.assert_numpy_array_equal(result, expected) diff --git a/pandas/tests/arrays/test_period.py b/pandas/tests/arrays/test_period.py index f96a15d5b2e7c..8fca2a6d83393 100644 --- a/pandas/tests/arrays/test_period.py +++ b/pandas/tests/arrays/test_period.py @@ -123,13 +123,18 @@ def test_astype(dtype): # We choose to ignore the sign and size of integers for # Period/Datetime/Timedelta astype arr = period_array(["2000", "2001", None], freq="D") - result = arr.astype(dtype) + with tm.assert_produces_warning(FutureWarning): + # astype(int..) deprecated + result = arr.astype(dtype) if np.dtype(dtype).kind == "u": expected_dtype = np.dtype("uint64") else: expected_dtype = np.dtype("int64") - expected = arr.astype(expected_dtype) + + with tm.assert_produces_warning(FutureWarning): + # astype(int..) deprecated + expected = arr.astype(expected_dtype) assert result.dtype == expected_dtype tm.assert_numpy_array_equal(result, expected) @@ -137,12 +142,17 @@ def test_astype(dtype): def test_astype_copies(): arr = period_array(["2000", "2001", None], freq="D") - result = arr.astype(np.int64, copy=False) + with tm.assert_produces_warning(FutureWarning): + # astype(int..) deprecated + result = arr.astype(np.int64, copy=False) + # Add the `.base`, since we now use `.asi8` which returns a view. # We could maybe override it in PeriodArray to return ._data directly. assert result.base is arr._data - result = arr.astype(np.int64, copy=True) + with tm.assert_produces_warning(FutureWarning): + # astype(int..) deprecated + result = arr.astype(np.int64, copy=True) assert result is not arr._data tm.assert_numpy_array_equal(result, arr._data.view("i8")) diff --git a/pandas/tests/arrays/test_timedeltas.py b/pandas/tests/arrays/test_timedeltas.py index c0567209ff91b..9d9ca41779b5a 100644 --- a/pandas/tests/arrays/test_timedeltas.py +++ b/pandas/tests/arrays/test_timedeltas.py @@ -82,13 +82,18 @@ def test_from_sequence_dtype(self): @pytest.mark.parametrize("dtype", [int, np.int32, np.int64, "uint32", "uint64"]) def test_astype_int(self, dtype): arr = TimedeltaArray._from_sequence([Timedelta("1H"), Timedelta("2H")]) - result = arr.astype(dtype) + with tm.assert_produces_warning(FutureWarning): + # astype(int..) deprecated + result = arr.astype(dtype) if np.dtype(dtype).kind == "u": expected_dtype = np.dtype("uint64") else: expected_dtype = np.dtype("int64") - expected = arr.astype(expected_dtype) + + with tm.assert_produces_warning(FutureWarning): + # astype(int..) deprecated + expected = arr.astype(expected_dtype) assert result.dtype == expected_dtype tm.assert_numpy_array_equal(result, expected) diff --git a/pandas/tests/dtypes/test_common.py b/pandas/tests/dtypes/test_common.py index 0d0601aa542b4..7d07995c58daf 100644 --- a/pandas/tests/dtypes/test_common.py +++ b/pandas/tests/dtypes/test_common.py @@ -720,7 +720,9 @@ def test_astype_nansafe(val, typ): msg = "Cannot convert NaT values to integer" with pytest.raises(ValueError, match=msg): - astype_nansafe(arr, dtype=typ) + with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + # datetimelike astype(int64) deprecated + astype_nansafe(arr, dtype=typ) @pytest.mark.parametrize("from_type", [np.datetime64, np.timedelta64]) diff --git a/pandas/tests/indexes/datetimes/test_astype.py b/pandas/tests/indexes/datetimes/test_astype.py index 2f22236d55ff3..98d5e074091de 100644 --- a/pandas/tests/indexes/datetimes/test_astype.py +++ b/pandas/tests/indexes/datetimes/test_astype.py @@ -29,7 +29,8 @@ def test_astype(self): ) tm.assert_index_equal(result, expected) - result = idx.astype(int) + with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + result = idx.astype(int) expected = Int64Index( [1463356800000000000] + [-9223372036854775808] * 3, dtype=np.int64, @@ -38,7 +39,8 @@ def test_astype(self): tm.assert_index_equal(result, expected) rng = date_range("1/1/2000", periods=10, name="idx") - result = rng.astype("i8") + with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + result = rng.astype("i8") tm.assert_index_equal(result, Index(rng.asi8, name="idx")) tm.assert_numpy_array_equal(result.values, rng.asi8) @@ -48,9 +50,9 @@ def test_astype_uint(self): np.array([946684800000000000, 946771200000000000], dtype="uint64"), name="idx", ) - - tm.assert_index_equal(arr.astype("uint64"), expected) - tm.assert_index_equal(arr.astype("uint32"), expected) + with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + tm.assert_index_equal(arr.astype("uint64"), expected) + tm.assert_index_equal(arr.astype("uint32"), expected) def test_astype_with_tz(self): diff --git a/pandas/tests/indexes/interval/test_astype.py b/pandas/tests/indexes/interval/test_astype.py index b4af1cb5859f0..34ce810e32273 100644 --- a/pandas/tests/indexes/interval/test_astype.py +++ b/pandas/tests/indexes/interval/test_astype.py @@ -197,10 +197,13 @@ def index(self, request): @pytest.mark.parametrize("subtype", ["int64", "uint64"]) def test_subtype_integer(self, index, subtype): dtype = IntervalDtype(subtype) - result = index.astype(dtype) - expected = IntervalIndex.from_arrays( - index.left.astype(subtype), index.right.astype(subtype), closed=index.closed - ) + with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + result = index.astype(dtype) + expected = IntervalIndex.from_arrays( + index.left.astype(subtype), + index.right.astype(subtype), + closed=index.closed, + ) tm.assert_index_equal(result, expected) def test_subtype_float(self, index): diff --git a/pandas/tests/indexes/interval/test_constructors.py b/pandas/tests/indexes/interval/test_constructors.py index 8b4cafc17a202..2194c628caacd 100644 --- a/pandas/tests/indexes/interval/test_constructors.py +++ b/pandas/tests/indexes/interval/test_constructors.py @@ -71,13 +71,21 @@ def test_constructor(self, constructor, breaks, closed, name): ) def test_constructor_dtype(self, constructor, breaks, subtype): # GH 19262: conversion via dtype parameter - expected_kwargs = self.get_kwargs_from_breaks(breaks.astype(subtype)) + warn = None + if subtype == "int64" and breaks.dtype.kind in ["M", "m"]: + # astype(int64) deprecated + warn = FutureWarning + + with tm.assert_produces_warning(warn, check_stacklevel=False): + expected_kwargs = self.get_kwargs_from_breaks(breaks.astype(subtype)) expected = constructor(**expected_kwargs) result_kwargs = self.get_kwargs_from_breaks(breaks) iv_dtype = IntervalDtype(subtype) for dtype in (iv_dtype, str(iv_dtype)): - result = constructor(dtype=dtype, **result_kwargs) + with tm.assert_produces_warning(warn, check_stacklevel=False): + + result = constructor(dtype=dtype, **result_kwargs) tm.assert_index_equal(result, expected) @pytest.mark.parametrize("breaks", [[np.nan] * 2, [np.nan] * 4, [np.nan] * 50]) diff --git a/pandas/tests/indexes/period/test_astype.py b/pandas/tests/indexes/period/test_astype.py index 674d09c6a7a8c..943b2605363c7 100644 --- a/pandas/tests/indexes/period/test_astype.py +++ b/pandas/tests/indexes/period/test_astype.py @@ -37,7 +37,8 @@ def test_astype_conversion(self): ) tm.assert_index_equal(result, expected) - result = idx.astype(np.int64) + with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + result = idx.astype(np.int64) expected = Int64Index( [16937] + [-9223372036854775808] * 3, dtype=np.int64, name="idx" ) @@ -48,15 +49,17 @@ def test_astype_conversion(self): tm.assert_index_equal(result, expected) idx = period_range("1990", "2009", freq="A", name="idx") - result = idx.astype("i8") + with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + 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") - tm.assert_index_equal(arr.astype("uint64"), expected) - tm.assert_index_equal(arr.astype("uint32"), expected) + with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + tm.assert_index_equal(arr.astype("uint64"), expected) + tm.assert_index_equal(arr.astype("uint32"), expected) def test_astype_object(self): idx = PeriodIndex([], freq="M") diff --git a/pandas/tests/indexes/test_common.py b/pandas/tests/indexes/test_common.py index a10be99dff076..1338a125cdc42 100644 --- a/pandas/tests/indexes/test_common.py +++ b/pandas/tests/indexes/test_common.py @@ -341,9 +341,14 @@ def test_astype_preserves_name(self, index, dtype): else: index.name = "idx" + warn = None + if dtype in ["int64", "uint64"]: + if needs_i8_conversion(index.dtype): + warn = FutureWarning try: # Some of these conversions cannot succeed so we use a try / except - result = index.astype(dtype) + with tm.assert_produces_warning(warn, check_stacklevel=False): + result = index.astype(dtype) except (ValueError, TypeError, NotImplementedError, SystemError): return diff --git a/pandas/tests/indexes/timedeltas/test_astype.py b/pandas/tests/indexes/timedeltas/test_astype.py index 6f82e77faca7a..a849ffa98324c 100644 --- a/pandas/tests/indexes/timedeltas/test_astype.py +++ b/pandas/tests/indexes/timedeltas/test_astype.py @@ -55,7 +55,8 @@ def test_astype(self): ) tm.assert_index_equal(result, expected) - result = idx.astype(int) + with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + result = idx.astype(int) expected = Int64Index( [100000000000000] + [-9223372036854775808] * 3, dtype=np.int64, name="idx" ) @@ -66,7 +67,8 @@ def test_astype(self): tm.assert_index_equal(result, expected) rng = timedelta_range("1 days", periods=10) - result = rng.astype("i8") + with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + result = rng.astype("i8") tm.assert_index_equal(result, Index(rng.asi8)) tm.assert_numpy_array_equal(rng.asi8, result.values) @@ -75,9 +77,9 @@ def test_astype_uint(self): expected = pd.UInt64Index( np.array([3600000000000, 90000000000000], dtype="uint64") ) - - tm.assert_index_equal(arr.astype("uint64"), expected) - tm.assert_index_equal(arr.astype("uint32"), expected) + with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + tm.assert_index_equal(arr.astype("uint64"), expected) + tm.assert_index_equal(arr.astype("uint32"), expected) def test_astype_timedelta64(self): # GH 13149, GH 13209 diff --git a/pandas/tests/internals/test_internals.py b/pandas/tests/internals/test_internals.py index d7580e9f8610e..9b032da1f20ea 100644 --- a/pandas/tests/internals/test_internals.py +++ b/pandas/tests/internals/test_internals.py @@ -454,6 +454,9 @@ def test_astype(self, t): # coerce all mgr = create_mgr("c: f4; d: f2; e: f8") + warn = FutureWarning if t == "int64" else None + # datetimelike.astype(int64) deprecated + t = np.dtype(t) tmgr = mgr.astype(t) assert tmgr.iget(0).dtype.type == t @@ -464,7 +467,8 @@ def test_astype(self, t): mgr = create_mgr("a,b: object; c: bool; d: datetime; e: f4; f: f2; g: f8") t = np.dtype(t) - tmgr = mgr.astype(t, errors="ignore") + with tm.assert_produces_warning(warn): + tmgr = mgr.astype(t, errors="ignore") assert tmgr.iget(2).dtype.type == t assert tmgr.iget(4).dtype.type == t assert tmgr.iget(5).dtype.type == t diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index 5b13091470b09..48382afef1b5f 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -785,7 +785,9 @@ def test_constructor_dtype_datetime64(self): dtype="datetime64[ns]", ) - result = Series(Series(dates).astype(np.int64) / 1000000, dtype="M8[ms]") + with tm.assert_produces_warning(FutureWarning): + # astype(np.int64) deprecated + result = Series(Series(dates).astype(np.int64) / 1000000, dtype="M8[ms]") tm.assert_series_equal(result, expected) result = Series(dates, dtype="datetime64[ns]") @@ -800,7 +802,9 @@ def test_constructor_dtype_datetime64(self): dts = Series(dates, dtype="datetime64[ns]") # valid astype - dts.astype("int64") + with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + # astype(np.int64) deprecated + dts.astype("int64") # invalid casting msg = r"cannot astype a datetimelike from \[datetime64\[ns\]\] to \[int32\]" @@ -810,8 +814,10 @@ def test_constructor_dtype_datetime64(self): # ints are ok # we test with np.int64 to get similar results on # windows / 32-bit platforms - result = Series(dts, dtype=np.int64) - expected = Series(dts.astype(np.int64)) + with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + # astype(np.int64) deprecated + result = Series(dts, dtype=np.int64) + expected = Series(dts.astype(np.int64)) tm.assert_series_equal(result, expected) # invalid dates can be help as object @@ -1287,13 +1293,16 @@ def test_constructor_dtype_timedelta64(self): td = Series([np.timedelta64(1, "s")]) assert td.dtype == "timedelta64[ns]" + # FIXME: dont leave commented-out # these are frequency conversion astypes # for t in ['s', 'D', 'us', 'ms']: # with pytest.raises(TypeError): # td.astype('m8[%s]' % t) # valid astype - td.astype("int64") + with tm.assert_produces_warning(FutureWarning): + # astype(int64) deprecated + td.astype("int64") # invalid casting msg = r"cannot astype a timedelta from \[timedelta64\[ns\]\] to \[int32\]" @@ -1410,8 +1419,10 @@ def test_constructor_cant_cast_datetimelike(self, index): # ints are ok # we test with np.int64 to get similar results on # windows / 32-bit platforms - result = Series(index, dtype=np.int64) - expected = Series(index.astype(np.int64)) + with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): + # asype(np.int64) deprecated, use .view(np.int64) instead + result = Series(index, dtype=np.int64) + expected = Series(index.astype(np.int64)) tm.assert_series_equal(result, expected) @pytest.mark.parametrize( From a40e61a8316c7493e82eb5555e630a29cd5d955e Mon Sep 17 00:00:00 2001 From: Brock Date: Thu, 17 Dec 2020 08:51:11 -0800 Subject: [PATCH 3/4] GH ref --- doc/source/whatsnew/v1.3.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index ae397ff86a05d..2080986ce322d 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -142,7 +142,7 @@ Other API changes Deprecations ~~~~~~~~~~~~ -- Deprecated casting of datetimelike (``timedelta64[ns]``, ``datetime64[ns]``, ``Datetime64TZDtype``, ``PeriodDtype``) to integer dtypes, use ``values.view(...)`` instead (:issue:`???`) +- Deprecated casting of datetimelike (``timedelta64[ns]``, ``datetime64[ns]``, ``Datetime64TZDtype``, ``PeriodDtype``) to integer dtypes, use ``values.view(...)`` instead (:issue:`38544`) - - From 166eb3a48d7f7c1da1a54e832318c9dca02f0955 Mon Sep 17 00:00:00 2001 From: Brock Date: Fri, 18 Dec 2020 18:50:17 -0800 Subject: [PATCH 4/4] update per comments --- doc/source/whatsnew/v1.3.0.rst | 2 +- pandas/tests/series/test_constructors.py | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index 60e332cda2cce..2d9da5fa1e1fd 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -142,7 +142,7 @@ Other API changes Deprecations ~~~~~~~~~~~~ -- Deprecated casting of datetimelike (``timedelta64[ns]``, ``datetime64[ns]``, ``Datetime64TZDtype``, ``PeriodDtype``) to integer dtypes, use ``values.view(...)`` instead (:issue:`38544`) +- Deprecated ``astype`` of datetimelike (``timedelta64[ns]``, ``datetime64[ns]``, ``Datetime64TZDtype``, ``PeriodDtype``) to integer dtypes, use ``values.view(...)`` instead (:issue:`38544`) - - diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index 48382afef1b5f..eabd6a1eb0743 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -785,9 +785,7 @@ def test_constructor_dtype_datetime64(self): dtype="datetime64[ns]", ) - with tm.assert_produces_warning(FutureWarning): - # astype(np.int64) deprecated - result = Series(Series(dates).astype(np.int64) / 1000000, dtype="M8[ms]") + result = Series(Series(dates).view(np.int64) / 1000000, dtype="M8[ms]") tm.assert_series_equal(result, expected) result = Series(dates, dtype="datetime64[ns]")