Skip to content

Commit d25cb7f

Browse files
authored
REGR: Fix assignment bug for unary operators (#39971)
1 parent e19403d commit d25cb7f

File tree

4 files changed

+17
-3
lines changed

4 files changed

+17
-3
lines changed

doc/source/whatsnew/v1.2.3.rst

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Fixed regressions
1616
~~~~~~~~~~~~~~~~~
1717

1818
- Fixed regression in :meth:`~DataFrame.to_excel` raising ``KeyError`` when giving duplicate columns with ``columns`` attribute (:issue:`39695`)
19+
- Fixed regression in :class:`IntegerArray` unary ops propagating mask on assignment (:issue:`39943`)
1920
- Fixed regression in :meth:`DataFrame.__setitem__` not aligning :class:`DataFrame` on right-hand side for boolean indexer (:issue:`39931`)
2021

2122
.. ---------------------------------------------------------------------------

pandas/core/arrays/integer.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -316,13 +316,13 @@ def __init__(self, values: np.ndarray, mask: np.ndarray, copy: bool = False):
316316
super().__init__(values, mask, copy=copy)
317317

318318
def __neg__(self):
319-
return type(self)(-self._data, self._mask)
319+
return type(self)(-self._data, self._mask.copy())
320320

321321
def __pos__(self):
322322
return self
323323

324324
def __abs__(self):
325-
return type(self)(np.abs(self._data), self._mask)
325+
return type(self)(np.abs(self._data), self._mask.copy())
326326

327327
@classmethod
328328
def _from_sequence(

pandas/core/arrays/masked.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ def __len__(self) -> int:
172172
return len(self._data)
173173

174174
def __invert__(self: BaseMaskedArrayT) -> BaseMaskedArrayT:
175-
return type(self)(~self._data, self._mask)
175+
return type(self)(~self._data, self._mask.copy())
176176

177177
def to_numpy(
178178
self,

pandas/tests/arrays/masked/test_arithmetic.py

+13
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,16 @@ def test_error_len_mismatch(data, all_arithmetic_operators):
162162
s = pd.Series(data)
163163
with pytest.raises(ValueError, match="Lengths must match"):
164164
op(s, other)
165+
166+
167+
@pytest.mark.parametrize("op", ["__neg__", "__abs__", "__invert__"])
168+
@pytest.mark.parametrize(
169+
"values, dtype", [([1, 2, 3], "Int64"), ([True, False, True], "boolean")]
170+
)
171+
def test_unary_op_does_not_propagate_mask(op, values, dtype):
172+
# https://github.com/pandas-dev/pandas/issues/39943
173+
s = pd.Series(values, dtype=dtype)
174+
result = getattr(s, op)()
175+
expected = result.copy(deep=True)
176+
s[0] = None
177+
tm.assert_series_equal(result, expected)

0 commit comments

Comments
 (0)