Repository: numpy/numpy

Issue:
String representation of exotic masked structured arrays with ndim=0 fails with ValueError
Even after the fixes in pull request #6094, there are still some cases where string representation fails, in particular where some members of a structured array are multi-dimensional:

```
In [1]: ar = array((0, [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]], 0.0), dtype="int, (2,3)float, float")

In [2]: arm = ma.masked_array(ar)

In [3]: x = str(arm)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-f98bbc78fe11> in <module>()
----> 1 x = str(arm)

/home/users/gholl/venv/stable-3.5/lib/python3.5/site-packages/numpy/ma/core.py in __str__(self)
   3698                 if m.shape == ():
   3699                     if m.dtype.names:
-> 3700                         m = m.view((bool, len(m.dtype)))
   3701                         if m.any():
   3702                             return str(tuple((f if _m else _d) for _d, _m in

ValueError: new type not compatible with array.
```

And without the `m = m.view(...)` line, `m.any()` would fail with `TypeError: cannot perform reduce with flexible type`.

A bit more of an overview, illustrating what we would like to see:

```
In [26]: m1 = ma.masked_array(data=[(0, [0, 0], 0)], mask=[(True,[False, True],True)], dtype="int, (2)float, int")

In [27]: m2 = ma.masked_array(data=(0, [0, 0], 0), mask=(True,[False, True],True), dtype="int, (2)float, int")

In [28]: str(m1)
Out[28]: '[(--, [0.0, --], --)]'

In [29]: str(m1[0])
Out[29]: '(--, [0.0, --], --)'

In [30]: str(m2)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-30-3ae8d0bbdb8a> in <module>()
----> 1 str(m2)

/home/users/gholl/venv/stable-3.5/lib/python3.5/site-packages/numpy/ma/core.py in __str__(self)
   3698                 if m.shape == ():
   3699                     if m.dtype.names:
-> 3700                         m = m.view((bool, len(m.dtype)))
   3701                         if m.any():
   3702                             return str(tuple((f if _m else _d) for _d, _m in

ValueError: new type not compatible with array.

In [34]: numpy.ma.core.mvoid.__str__(m2)
Out[34]: '(--, [0.0, --], --)'
```



Discussion:
The stack trace was off in the first version of this report, now it points to the correct place.


Resolving patch:
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -3695,7 +3695,7 @@ def __str__(self):
             if m is nomask:
                 res = self._data
             else:
-                if m.shape == ():
+                if m.shape == () and m.itemsize==len(m.dtype):
                     if m.dtype.names:
                         m = m.view((bool, len(m.dtype)))
                         if m.any():


Test patch:
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -625,6 +625,18 @@ def test_fancy_printoptions(self):
         control = "[(--, (2, --)) (4, (--, 6.0))]"
         assert_equal(str(test), control)
 
+        # Test 0-d array with multi-dimensional dtype
+        t_2d0 = masked_array(data = (0, [[0.0, 0.0, 0.0],
+                                        [0.0, 0.0, 0.0]],
+                                    0.0),
+                             mask = (False, [[True, False, True],
+                                             [False, False, True]],
+                                     False),
+                             dtype = "int, (2,3)float, float")
+        control = "(0, [[--, 0.0, --], [0.0, 0.0, --]], 0.0)"
+        assert_equal(str(t_2d0), control)
+
+
     def test_flatten_structured_array(self):
         # Test flatten_structured_array on arrays
         # On ndarray