From 5e50d3f3d2b0ee65f0d5bfda0c6da47ffd39dcfe Mon Sep 17 00:00:00 2001 From: Richard Shadrach <45562402+rhshadrach@users.noreply.github.com> Date: Thu, 2 Jan 2025 19:03:34 -0500 Subject: [PATCH] BUG/TST (string dtype): raise proper TypeError in interpolate (#60637) * TST(string dtype): Resolve xfail for interpolate * Adjust arrow tests * Fixup for NumPyExtensionArray * Use tm.shares_memory --- pandas/core/arrays/arrow/array.py | 2 +- pandas/core/arrays/numpy_.py | 3 +++ pandas/tests/extension/test_arrow.py | 4 +++- pandas/tests/frame/methods/test_interpolate.py | 13 +++++-------- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/pandas/core/arrays/arrow/array.py b/pandas/core/arrays/arrow/array.py index afa219f611992..4d9c8eb3a41b6 100644 --- a/pandas/core/arrays/arrow/array.py +++ b/pandas/core/arrays/arrow/array.py @@ -2160,7 +2160,7 @@ def interpolate( """ # NB: we return type(self) even if copy=False if not self.dtype._is_numeric: - raise ValueError("Values must be numeric.") + raise TypeError(f"Cannot interpolate with {self.dtype} dtype") if ( not pa_version_under13p0 diff --git a/pandas/core/arrays/numpy_.py b/pandas/core/arrays/numpy_.py index f222d6e1b328b..ac0823ed903b3 100644 --- a/pandas/core/arrays/numpy_.py +++ b/pandas/core/arrays/numpy_.py @@ -292,6 +292,9 @@ def interpolate( See NDFrame.interpolate.__doc__. """ # NB: we return type(self) even if copy=False + if not self.dtype._is_numeric: + raise TypeError(f"Cannot interpolate with {self.dtype} dtype") + if not copy: out_data = self._ndarray else: diff --git a/pandas/tests/extension/test_arrow.py b/pandas/tests/extension/test_arrow.py index 6dd1f3f15bc15..c5f5a65b77eea 100644 --- a/pandas/tests/extension/test_arrow.py +++ b/pandas/tests/extension/test_arrow.py @@ -3451,7 +3451,9 @@ def test_string_to_datetime_parsing_cast(): ) def test_interpolate_not_numeric(data): if not data.dtype._is_numeric: - with pytest.raises(ValueError, match="Values must be numeric."): + ser = pd.Series(data) + msg = re.escape(f"Cannot interpolate with {ser.dtype} dtype") + with pytest.raises(TypeError, match=msg): pd.Series(data).interpolate() diff --git a/pandas/tests/frame/methods/test_interpolate.py b/pandas/tests/frame/methods/test_interpolate.py index b8a34d5eaa226..09d1cc9a479b2 100644 --- a/pandas/tests/frame/methods/test_interpolate.py +++ b/pandas/tests/frame/methods/test_interpolate.py @@ -64,11 +64,7 @@ def test_interpolate_inplace(self, frame_or_series, request): assert np.shares_memory(orig, obj.values) assert orig.squeeze()[1] == 1.5 - # TODO(infer_string) raise proper TypeError in case of string dtype - @pytest.mark.xfail( - using_string_dtype(), reason="interpolate doesn't work for string" - ) - def test_interp_basic(self): + def test_interp_basic(self, using_infer_string): df = DataFrame( { "A": [1, 2, np.nan, 4], @@ -77,7 +73,8 @@ def test_interp_basic(self): "D": list("abcd"), } ) - msg = "DataFrame cannot interpolate with object dtype" + dtype = "str" if using_infer_string else "object" + msg = f"[Cc]annot interpolate with {dtype} dtype" with pytest.raises(TypeError, match=msg): df.interpolate() @@ -87,8 +84,8 @@ def test_interp_basic(self): df.interpolate(inplace=True) # check we DID operate inplace - assert np.shares_memory(df["C"]._values, cvalues) - assert np.shares_memory(df["D"]._values, dvalues) + assert tm.shares_memory(df["C"]._values, cvalues) + assert tm.shares_memory(df["D"]._values, dvalues) @pytest.mark.xfail( using_string_dtype(), reason="interpolate doesn't work for string"