Skip to content

BUG Ensure masked object arrays can always return single items. - #5962

Merged
charris merged 1 commit into
numpy:masterfrom
mhvk:ma-getitem-nomask-correction
Jun 18, 2015
Merged

charris merged 1 commit into
numpy:masterfrom
mhvk:ma-getitem-nomask-correction

Conversation

@mhvk

@mhvk mhvk commented Jun 12, 2015

Copy link
Copy Markdown
Contributor

For a masked array holding objects that themselves are arrays, when selecting a single item, it is treated as if it were a slice of the array and an attempt is made to set its mask. This was always a bug, but it become visible with a recent change to MaskedArray.__getitem__ (#4586) where it is attempted to change the shape of the mask (to help matrices, sigh, was not even part of PR initially!). With this PR, the treatment is the same as for other single items: one either gets the array stored in the object, or masked.

Test case that now works but used to fail:

mx1 = MaskedArray([1.], mask=[True])
mx2 = MaskedArray_array([1., 2.])
mx = MaskedArray([mx1, mx2], mask=[False, True])
mx[0]

@mhvk

mhvk commented Jun 12, 2015

Copy link
Copy Markdown
Contributor Author

p.s. Bug found by testing astropy -- see astropy/astropy#3848. It seems our test suite checks even the dark corners of numpy!

@embray

embray commented Jun 12, 2015

Copy link
Copy Markdown
Contributor

Would not be the first time we've tested out dark corners of Numpy :)

@charris

charris commented Jun 12, 2015

Copy link
Copy Markdown
Member

Probably a case where a little light pollution would be a good thing ;)

@seberg

seberg commented Jun 12, 2015

Copy link
Copy Markdown
Member

Just face it, you guys are basically the MA maintainers now ;)

@mhvk

mhvk commented Jun 12, 2015

Copy link
Copy Markdown
Contributor Author

Thanks but no thanks ;-) It does look like travis passes; I think this is fine, but is there anyone else that should have a look?

Comment thread numpy/ma/core.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is a second bugfix, unrelated to object arrays, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right -- did that in the process and forgot about it...

I'll add a test...

(BTW, shall I volunteer you for maintainer........)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it seems one cannot initialise a MaskedArray with record type and nomask, so I'll just get rid of that change.

@mhvk
mhvk force-pushed the ma-getitem-nomask-correction branch from 6bd731b to c4c2eee Compare June 12, 2015 19:01
@mhvk

mhvk commented Jun 12, 2015

Copy link
Copy Markdown
Contributor Author

@ahaldane - thanks for checking! The extraneous change is now removed.

@ahaldane

Copy link
Copy Markdown
Member

I'm going to have to pass on the maintainership :)

The PR looks good now.

@mhvk
mhvk force-pushed the ma-getitem-nomask-correction branch from c4c2eee to 84fa8d9 Compare June 14, 2015 00:46
@mhvk

mhvk commented Jun 14, 2015

Copy link
Copy Markdown
Contributor Author

@ahaldane - it turns out the fix I had was not enough: at least in astropy there are tests that rely on the previous buggy behaviour where the array held in the masked object array was returned as a MaskedArray that, e.g., had zero length (i.e., tests were done like len(mx[0]) == 0). I don't think this corner case is important enough to break backwards compatibility that much, so I now made the test specifically for object arrays, returning a fully masked array for this case (as before, but not doing casting to type(self) or doing update_from(self), which is silly if one gets a single element).

At least all the tests in astropy now pass that previously failed because of my PR (but it seems some recent change in recarray has broken some of our io.fits tests... yikes).

@mhvk
mhvk force-pushed the ma-getitem-nomask-correction branch 2 times, most recently from c1cfd7e to 6049392 Compare June 14, 2015 01:24
@ahaldane

Copy link
Copy Markdown
Member

That's worrying.. which tests? I just tried building+testing astropy with this PR, and I don't see anything (8753 passed, 199 skipped, 43 xfailed, 2 xpassed )

@mhvk

mhvk commented Jun 17, 2015

Copy link
Copy Markdown
Contributor Author

@ahaldane - there definitely failures in astropy.io.fits (which I hope will be resolved by #5943). In addition, the removal of NotImplemented in np.ufunc (#5964, #5864) brought forth a mistake in Quantity which causes failures in astropy.units (see astropy/astropy#3860).

None of these errors are related to the ones solved by this PR, though.

EDIT: sadly, #5943 does not resolve the astropy.io.fits problems.

@charris

charris commented Jun 17, 2015

Copy link
Copy Markdown
Member

@mhvk Fixing the astropy.io.fits problem looks like a 1.10 blocker. Could you spend some time on that?

@ahaldane

Copy link
Copy Markdown
Member

@mhvk I'm happy to help debug this, if you know which tests fail.

astropy.io.fits passed all tests in python2 on my (linux) system with numpy master. It failed a bunch in python3, but it fails even if I use a numpy revision before any of my recent recarray commits.

@mhvk

mhvk commented Jun 17, 2015

Copy link
Copy Markdown
Contributor Author

hmm, so a python3 issue for io.fits.. Odd. I'll try to look later. In the meantime, CC @embray.

@mhvk
mhvk force-pushed the ma-getitem-nomask-correction branch from 6049392 to 0db6200 Compare June 18, 2015 00:18
@mhvk

mhvk commented Jun 18, 2015

Copy link
Copy Markdown
Contributor Author

@charris - still investigating the io.fits issue (now clearly related to python3). Hopefully solved soon. But as for importance: this present PR is actually more important, as it prevents the bug I exposed in #4586 from breaking many of our tests.

@charris

charris commented Jun 18, 2015

Copy link
Copy Markdown
Member

@mhvk I agree that this is a bug fix len(mx[0]) == 0 is just weird for a not empty object. Even so, it should probably be mentioned in the release notes. I assume mx2 = MaskedArray_array([1., 2.]) should be mx2 = MaskedArray(array([1., 2.])) in the example.

For a masked array holding objects that themselves are arrays, when selecting a
single item, it is treated as if it were a slice of the array and an attempt is
made to set its mask.  This was always a bug, but it become visible with a
recent change to `MaskedArray.__getitem__` (numpygh-4586) where it is attempted to
change the shape of the mask.  With this PR, this case gets special  treatment
in that the object is made into a Masked Array with a full set mask.
(A previous attempt to do the perhaps more logical think and just return
`masked` caused quite a few errors in astropy.io.votable; it seemed it was
not worth breaking backwards compatibility that much).

Test case that now works but used to fail:
```
mx1 = MaskedArray([1.], mask=[True])
mx2 = MaskedArray([1., 2.])
mx = MaskedArray([mx1, mx2], mask=[False, True])
mx[0]
```
@mhvk
mhvk force-pushed the ma-getitem-nomask-correction branch from 0db6200 to 1a4d943 Compare June 18, 2015 02:17
@mhvk

mhvk commented Jun 18, 2015

Copy link
Copy Markdown
Contributor Author

OK, I added a brief item to the release notes, and corrected my commit message. Let me know if this makes sense.

charris added a commit that referenced this pull request Jun 18, 2015
BUG Ensure masked object arrays can always return single items.
@charris
charris merged commit 2c29b13 into numpy:master Jun 18, 2015
@charris

charris commented Jun 18, 2015

Copy link
Copy Markdown
Member

Thanks @mhvk.

@eric-wieser

Copy link
Copy Markdown
Member

This PR introduced a different bug - #8906. Do we need to keep this behaviour of not just returning np.ma.maskedin this case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants