diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index c3481a5452091..2258c76a6cff5 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -780,7 +780,7 @@ Deprecations - :meth:`Index.is_object` has been deprecated. Use :func:`pandas.api.types.is_object_dtype` instead (:issue:`50042`) - :meth:`Index.is_interval` has been deprecated. Use :func:`pandas.api.types.is_intterval_dtype` instead (:issue:`50042`) - Deprecated ``all`` and ``any`` reductions with ``datetime64`` and :class:`DatetimeTZDtype` dtypes, use e.g. ``(obj != pd.Timestamp(0), tz=obj.tz).all()`` instead (:issue:`34479`) -- +- Deprecated calling ``float`` or ``int`` on a single element :class:`Series` to return a ``float`` or ``int`` respectively. Extract the element before calling ``float`` or ``int`` instead (:issue:`51101`) .. --------------------------------------------------------------------------- .. _whatsnew_200.prior_deprecations: diff --git a/pandas/core/series.py b/pandas/core/series.py index abe31d0dbd52a..9a5412145366f 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -19,6 +19,7 @@ cast, overload, ) +import warnings import weakref import numpy as np @@ -81,6 +82,7 @@ Substitution, doc, ) +from pandas.util._exceptions import find_stack_level from pandas.util._validators import ( validate_ascending, validate_bool_kwarg, @@ -216,6 +218,13 @@ def _coerce_method(converter): def wrapper(self): if len(self) == 1: + warnings.warn( + f"Calling {converter.__name__} on a single element Series is " + "deprecated and will raise a TypeError in the future. " + f"Use {converter.__name__}(ser.iloc[0]) instead", + FutureWarning, + stacklevel=find_stack_level(), + ) return converter(self.iloc[0]) raise TypeError(f"cannot convert the series to {converter}") diff --git a/pandas/tests/apply/test_invalid_arg.py b/pandas/tests/apply/test_invalid_arg.py index 3f2e8e9ea07a6..101e7be70e691 100644 --- a/pandas/tests/apply/test_invalid_arg.py +++ b/pandas/tests/apply/test_invalid_arg.py @@ -277,7 +277,7 @@ def test_agg_none_to_type(): df = DataFrame({"a": [None]}) msg = re.escape("int() argument must be a string") with pytest.raises(TypeError, match=msg): - df.agg({"a": int}) + df.agg({"a": lambda x: int(x.iloc[0])}) def test_transform_none_to_type(): @@ -285,7 +285,7 @@ def test_transform_none_to_type(): df = DataFrame({"a": [None]}) msg = "argument must be a" with pytest.raises(TypeError, match=msg): - df.transform({"a": int}) + df.transform({"a": lambda x: int(x.iloc[0])}) @pytest.mark.parametrize( diff --git a/pandas/tests/series/test_api.py b/pandas/tests/series/test_api.py index 4852788ef2c06..5c3dfd246e9aa 100644 --- a/pandas/tests/series/test_api.py +++ b/pandas/tests/series/test_api.py @@ -287,3 +287,10 @@ def test_numeric_only(self, kernel, has_numeric_only, dtype): else: # reducer assert result == expected + + +@pytest.mark.parametrize("converter", [int, float, complex]) +def test_float_int_deprecated(converter): + # GH 51101 + with tm.assert_produces_warning(FutureWarning): + assert converter(Series([1])) == converter(1) diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index bd6db2befdb0b..49c5b78a48a9f 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -145,10 +145,6 @@ def test_scalar_conversion(self): scalar = Series(0.5) assert not isinstance(scalar, float) - # Coercion - assert float(Series([1.0])) == 1.0 - assert int(Series([1.0])) == 1 - def test_scalar_extension_dtype(self, ea_scalar_and_dtype): # GH 28401