Skip to content

Navigation Menu

Sign in
Appearance settings
Sign up
Appearance settings
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
BUG: np.take out dtype
Previously, an error was raised when the input and output dtypes were different during casting.
This change allows 'same-kind' casting to proceed while issuing a
DeprecationWarning for other casting types to maintain backward
compatibility while signaling future changes.

Closes #25588
  • Loading branch information
himanow authored and seberg committed Mar 24, 2026
commit 8db70a75ce0ff639e1269a32c039cde07e2817dc
23 changes: 21 additions & 2 deletions 23 numpy/_core/src/multiarray/item_selection.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ NPY_NO_EXPORT PyObject *
PyArray_TakeFrom(PyArrayObject *self0, PyObject *indices0, int axis,
PyArrayObject *out, NPY_CLIPMODE clipmode)
{
PyArray_Descr *dtype;
PyArray_Descr *dtype, *out_dtype;
PyArrayObject *obj = NULL, *self, *indices;
npy_intp nd, i, n, m, max_item, chunk, itemsize, nelem;
npy_intp shape[NPY_MAXDIMS];
Expand Down Expand Up @@ -311,7 +311,26 @@ PyArray_TakeFrom(PyArrayObject *self0, PyObject *indices0, int axis,
}
dtype = PyArray_DESCR(self);
Py_INCREF(dtype);

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 needs cleaning up, you are inserting code but that code interacts closely with this so you can't insert code between these two lines.
I.e. the dtype reference can be lost on error.

@himanow himanow Jan 17, 2026

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.

Fixed in 0029b81. Is it safe to insert code between dtype = PyArray_DESCR(self); and Py_INCREF(dtype);? Also, is the line Py_INCREF(out_dtype); unnecessary or redundant here?

obj = (PyArrayObject *)PyArray_FromArray(out, dtype, flags);
out_dtype = PyArray_DESCR(out);
if (dtype == out_dtype) {
obj = (PyArrayObject *)out;
Py_INCREF(obj);
}
else {
if (PyArray_CanCastTypeTo(dtype, out_dtype, NPY_SAME_KIND_CASTING) == 0) {

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.

Most code uses !PyArray_... for this type of pattern, so I would stick to it here too. (The < 0 is very common for errors.)

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.

Fixed in 6f40af4. I've updated this to follow the !PyArray_... pattern.

if (DEPRECATE(
"Implicit casting of output to a different kind is "
"deprecated. "
"In a future version, this will result in an error. Please "
"ensure the output has the same-kind type as the input.") <

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.

Please add the comments we usually add to say when the deprecation happened (before it) and also inside the deprecation itself, such as (deprecated NumPy 2.5).

The last sentence feels like unnecessary to me. (I should think once more if we shouldn't just use safe casting, although then one might be tempted to ask for a casting= kwarg.)

@himanow himanow Jan 17, 2026

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.

Fixed in commit 0029b81. I removed the last sentence.

0) {
goto fail;
}
}
flags |= NPY_ARRAY_FORCECAST;
obj = (PyArrayObject *)PyArray_FromArray(out, dtype, flags);

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 is the exact same code as the first branch, except for a flag that is irrelevant in the first branch.

@himanow himanow Jan 17, 2026

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.

Fixed in commit 0029b81.

Py_INCREF(obj);
}
if (obj == NULL) {
goto fail;
}
Expand Down
11 changes: 11 additions & 0 deletions 11 numpy/_core/tests/test_item_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ def test_empty_partition(self):

assert_array_equal(a, a_original)

def test_out_dtype(self):
# In reference to github issue #25588
a = np.arange(3).astype(np.int32)
indices = np.arange(2)
out = np.zeros_like(indices, dtype=np.int64)
np.take(a, indices, out=out)
assert_array_equal(a[indices], out)
Comment thread
seberg marked this conversation as resolved.
diffrent_dtype_out = np.zeros_like(indices, dtype=np.uint32)
with pytest.warns(DeprecationWarning):
np.take(a, indices, out=diffrent_dtype_out)

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.

Please move this test to test_deprecations and use the pattern used there.

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.

Fixed in commit 0029b81. Could you please check if the implementation and coding style are correct?


def test_empty_argpartition(self):
# In reference to github issue #6530
a = np.array([0, 2, 4, 6, 8, 10])
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.