summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2016-02-20 20:35:13 -0700
committerCharles Harris <charlesr.harris@gmail.com>2016-02-20 20:35:13 -0700
commit710ec5667e31e640695c61f04136230f359ea07b (patch)
tree6a7233327666c6ae913c3b3ee0904e0d61731a0a
parent6d3b34fed6d5c1af6eb02cd47d31ee48a15b582d (diff)
parentc104112d27922208d980ff8afe6e5132731823c9 (diff)
downloadnumpy-710ec5667e31e640695c61f04136230f359ea07b.tar.gz
Merge pull request #7296 from mhvk/ma_ufuncs_subclasses
Revert part of #3907 which incorrectly propogated MaskedArray info.
-rw-r--r--numpy/ma/core.py15
-rw-r--r--numpy/ma/tests/test_subclassing.py20
2 files changed, 29 insertions, 6 deletions
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index 3dfe0c4e3..f3d30d15c 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -911,7 +911,7 @@ class _MaskedUnaryOperation:
# Transform to
masked_result = result.view(get_masked_subclass(a))
masked_result._mask = m
- masked_result._update_from(result)
+ masked_result._update_from(a)
return masked_result
def __str__(self):
@@ -999,7 +999,10 @@ class _MaskedBinaryOperation:
# Transforms to a (subclass of) MaskedArray
masked_result = result.view(get_masked_subclass(a, b))
masked_result._mask = m
- masked_result._update_from(result)
+ if isinstance(a, MaskedArray):
+ masked_result._update_from(a)
+ elif isinstance(b, MaskedArray):
+ masked_result._update_from(b)
return masked_result
def reduce(self, target, axis=0, dtype=None):
@@ -1030,7 +1033,6 @@ class _MaskedBinaryOperation:
return tr
masked_tr = tr.view(tclass)
masked_tr._mask = mr
- masked_tr._update_from(tr)
return masked_tr
def outer(self, a, b):
@@ -1056,7 +1058,6 @@ class _MaskedBinaryOperation:
return d
masked_d = d.view(get_masked_subclass(a, b))
masked_d._mask = m
- masked_d._update_from(d)
return masked_d
def accumulate(self, target, axis=0):
@@ -1068,7 +1069,6 @@ class _MaskedBinaryOperation:
t = filled(target, self.filly)
result = self.f.accumulate(t, axis)
masked_result = result.view(tclass)
- masked_result._update_from(result)
return masked_result
def __str__(self):
@@ -1145,7 +1145,10 @@ class _DomainedBinaryOperation:
# Transforms to a (subclass of) MaskedArray
masked_result = result.view(get_masked_subclass(a, b))
masked_result._mask = m
- masked_result._update_from(result)
+ if isinstance(a, MaskedArray):
+ masked_result._update_from(a)
+ elif isinstance(b, MaskedArray):
+ masked_result._update_from(b)
return masked_result
def __str__(self):
diff --git a/numpy/ma/tests/test_subclassing.py b/numpy/ma/tests/test_subclassing.py
index 68734425c..814ed5977 100644
--- a/numpy/ma/tests/test_subclassing.py
+++ b/numpy/ma/tests/test_subclassing.py
@@ -47,6 +47,14 @@ class SubArray(np.ndarray):
subarray = SubArray
+class SubMaskedArray(MaskedArray):
+ """Pure subclass of MaskedArray, keeping some info on subclass."""
+ def __new__(cls, info=None, **kwargs):
+ obj = super(SubMaskedArray, cls).__new__(cls, **kwargs)
+ obj._optinfo['info'] = info
+ return obj
+
+
class MSubArray(SubArray, MaskedArray):
def __new__(cls, data, info={}, mask=nomask):
@@ -332,6 +340,18 @@ class TestSubclassing(TestCase):
mxcsub = masked_array(xcsub, mask=[True, False, True, False, False])
self.assertTrue(str(mxcsub) == 'myprefix [-- 1 -- 3 4] mypostfix')
+ def test_pure_subclass_info_preservation(self):
+ # Test that ufuncs and methods conserve extra information consistently;
+ # see gh-7122.
+ arr1 = SubMaskedArray('test', data=[1,2,3,4,5,6])
+ arr2 = SubMaskedArray(data=[0,1,2,3,4,5])
+ diff1 = np.subtract(arr1, arr2)
+ self.assertTrue('info' in diff1._optinfo)
+ self.assertTrue(diff1._optinfo['info'] == 'test')
+ diff2 = arr1 - arr2
+ self.assertTrue('info' in diff2._optinfo)
+ self.assertTrue(diff2._optinfo['info'] == 'test')
+
###############################################################################
if __name__ == '__main__':