diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index ef6bb1340dc69..64f21e027e048 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -1324,6 +1324,7 @@ ExtensionArray - Bug in :meth:`api.types.is_numeric_dtype` where a custom :class:`ExtensionDtype` would not return ``True`` if ``_is_numeric`` returned ``True`` (:issue:`50563`) - Bug in :meth:`api.types.is_integer_dtype`, :meth:`api.types.is_unsigned_integer_dtype`, :meth:`api.types.is_signed_integer_dtype`, :meth:`api.types.is_float_dtype` where a custom :class:`ExtensionDtype` would not return ``True`` if ``kind`` returned the corresponding NumPy type (:issue:`50667`) - Bug in :class:`Series` constructor unnecessarily overflowing for nullable unsigned integer dtypes (:issue:`38798`, :issue:`25880`) +- Bug in setting non-string value into ``StringArray`` raising ``ValueError`` instead of ``TypeError`` (:issue:`49632`) Styler ^^^^^^ diff --git a/pandas/core/arrays/string_.py b/pandas/core/arrays/string_.py index 9b26db07fc28f..952fd3a19daae 100644 --- a/pandas/core/arrays/string_.py +++ b/pandas/core/arrays/string_.py @@ -414,14 +414,14 @@ def __setitem__(self, key, value): if isna(value): value = libmissing.NA elif not isinstance(value, str): - raise ValueError( + raise TypeError( f"Cannot set non-string value '{value}' into a StringArray." ) else: if not is_array_like(value): value = np.asarray(value, dtype=object) if len(value) and not lib.is_string_array(value, skipna=True): - raise ValueError("Must provide strings.") + raise TypeError("Must provide strings.") value[isna(value)] = libmissing.NA diff --git a/pandas/core/arrays/string_arrow.py b/pandas/core/arrays/string_arrow.py index 4aebe61412866..92385b64f5c70 100644 --- a/pandas/core/arrays/string_arrow.py +++ b/pandas/core/arrays/string_arrow.py @@ -163,13 +163,13 @@ def _maybe_convert_setitem_value(self, value): if isna(value): value = None elif not isinstance(value, str): - raise ValueError("Scalar must be NA or str") + raise TypeError("Scalar must be NA or str") else: value = np.array(value, dtype=object, copy=True) value[isna(value)] = None for v in value: if not (v is None or isinstance(v, str)): - raise ValueError("Scalar must be NA or str") + raise TypeError("Scalar must be NA or str") return super()._maybe_convert_setitem_value(value) def isin(self, values) -> npt.NDArray[np.bool_]: diff --git a/pandas/tests/arrays/string_/test_string.py b/pandas/tests/arrays/string_/test_string.py index da5fc46c03d92..cced9cfe8cb20 100644 --- a/pandas/tests/arrays/string_/test_string.py +++ b/pandas/tests/arrays/string_/test_string.py @@ -53,14 +53,14 @@ def test_setitem_validates(cls): msg = "Cannot set non-string value '10' into a StringArray." else: msg = "Scalar must be NA or str" - with pytest.raises(ValueError, match=msg): + with pytest.raises(TypeError, match=msg): arr[0] = 10 if cls is pd.arrays.StringArray: msg = "Must provide strings." else: msg = "Scalar must be NA or str" - with pytest.raises(ValueError, match=msg): + with pytest.raises(TypeError, match=msg): arr[:] = np.array([1, 2]) @@ -403,12 +403,10 @@ def test_fillna_args(dtype, request): tm.assert_extension_array_equal(res, expected) if dtype.storage == "pyarrow": - err = TypeError msg = "Invalid value '1' for dtype string" else: - err = ValueError msg = "Cannot set non-string value '1' into a StringArray." - with pytest.raises(err, match=msg): + with pytest.raises(TypeError, match=msg): arr.fillna(value=1) @@ -574,7 +572,7 @@ def test_setitem_scalar_with_mask_validation(dtype): msg = "Cannot set non-string value" else: msg = "Scalar must be NA or str" - with pytest.raises(ValueError, match=msg): + with pytest.raises(TypeError, match=msg): ser[mask] = 1