Skip to content

Commit 85cadf8

Browse files
mzeitlin11yeshsurya
authored andcommitted
BUG: isna not returning copy for MaskedArray (pandas-dev#41020)
1 parent 8d96556 commit 85cadf8

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

doc/source/whatsnew/v1.3.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,7 @@ Missing
749749
- Bug in :class:`Grouper` now correctly propagates ``dropna`` argument and :meth:`DataFrameGroupBy.transform` now correctly handles missing values for ``dropna=True`` (:issue:`35612`)
750750
- Bug in :func:`isna`, and :meth:`Series.isna`, :meth:`Index.isna`, :meth:`DataFrame.isna` (and the corresponding ``notna`` functions) not recognizing ``Decimal("NaN")`` objects (:issue:`39409`)
751751
- Bug in :meth:`DataFrame.fillna` not accepting dictionary for ``downcast`` keyword (:issue:`40809`)
752+
- Bug in :func:`isna` not returning a copy of the mask for nullable types, causing any subsequent mask modification to change the original array (:issue:`40935`)
752753

753754
MultiIndex
754755
^^^^^^^^^^

pandas/core/arrays/masked.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ def _hasna(self) -> bool:
352352
return self._mask.any() # type: ignore[return-value]
353353

354354
def isna(self) -> np.ndarray:
355-
return self._mask
355+
return self._mask.copy()
356356

357357
@property
358358
def _na_value(self):

pandas/tests/extension/base/missing.py

+13
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import numpy as np
2+
import pytest
23

34
import pandas as pd
45
import pandas._testing as tm
6+
from pandas.api.types import is_sparse
57
from pandas.tests.extension.base.base import BaseExtensionTests
68

79

@@ -21,6 +23,17 @@ def test_isna(self, data_missing):
2123
expected = pd.Series([], dtype=bool)
2224
self.assert_series_equal(result, expected)
2325

26+
@pytest.mark.parametrize("na_func", ["isna", "notna"])
27+
def test_isna_returns_copy(self, data_missing, na_func):
28+
result = pd.Series(data_missing)
29+
expected = result.copy()
30+
mask = getattr(result, na_func)()
31+
if is_sparse(mask):
32+
mask = np.array(mask)
33+
34+
mask[:] = True
35+
self.assert_series_equal(result, expected)
36+
2437
def test_dropna_array(self, data_missing):
2538
result = data_missing.dropna()
2639
expected = data_missing[[1]]

0 commit comments

Comments
 (0)