diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 331c2421a31ef4..0e6d1029d352b4 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -548,6 +548,8 @@ Removal of prior version deprecations/changes - Changed behavior of setitem-like operations (``__setitem__``, ``fillna``, ``where``, ``mask``, ``replace``, ``insert``, fill_value for ``shift``) on an object with :class:`DatetimeTZDtype` when using a value with a non-matching timezone, the value will be cast to the object's timezone instead of casting both to object-dtype (:issue:`44243`) - Changed behavior of :class:`Index`, :class:`Series`, :class:`DataFrame` constructors with floating-dtype data and a :class:`DatetimeTZDtype`, the data are now interpreted as UTC-times instead of wall-times, consistent with how integer-dtype data are treated (:issue:`45573`) - Changed behavior of :class:`Series` and :class:`DataFrame` constructors with integer dtype and floating-point data containing ``NaN``, this now raises ``IntCastingNaNError`` (:issue:`40110`) +- Changed behavior of :class:`Series` and :class:`DataFrame` constructors with an integer ``dtype`` and values that are too large to losslessly cast to this dtype, this now raises ``ValueError`` (:issue:`41734`) +- Changed behavior of :class:`Series` and :class:`DataFrame` constructors with an integer ``dtype`` and values having either ``datetime64`` or ``timedelta64`` dtypes, this now raises ``TypeError``, use ``values.view("int64")`` instead (:issue:`41770`) - Removed the deprecated ``base`` and ``loffset`` arguments from :meth:`pandas.DataFrame.resample`, :meth:`pandas.Series.resample` and :class:`pandas.Grouper`. Use ``offset`` or ``origin`` instead (:issue:`31809`) - Changed behavior of :meth:`Series.fillna` and :meth:`DataFrame.fillna` with ``timedelta64[ns]`` dtype and an incompatible ``fill_value``; this now casts to ``object`` dtype instead of raising, consistent with the behavior with other dtypes (:issue:`45746`) - Change the default argument of ``regex`` for :meth:`Series.str.replace` from ``True`` to ``False``. Additionally, a single character ``pat`` with ``regex=True`` is now treated as a regular expression instead of a string literal. (:issue:`36695`, :issue:`24804`) diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index 215b6c1021fd89..11c2bf8711ad14 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -41,7 +41,6 @@ IntCastingNaNError, LossySetitemError, ) -from pandas.util._exceptions import find_stack_level from pandas.util._validators import validate_bool_kwarg from pandas.core.dtypes.common import ( @@ -1680,25 +1679,17 @@ def maybe_cast_to_integer_array( if casted.dtype < arr.dtype: # GH#41734 e.g. [1, 200, 923442] and dtype="int8" -> overflows - warnings.warn( - f"Values are too large to be losslessly cast to {dtype}. " - "In a future version this will raise OverflowError. To retain the " - f"old behavior, use pd.Series(values).astype({dtype})", - FutureWarning, - stacklevel=find_stack_level(), + raise ValueError( + f"Values are too large to be losslessly converted to {dtype}. " + f"To cast anyway, use pd.Series(values).astype({dtype})" ) - return casted if arr.dtype.kind in ["m", "M"]: # test_constructor_maskedarray_nonfloat - warnings.warn( - f"Constructing Series or DataFrame from {arr.dtype} values and " - f"dtype={dtype} is deprecated and will raise in a future version. " - "Use values.view(dtype) instead.", - FutureWarning, - stacklevel=find_stack_level(), + raise TypeError( + f"Constructing a Series or DataFrame from {arr.dtype} values and " + f"dtype={dtype} is not supported. Use values.view({dtype}) instead." ) - return casted # No known cases that get here, but raising explicitly to cover our bases. raise ValueError(f"values cannot be losslessly cast to {dtype}") diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index b83e060a666500..b6c6792355fc78 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -1054,18 +1054,15 @@ def test_constructor_maskedarray_nonfloat(self): assert isna(frame).values.all() # cast type - msg = r"datetime64\[ns\] values and dtype=int64" - with tm.assert_produces_warning(FutureWarning, match=msg): + msg = r"datetime64\[ns\] values and dtype=int64 is not supported" + with pytest.raises(TypeError, match=msg): with warnings.catch_warnings(): warnings.filterwarnings( "ignore", category=DeprecationWarning, message="elementwise comparison failed", ) - frame = DataFrame( - mat, columns=["A", "B", "C"], index=[1, 2], dtype=np.int64 - ) - assert frame.values.dtype == np.int64 + DataFrame(mat, columns=["A", "B", "C"], index=[1, 2], dtype=np.int64) # Check non-masked values mat2 = ma.copy(mat) diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index 826ad20dfd54e2..b44f5b699cab49 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -749,25 +749,17 @@ def test_constructor_cast(self): with pytest.raises(ValueError, match=msg): Series(["a", "b", "c"], dtype=float) - def test_constructor_signed_int_overflow_deprecation(self): - # GH#41734 disallow silent overflow - msg = "Values are too large to be losslessly cast" + def test_constructor_signed_int_overflow_raises(self): + # GH#41734 disallow silent overflow, enforced in 2.0 + msg = "Values are too large to be losslessly converted" numpy_warning = DeprecationWarning if is_numpy_dev else None - with tm.assert_produces_warning( - (FutureWarning, numpy_warning), match=msg, check_stacklevel=False - ): - ser = Series([1, 200, 923442], dtype="int8") - - expected = Series([1, -56, 50], dtype="int8") - tm.assert_series_equal(ser, expected) - - with tm.assert_produces_warning( - (FutureWarning, numpy_warning), match=msg, check_stacklevel=False - ): - ser = Series([1, 200, 923442], dtype="uint8") + with pytest.raises(ValueError, match=msg): + with tm.assert_produces_warning(numpy_warning): + Series([1, 200, 923442], dtype="int8") - expected = Series([1, 200, 50], dtype="uint8") - tm.assert_series_equal(ser, expected) + with pytest.raises(ValueError, match=msg): + with tm.assert_produces_warning(numpy_warning): + Series([1, 200, 923442], dtype="uint8") @pytest.mark.parametrize( "values",