summaryrefslogtreecommitdiff
path: root/numpy/ma
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/ma')
-rw-r--r--numpy/ma/core.py31
-rw-r--r--numpy/ma/tests/test_core.py11
2 files changed, 29 insertions, 13 deletions
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index 9ae225728..472b04429 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -6184,11 +6184,11 @@ isMA = isMaskedArray # backward compatibility
class MaskedConstant(MaskedArray):
-
+ # the lone np.ma.masked instance
__singleton = None
- def __new__(self):
- if self.__singleton is None:
+ def __new__(cls):
+ if cls.__singleton is None:
# We define the masked singleton as a float for higher precedence.
# Note that it can be tricky sometimes w/ type comparison
data = np.array(0.)
@@ -6198,10 +6198,12 @@ class MaskedConstant(MaskedArray):
data.flags.writeable = False
mask.flags.writeable = False
- masked = MaskedArray(data, mask=mask)
- self.__singleton = masked.view(self)
+ # don't fall back on MaskedArray.__new__(MaskedConstant), since
+ # that might confuse it - this way, the construction is entirely
+ # within our control
+ cls.__singleton = MaskedArray(data, mask=mask).view(cls)
- return self.__singleton
+ return cls.__singleton
def __array_finalize__(self, obj):
if self.__singleton is None:
@@ -6215,7 +6217,7 @@ class MaskedConstant(MaskedArray):
# everywhere else, we want to downcast to MaskedArray, to prevent a
# duplicate maskedconstant.
self.__class__ = MaskedArray
- self.__array_finalize__(obj)
+ MaskedArray.__array_finalize__(self, obj)
def __array_prepare__(self, obj, context=None):
return self.view(MaskedArray).__array_prepare__(obj, context)
@@ -6227,10 +6229,10 @@ class MaskedConstant(MaskedArray):
return str(masked_print_option._display)
def __repr__(self):
- if self is masked:
+ if self is self.__singleton:
return 'masked'
else:
- # something is wrong, make it obvious
+ # it's a subclass, or something is wrong, make it obvious
return object.__repr__(self)
def __reduce__(self):
@@ -6240,9 +6242,16 @@ class MaskedConstant(MaskedArray):
# inplace operations have no effect. We have to override them to avoid
# trying to modify the readonly data and mask arrays
- def __inop(self, other):
+ def __iop__(self, other):
return self
- __iadd__ = __isub__ = __imul__ = __ifloordiv__ = __itruediv__ = __ipow__ = __inop
+ __iadd__ = \
+ __isub__ = \
+ __imul__ = \
+ __ifloordiv__ = \
+ __itruediv__ = \
+ __ipow__ = \
+ __iop__
+ del __iop__ # don't leave this around
masked = masked_singleton = MaskedConstant()
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
index bf83461d7..69a3a0dc4 100644
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -4762,9 +4762,16 @@ class TestMaskedConstant(TestCase):
assert_equal(np.ma.masked.mask, True)
def test_no_copies(self):
+ # when making a view or a copy, downcast to MaskedArray
MC = np.ma.core.MaskedConstant
- assert_(not isinstance(np.ma.masked[...], MC))
- assert_(not isinstance(np.ma.masked.copy(), MC))
+
+ m_sl = np.ma.masked[...]
+ assert_equal(type(m_sl), np.ma.MaskedArray)
+ assert_equal(m_sl.mask, True)
+
+ m_copy = np.ma.masked.copy()
+ assert_equal(type(m_copy), np.ma.MaskedArray)
+ # assert_equal(m_copy.mask, True) - gh-9430
def test_immutable(self):
assert_raises(ValueError, operator.setitem, np.ma.masked.data, (), 1)