-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
WIP: MAINT: Add deprecation warning to views of multi-field indexes #6054
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Did you run the test on a clean session? Otherwise they are probably suppressed. If you are running them on a clean session, there is a The thing to remember with testing warnings is that all warnings must be created with EDIT: To be more clear, there may be some other test, which gives the warning, but does not notice there is an extra warning being given. And since the warning is not set to By the way, would it be possible to wrap the whole test suit in an |
Added a PR that might make that problem go away to some degree. (but you always need to use a warning clean session when testing, and that is difficult to provide! E.g. we had it that running numpy tests a second time would give errors because of this kind of issue) |
All right, part of the problem was that the test was being skipped in python2, so it was normal not to see the warning. If I set raise_warnings in python3, that test does indeed raise, but for a different deprecation that happens before mine. If I run the test manually (by importing it and running it) it correctly shows all the deprecations. In order to be able to see all the deprecation warnings (and not just the first one in a test) I found I need to also comment out this line, and then run I added a test and moved unrelated changes to another PR. |
I just got a bit worried about multifield subscription/getitem. You know the wonky "buffer" logic in setitem (and we can fix that), but in general I am a bit worried about losing the non-indexed information, i.e. silently overwriting the garbage part of the VOID dtype. |
Just to be clear, this PR should only be merged if we decide to go ahead with multi-field indices returning views (#6053). So really I need to finish that, and we need to decide what the plan is in #6053 before deciding what to do here. As for avoiding writing garbage to unviewed fields, #6053 is already safe with respect to this. The solution was to prevent use of the 'buffer' logic in |
9b6f753
to
ff79228
Compare
@@ -601,6 +601,22 @@ PyArray_View(PyArrayObject *self, PyArray_Descr *type, PyTypeObject *pytype) | |||
subtype = Py_TYPE(self); | |||
} | |||
|
|||
if (type != NULL && (PyArray_FLAGS(self) & NPY_ARRAY_WARN_ON_WRITE)) { | |||
const char *msg = | |||
"Numpy has detected that you (may be) taking a view of an array " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some line breaks would be good.
@seberg Will your recent work on warnings help make the tests work consistently? |
Yes, rebase on master, and you can be sure to find all affected tests (unless they already explicitly filter the future warnings or so). That was the point of it mostly. |
I tried rebasing on master, seems somewhere in a calling function an error check is missing or something, got segfaults when running the test suits (I expected tests failing, but not segfaulting) |
Cool ,the warning improvements sound promising! I'll fix this up tonight and look into the segfault. |
@ahaldane What is the status of this? |
4f8e70e
to
b1cf258
Compare
Sorry, I had an unexpected turn of events last week. Updated now. The segfault is fixed. It was due to a missing check that I added extra wrappers to all the tests the deprecation will affect. The new warning improvements make it very easy to see what tests need to change! Very nice. Also, originally I thought we would be making both |
Looks like some more tests need ah fixin'. |
528dca7
to
2d62047
Compare
@charris : Not sure how my PR will address this failure. My patch is addressing the DEBUG=1 machine. |
@charris : Hmmm...I guess along the trend of unusual build errors I guess that could be relevant. |
Oki, seems like you figured out the "ignore" thing. Could also use the new |
I think I got the last error: I was ignoring a warning when I should have been recording it. (certain config flags make the numpy warning suite complain about ignored warnings). |
assert_(np.can_cast(a.dtype, b.dtype, casting='equiv')) | ||
c = a.astype(b.dtype, casting='equiv') | ||
with warnings.catch_warnings(record=True) as log: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to show it off (I really don't care about it), this could be an alternative:
with suppress_warnings() as sup:
sup.filter(FutureWarning)
without checking that there are only FutureWarnings there, or if you want to make sure there is one future warning:
with suppress_warnings() as sup:
l = sup.record(FutureWarning)
...
assert_(len(l) > 0)
also works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, maybe assert_warns even was a context manager by now, I somewhat think it was....
updated to use |
5eec07a
to
d8b846f
Compare
Ready to squash yet? |
6b87001
to
37dd276
Compare
Behavior of multi-field indexes will change in 1.13: Multi-field indexes will return a view (not a copy) and assignment between structures with non-identical fieldnames occurs "by position" (not "by fieldname"): >>> a = zeros(10, dtype=[('x', 'i8'), ('y', 'i8'), ('z', 'i8')]) >>> a[['x', 'z']].view('i4') # Deprecation warning for multifield view >>> b = ones(10, dtype=[('y', 'i4'), ('x', 'f4')]) >>> a[:] = b # Deprecation warning for multifield assignment
Squashed. |
Also, tweaked the warning to remove the recommended workaround, to replace The actual workaround is to define something like def pack_fields(arr):
dt = arr.dtype
packed_dtype = np.dtype(zip((n,dt.fields[n][0]) for n in dt.names))
return array(arr, dtype=packed_dtype, copy=True) then do |
Hmm, that is a pretty complicated workaround. Maybe we need a |
Let's see what complaints we can gin up. Thanks Allan. |
Thanks for the reviews, Chuck and Sebastian! |
As discussed in #6053, in preparation for making multi-field indices return a view instead of a copy, this adds a deprecation warning when attempting to view the result of a multi-field index, as in:
Such code will break any time we convert copies to views, because the byte arrangement of copies and views is necessarily different. I'd like to get it in for 1.10, so we can more easily make the copy->view change in 1.11.
My computer access is limited right now so this PR might be a bit rough, I'll tidy it later. Just posting for feedback now.
One thing I haven't figured out is how to make the unit tests show the deprecation warning: There are unit tests which I know show the warning (
test_field_names
) but the warnings don't show up when I runnp.test('full')
or evennp.test('full', raise_warnings=[FutureWarning])
. I'd like to use this to catch all the numpy code that will break when convertingmulti-field copies to view. Any ideas?