From c104112d27922208d980ff8afe6e5132731823c9 Mon Sep 17 00:00:00 2001 From: Marten van Kerkwijk Date: Sat, 20 Feb 2016 20:03:40 -0500 Subject: [PATCH] Revert part of #3907 which incorrectly propogated MaskedArray info. --- numpy/ma/core.py | 15 +++++++++------ numpy/ma/tests/test_subclassing.py | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/numpy/ma/core.py b/numpy/ma/core.py index 3dfe0c4e359c..f3d30d15c441 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -911,7 +911,7 @@ def __call__(self, a, *args, **kwargs): # 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 @@ def __call__(self, a, b, *args, **kwargs): # 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 @@ def reduce(self, target, axis=0, dtype=None): 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 @@ def outer(self, a, b): 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 @@ def accumulate(self, target, axis=0): 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 @@ def __call__(self, a, b, *args, **kwargs): # 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 68734425c715..814ed5977fed 100644 --- a/numpy/ma/tests/test_subclassing.py +++ b/numpy/ma/tests/test_subclassing.py @@ -47,6 +47,14 @@ def __iadd__(self, other): 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 @@ def test_subclass_str(self): 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__':