Skip to content

Commit aa97540

Browse files
authored
BUG: Series[bool].__setitem__(scalar, non_bool) (pandas-dev#39478)
1 parent d284250 commit aa97540

File tree

3 files changed

+27
-23
lines changed

3 files changed

+27
-23
lines changed

pandas/core/dtypes/cast.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1904,12 +1904,15 @@ def validate_numeric_casting(dtype: np.dtype, value: Scalar) -> None:
19041904
):
19051905
raise ValueError("Cannot assign nan to integer series")
19061906

1907-
if dtype.kind in ["i", "u", "f", "c"]:
1907+
elif dtype.kind in ["i", "u", "f", "c"]:
19081908
if is_bool(value) or isinstance(value, np.timedelta64):
19091909
# numpy will cast td64 to integer if we're not careful
19101910
raise ValueError(
19111911
f"Cannot assign {type(value).__name__} to float/integer series"
19121912
)
1913+
elif dtype.kind == "b":
1914+
if is_scalar(value) and not is_bool(value):
1915+
raise ValueError(f"Cannot assign {type(value).__name__} to bool series")
19131916

19141917

19151918
def can_hold_element(dtype: np.dtype, element: Any) -> bool:

pandas/tests/indexing/test_coercion.py

+7-22
Original file line numberDiff line numberDiff line change
@@ -161,34 +161,19 @@ def test_setitem_series_complex128(self, val, exp_dtype):
161161
@pytest.mark.parametrize(
162162
"val,exp_dtype",
163163
[
164-
(1, np.int64),
165-
(3, np.int64),
166-
(1.1, np.float64),
167-
(1 + 1j, np.complex128),
164+
(1, object),
165+
("3", object),
166+
(3, object),
167+
(1.1, object),
168+
(1 + 1j, object),
168169
(True, np.bool_),
169170
],
170171
)
171-
def test_setitem_series_bool(self, val, exp_dtype, request):
172+
def test_setitem_series_bool(self, val, exp_dtype):
172173
obj = pd.Series([True, False, True, False])
173174
assert obj.dtype == np.bool_
174175

175-
mark = None
176-
if exp_dtype is np.int64:
177-
exp = pd.Series([True, True, True, False])
178-
self._assert_setitem_series_conversion(obj, val, exp, np.bool_)
179-
mark = pytest.mark.xfail(reason="TODO_GH12747 The result must be int")
180-
elif exp_dtype is np.float64:
181-
exp = pd.Series([True, True, True, False])
182-
self._assert_setitem_series_conversion(obj, val, exp, np.bool_)
183-
mark = pytest.mark.xfail(reason="TODO_GH12747 The result must be float")
184-
elif exp_dtype is np.complex128:
185-
exp = pd.Series([True, True, True, False])
186-
self._assert_setitem_series_conversion(obj, val, exp, np.bool_)
187-
mark = pytest.mark.xfail(reason="TODO_GH12747 The result must be complex")
188-
if mark is not None:
189-
request.node.add_marker(mark)
190-
191-
exp = pd.Series([True, val, True, False])
176+
exp = pd.Series([True, val, True, False], dtype=exp_dtype)
192177
self._assert_setitem_series_conversion(obj, val, exp, exp_dtype)
193178

194179
@pytest.mark.parametrize(

pandas/tests/series/indexing/test_setitem.py

+16
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,22 @@ def test_setitem_dt64_into_int_series(self, dtype):
281281
ser[:-1] = np.array([val, val])
282282
tm.assert_series_equal(ser, expected)
283283

284+
@pytest.mark.parametrize("unique", [True, False])
285+
@pytest.mark.parametrize("val", [3, 3.0, "3"], ids=type)
286+
def test_setitem_non_bool_into_bool(self, val, indexer_sli, unique):
287+
# dont cast these 3-like values to bool
288+
ser = Series([True, False])
289+
if not unique:
290+
ser.index = [1, 1]
291+
292+
indexer_sli(ser)[1] = val
293+
assert type(ser.iloc[1]) == type(val)
294+
295+
expected = Series([True, val], dtype=object, index=ser.index)
296+
if not unique and indexer_sli is not tm.iloc:
297+
expected = Series([val, val], dtype=object, index=[1, 1])
298+
tm.assert_series_equal(ser, expected)
299+
284300

285301
class SetitemCastingEquivalents:
286302
"""

0 commit comments

Comments
 (0)