8000 BUG: view with fieldless dtype should raise if itemsize != 0 by ahaldane · Pull Request #14393 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

BUG: view with fieldless dtype should raise if itemsize != 0 #14393

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

Merged
merged 4 commits into from
Sep 8, 2019

Conversation

ahaldane
Copy link
Member

Fixes #14344

Minor bugfix caused by treating the "dtype([])" structured type as if it was the "V0" flexible type.

@charris
Copy link
Member
charris commented Aug 28, 2019

Does this need a backport?

@ahaldane
Copy link
Member Author

This bug is so niche that a backport doesn't really seem worth the effort to me, but it would also be harmless to backport.

@ahaldane ahaldane force-pushed the fix_fieldless_view_itemsize branch from d4ddfaa to 847aefc Compare August 28, 2019 17:54
@eric-wieser
Copy link
Member
eric-wieser commented Aug 29, 2019

I think this now warrants a few more tests, since this fixed a lot of bugs.
Here's another that I think is fixed

>>> np.dtype((np.dtype([]), 10))
dtype({'names':[], 'formats':[], 'offsets':[], 'itemsize':10})  # before
dtype(([], (10,)))  # after

And another

>>> np.fromiter((() for i in range(10)), [])
ValueError: Must specify length when using variable-size data-type.  # before
array(...)  # after

@eric-wieser
Copy link
Member

Probably worth a ..versionchanged in doc/source/reference/c-api/array.rst too, where this macro is documented.

@@ -1200,7 +1200,8 @@ _void_compare(PyArrayObject *self, PyArrayObject *other, int cmp_op)
}
}
if (res == NULL && !PyErr_Occurred()) {
PyErr_SetString(PyExc_ValueError, "No fields found.");
/* these dtypes had no fields */
return cmp_op == Py_EQ ? Py_True : Py_False;
Copy link
Member

Choose a reason for hiding this comment

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

This change isn't correct - it doesn't produce a correctly broadcast array. Let's leave this to a future PR - the rest looks great.

Copy link
Member Author
@ahaldane ahaldane Aug 31, 2019

Choose a reason for hiding this comment

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

Fixed by falling through to the string compare case which does the right thing here.

Edit: Oh wait, I forgot about itemsize differences.. Never mind, it does work because V0 and V8 empty strings are equal.

@ahaldane
Copy link
Member Author

Thanks for great reviews, as usual.

I updated PyDataType_ISUNSIZED, and went through all the places it was used to check if this introduced any bugs. It did, which I fixed, and I added appropriate tests.

I have some hesitation on doing it this way, so consider this a WIP. First, in some of the places calling ISUNSIZED the code really did want to check just elsize == 0, fields or no fields. Also, with the same logic it seems like PyDataType_ISFLEXIBLE should also be False for structured 0-size types. However, when I make that change I get a bunch of segfaults, especially in the pickling code. .

* compare as a string. Assumes self and
* other have same descr->type
* compare as a string. Assumes self and other have same descr->type.
* Note that fieldless structured datatypes (itemsize 0) fall through
Copy link
Member

Choose a reason for hiding this comment

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

What about fieldless types with padding?

@ahaldane ahaldane force-pushed the fix_fieldless_view_itemsize branch 2 times, most recently from c1d3f73 to c2b2c00 Compare August 31, 2019 20:09
@ahaldane ahaldane force-pushed the fix_fieldless_view_itemsize branch from c2b2c00 to 7c3adfb Compare August 31, 2019 21:17
@@ -1200,15 +1200,18 @@ _void_compare(PyArrayObject *self, PyArrayObject *other, int cmp_op)
}
}
if (res == NULL && !PyErr_Occurred()) {
PyErr_SetString(PyExc_ValueError, "No fields found.");
/* these dtypes had no fields */
res = PyArray_NewLikeArray(self, NPY_ANYORDER,
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't broadcast with other, unless the broadcasting has already happened here

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, yeah. I think I've got it finally by using a multiiter.

@@ -1200,15 +1200,28 @@ _void_compare(PyArrayObject *self, PyArrayObject *other, int cmp_op)
}
}
if (res == NULL && !PyErr_Occurred()) {
PyErr_SetString(PyExc_ValueError, "No fields found.");
Copy link
Member

Choose a reason for hiding this comment

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

Fixes gh-13438, I think

@@ -1861,7 +1861,7 @@ array_reduce_ex(PyArrayObject *self, PyObject *args)
PyDataType_FLAGCHK(descr, NPY_ITEM_HASOBJECT) ||
(PyType_IsSubtype(((PyObject*)self)->ob_type, &PyArray_Type) &&
((PyObject*)self)->ob_type != &PyArray_Type) ||
PyDataType_ISUNSIZED(descr)) {
descr->elsize == 0) {
Copy link
Member

Choose a reason for hiding this comment

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

It's not clear to me why this condition is needed at all, although it admittedly looks harmless.

Copy link
Member Author

Choose a reason for hiding this comment

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

not clear to me either. These lines previously discussed here: https://github.com/numpy/numpy/pull/12748/files#r249258808 and introduced in #12011, but not discussed there.

Copy link
Member
@eric-wieser eric-wieser left a comment

Choose a reason for hiding this comment

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

Looks pretty good - one unimportant question, and a doc typo. Getting the comparison fix in here should have enabled me to push some of my remaining fixes, which were untestable without it - thanks!

@eric-wieser
Copy link
Member

I think an upcoming_changes/14393.c_api.rst note might be warranted about the macro behavior

@charris
Copy link
Member
charris commented Sep 5, 2019

@ahaldane Ping.

@ahaldane
Copy link
Member Author
ahaldane commented Sep 5, 2019

About to push as you wrote that!

@ahaldane ahaldane force-pushed the fix_fieldless_view_itemsize branch from d33c5d2 to 5e7bca5 Compare September 5, 2019 20:57
@ahaldane ahaldane force-pushed the fix_fieldless_view_itemsize branch from 5e7bca5 to d6f7524 Compare September 5, 2019 22:07
@mattip mattip merged commit f786041 into numpy:master Sep 8, 2019
@mattip
Copy link
Member
mattip commented Sep 8, 2019

Thanks @ahaldane and reviewers

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.

viewing an array with a fieldless structured dtype does not update the dtype:
4 participants
0