numpy/numpy — pull request #4576 by mhvk (2014-04-01 20:41:01+00:00)
Title: BUG Ensure more complicated base classes work with MaskedArray str, repr

(@charris: this is one of the corrections I mentioned in #3907 that we need to make to MaskedArray to get astropy's more complicated ndarray subclasses to be used as base classes.)

Currently, `repr(ma)` and `str(ma)` do not deal well with base classes that redefine `__repr__` to use a different way to print the class name, or that override `__setitem__` to do checks on values, respectively. This PR corrects this, by simply letting `__repr__` use `__class__.__name__` instead of trying to be smart in how to get it, and by ensuring that `__str__` inserts `masked_print_option` in an `ndarray` view of the object array that is created for string output (the current way `__str__` is handled is perhaps too clever a trick, but I'm not quite sure yet how to make it safer; my PR should at least help a little.).

Specifically, currently, after defining:
```
import numpy as np

class ComplicatedSubArray(np.ndarray):
def __new__(cls, arr):
return np.asanyarray(arr).view(cls)

def __str__(self):
return 'myprefix {0} mypostfix'.format(
super(ComplicatedSubArray, self).__str__())

def __repr__(self):
# Return a repr that does not start with 'name('
return '<{0} {1}>'.format(self.__class__.__name__, self)

def __setitem__(self, item, value):
# this ensures direct assignment to masked_print_option will fail
if not isinstance(value, ComplicatedSubArray):
raise ValueError("Can only set to MySubArray values")
super(ComplicatedSubArray, self).__setitem__(item, value)

xcsub = ComplicatedSubArray(np.arange(5))
mxcsub1 = np.ma.masked_array(xcsub)
mxcsub2 = np.ma.masked_array(xcsub, mask=[True, False, True, False, False])
```
one gets
```
In [15]: mxcsub1
Out[15]:
masked_(data = myprefix [0 1 2 3 4] mypostfix,
mask = False,
fill_value = 999999)
In [16]: mxcsub2
Out[16]:
.
.
.
ValueError: Can only set to MySubArray values
```

With the PR,
```
In [2]: mxcsub1
Out[2]:
masked_ComplicatedSubArray(data = myprefix [0 1 2 3 4] mypostfix,
mask = False,
fill_value = 999999)
In [3]: mxcsub2
Out[3]:
masked_ComplicatedSubArray(data = myprefix [-- 1 -- 3 4] mypostfix,
mask = [ True False True False False],
fill_value = 999999)
```