summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/ma/core.py41
-rw-r--r--numpy/ma/tests/test_core.py15
2 files changed, 35 insertions, 21 deletions
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index 5ed086db3..d4c4c4437 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -215,7 +215,7 @@ def _recursive_fill_value(dtype, f):
"""
Recursively produce a fill value for `dtype`, calling f on scalar dtypes
"""
- if dtype.names:
+ if dtype.names is not None:
vals = tuple(_recursive_fill_value(dtype[name], f) for name in dtype.names)
return np.array(vals, dtype=dtype)[()] # decay to void scalar from 0d
elif dtype.subdtype:
@@ -433,7 +433,7 @@ def _recursive_set_fill_value(fillvalue, dt):
if cdtype.subdtype:
cdtype = cdtype.subdtype[0]
- if cdtype.names:
+ if cdtype.names is not None:
output_value.append(tuple(_recursive_set_fill_value(fval, cdtype)))
else:
output_value.append(np.array(fval, dtype=cdtype).item())
@@ -1282,7 +1282,7 @@ def _replace_dtype_fields_recursive(dtype, primitive_dtype):
_recurse = _replace_dtype_fields_recursive
# Do we have some name fields ?
- if dtype.names:
+ if dtype.names is not None:
descr = []
for name in dtype.names:
field = dtype.fields[name]
@@ -1547,7 +1547,7 @@ def _shrink_mask(m):
"""
Shrink a mask to nomask if possible
"""
- if not m.dtype.names and not m.any():
+ if m.dtype.names is None and not m.any():
return nomask
else:
return m
@@ -1733,7 +1733,7 @@ def mask_or(m1, m2, copy=False, shrink=True):
names = m1.dtype.names
for name in names:
current1 = m1[name]
- if current1.dtype.names:
+ if current1.dtype.names is not None:
_recursive_mask_or(current1, m2[name], newmask[name])
else:
umath.logical_or(current1, m2[name], newmask[name])
@@ -1750,7 +1750,7 @@ def mask_or(m1, m2, copy=False, shrink=True):
(dtype1, dtype2) = (getattr(m1, 'dtype', None), getattr(m2, 'dtype', None))
if (dtype1 != dtype2):
raise ValueError("Incompatible dtypes '%s'<>'%s'" % (dtype1, dtype2))
- if dtype1.names:
+ if dtype1.names is not None:
# Allocate an output mask array with the properly broadcast shape.
newmask = np.empty(np.broadcast(m1, m2).shape, dtype1)
_recursive_mask_or(m1, m2, newmask)
@@ -1793,7 +1793,7 @@ def flatten_mask(mask):
def _flatmask(mask):
"Flatten the mask and returns a (maybe nested) sequence of booleans."
mnames = mask.dtype.names
- if mnames:
+ if mnames is not None:
return [flatten_mask(mask[name]) for name in mnames]
else:
return mask
@@ -2429,7 +2429,7 @@ def _recursive_printoption(result, mask, printopt):
"""
names = result.dtype.names
- if names:
+ if names is not None:
for name in names:
curdata = result[name]
curmask = mask[name]
@@ -2481,7 +2481,7 @@ def _recursive_filled(a, mask, fill_value):
names = a.dtype.names
for name in names:
current = a[name]
- if current.dtype.names:
+ if current.dtype.names is not None:
_recursive_filled(current, mask[name], fill_value[name])
else:
np.copyto(current, fill_value[name], where=mask[name])
@@ -2868,12 +2868,12 @@ class MaskedArray(ndarray):
_data._mask = mask
_data._sharedmask = not copy
else:
- if _data.dtype.names:
+ if _data.dtype.names is not None:
def _recursive_or(a, b):
"do a|=b on each field of a, recursively"
for name in a.dtype.names:
(af, bf) = (a[name], b[name])
- if af.dtype.names:
+ if af.dtype.names is not None:
_recursive_or(af, bf)
else:
af |= bf
@@ -2960,7 +2960,7 @@ class MaskedArray(ndarray):
if isinstance(obj, ndarray):
# XX: This looks like a bug -- shouldn't it check self.dtype
# instead?
- if obj.dtype.names:
+ if obj.dtype.names is not None:
_mask = getmaskarray(obj)
else:
_mask = getmask(obj)
@@ -3009,7 +3009,7 @@ class MaskedArray(ndarray):
# When _mask.shape is not writable (because it's a void)
pass
# Finalize the fill_value for structured arrays
- if self.dtype.names:
+ if self.dtype.names is not None:
if self._fill_value is None:
self._fill_value = _check_fill_value(None, self.dtype)
return
@@ -3293,15 +3293,14 @@ class MaskedArray(ndarray):
return
_dtype = _data.dtype
- nbfields = len(_dtype.names or ())
if value is masked:
# The mask wasn't set: create a full version.
if _mask is nomask:
_mask = self._mask = make_mask_none(self.shape, _dtype)
# Now, set the mask to its value.
- if nbfields:
- _mask[indx] = tuple([True] * nbfields)
+ if _dtype.names is not None:
+ _mask[indx] = tuple([True] * len(_dtype.names))
else:
_mask[indx] = True
return
@@ -3310,8 +3309,8 @@ class MaskedArray(ndarray):
dval = getattr(value, '_data', value)
# Get the _mask part of the new value
mval = getmask(value)
- if nbfields and mval is nomask:
- mval = tuple([False] * nbfields)
+ if _dtype.names is not None and mval is nomask:
+ mval = tuple([False] * len(_dtype.names))
if _mask is nomask:
# Set the data, then the mask
_data[indx] = dval
@@ -3326,7 +3325,7 @@ class MaskedArray(ndarray):
indx = indx * umath.logical_not(_mask)
_data[indx] = dval
else:
- if nbfields:
+ if _dtype.names is not None:
err_msg = "Flexible 'hard' masks are not yet supported."
raise NotImplementedError(err_msg)
mindx = mask_or(_mask[indx], mval, copy=True)
@@ -3707,7 +3706,7 @@ class MaskedArray(ndarray):
if self is masked_singleton:
return np.asanyarray(fill_value)
- if m.dtype.names:
+ if m.dtype.names is not None:
result = self._data.copy('K')
_recursive_filled(result, self._mask, fill_value)
elif not m.any():
@@ -3977,7 +3976,7 @@ class MaskedArray(ndarray):
mask = mask_or(smask, omask, copy=True)
odata = getdata(other)
- if mask.dtype.names:
+ if mask.dtype.names is not None:
# For possibly masked structured arrays we need to be careful,
# since the standard structured array comparison will use all
# fields, masked or not. To avoid masked fields influencing the
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
index 51616f214..b086ec69c 100644
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -5016,3 +5016,18 @@ def test_astype():
x_f2 = np.array(x, dtype=x.dtype, order='F', subok=True)
assert_(x_f2.flags.f_contiguous)
assert_(x_f2.mask.flags.f_contiguous)
+
+
+def test_fieldless_void():
+ dt = np.dtype([]) # a void dtype with no fields
+ x = np.empty(4, dt)
+
+ # these arrays contain no values, so there's little to test - but this
+ # shouldn't crash
+ mx = np.ma.array(x)
+ assert_equal(mx.dtype, x.dtype)
+ assert_equal(mx.shape, x.shape)
+
+ mx = np.ma.array(x, mask=x)
+ assert_equal(mx.dtype, x.dtype)
+ assert_equal(mx.shape, x.shape)