From 8390193647993b0df3d92eff1dccf673d50d4b05 Mon Sep 17 00:00:00 2001 From: Brock Date: Thu, 6 Jan 2022 11:08:25 -0800 Subject: [PATCH] BUG: Series.__setitem__ positional raising ValuError --- doc/source/whatsnew/v1.5.0.rst | 2 +- pandas/core/series.py | 5 +++-- pandas/tests/series/indexing/test_setitem.py | 14 ++++++++++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index 7f2a1a9305039..5bf4d8536df4e 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -151,7 +151,7 @@ Interval Indexing ^^^^^^^^ -- +- Bug in :meth:`Series.__setitem__` with a non-integer :class:`Index` when using an integer key to set a value that cannot be set inplace where a ``ValueError`` was raised insead of casting to a common dtype (:issue:`45070`) - Missing diff --git a/pandas/core/series.py b/pandas/core/series.py index 7ca80601bbfd0..748b5f9f25656 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1098,8 +1098,9 @@ def __setitem__(self, key, value) -> None: FutureWarning, stacklevel=find_stack_level(), ) - # this is equivalent to self._values[key] = value - self._mgr.setitem_inplace(key, value) + # can't use _mgr.setitem_inplace yet bc could have *both* + # KeyError and then ValueError, xref GH#45070 + self._set_values(key, value) else: # GH#12862 adding a new key to the Series self.loc[key] = value diff --git a/pandas/tests/series/indexing/test_setitem.py b/pandas/tests/series/indexing/test_setitem.py index fb07b28c5a54f..d162627d72a50 100644 --- a/pandas/tests/series/indexing/test_setitem.py +++ b/pandas/tests/series/indexing/test_setitem.py @@ -1350,8 +1350,9 @@ def test_6942(indexer_al): assert df.iloc[0, 0] == t2 -@pytest.mark.xfail(reason="Doesn't catch when numpy raises.") -def test_45070(): +def test_setitem_positional_with_casting(): + # GH#45070 case where in __setitem__ we get a KeyError, then when + # we fallback we *also* get a ValueError if we try to set inplace. ser = Series([1, 2, 3], index=["a", "b", "c"]) ser[0] = "X" @@ -1359,6 +1360,15 @@ def test_45070(): tm.assert_series_equal(ser, expected) +def test_setitem_positional_float_into_int_coerces(): + # Case where we hit a KeyError and then trying to set in-place incorrectly + # casts a float to an int + ser = Series([1, 2, 3], index=["a", "b", "c"]) + ser[0] = 1.5 + expected = Series([1.5, 2, 3], index=["a", "b", "c"]) + tm.assert_series_equal(ser, expected) + + @pytest.mark.xfail(reason="unwanted upcast") def test_15231(): df = DataFrame([[1, 2], [3, 4]], columns=["a", "b"])