Skip to content

BUG: setting non-string value into StringArray raises ValueError instead of TypeError #51191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/arrays/string_.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions pandas/core/arrays/string_arrow.py
Original file line number Diff line number Diff line change
Expand Up @@ -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_]:
Expand Down
10 changes: 4 additions & 6 deletions pandas/tests/arrays/string_/test_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])


Expand Down Expand Up @@ -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)


Expand Down Expand Up @@ -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


Expand Down