Skip to content

Commit

Permalink
BUG: Fix ma coercion list-of-ma-arrays if they do not cast to bool
Browse files Browse the repository at this point in the history
There was a regression here due to force casting to bool, but if that
happens to fail (it does, but should not for strings). The mask
would just be dropped.

Of course masked arrays are held together by faith here, but its
a regression.

Closes gh-18551
  • Loading branch information
seberg authored and charris committed Mar 17, 2021
1 parent b947264 commit 75e13a6
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
5 changes: 3 additions & 2 deletions numpy/ma/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2859,8 +2859,9 @@ def __new__(cls, data=None, mask=nomask, dtype=None, copy=False,
elif isinstance(data, (tuple, list)):
try:
# If data is a sequence of masked array
mask = np.array([getmaskarray(np.asanyarray(m, dtype=mdtype))
for m in data], dtype=mdtype)
mask = np.array(
[getmaskarray(np.asanyarray(m, dtype=_data.dtype))
for m in data], dtype=mdtype)
except ValueError:
# If data is nested
mask = nomask
Expand Down
19 changes: 19 additions & 0 deletions numpy/ma/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,25 @@ def test_creation_with_list_of_maskedarrays(self):
assert_equal(data, [[0, 1, 2, 3, 4], [4, 3, 2, 1, 0]])
assert_(data.mask is nomask)

def test_creation_with_list_of_maskedarrays_no_bool_cast(self):
# Tests the regression in gh-18551
masked_str = np.ma.masked_array(['a', 'b'], mask=[True, False])
normal_int = np.arange(2)
res = np.ma.asarray([masked_str, normal_int])
assert_array_equal(res.mask, [[True, False], [False, False]])
# Te above only failed due a long chain of oddity, try also with
# an object array that cannot be converted to bool always:
class NotBool():
def __bool__(self):
raise ValueError("not a bool!")
masked_obj = np.ma.masked_array([NotBool(), 'b'], mask=[True, False])
# Check that the NotBool actually fails like we would expect:
with pytest.raises(ValueError, match="not a bool!"):
np.asarray([masked_obj], dtype=bool)

res = np.ma.asarray([masked_obj, normal_int])
assert_array_equal(res.mask, [[True, False], [False, False]])

def test_creation_from_ndarray_with_padding(self):
x = np.array([('A', 0)], dtype={'names':['f0','f1'],
'formats':['S4','i8'],
Expand Down

0 comments on commit 75e13a6

Please sign in to comment.