summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandt Bucher <brandtbucher@gmail.com>2020-03-23 17:20:44 -0700
committerBrandt Bucher <brandtbucher@gmail.com>2020-03-23 17:24:31 -0700
commit7ceb5428ad6d97f71295815c2d3d1d785affa3dd (patch)
tree05e932d0fe02ce884196cd44bf64ed8a6a4a3d69
parent367c5a2138d4bfdeb41c0de9ac8db8b974656f2e (diff)
downloadnumpy-7ceb5428ad6d97f71295815c2d3d1d785affa3dd.tar.gz
BUG: Break on errors when performing strided casts.
Closed gh-15790.
-rw-r--r--numpy/core/src/multiarray/dtype_transfer.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/numpy/core/src/multiarray/dtype_transfer.c b/numpy/core/src/multiarray/dtype_transfer.c
index 6c5fe2aed..5a7bce5ff 100644
--- a/numpy/core/src/multiarray/dtype_transfer.c
+++ b/numpy/core/src/multiarray/dtype_transfer.c
@@ -312,7 +312,7 @@ typedef struct {
NpyAuxData *wrappeddata, *todata, *fromdata;
npy_intp src_itemsize, dst_itemsize;
char *bufferin, *bufferout;
- npy_bool init_dest;
+ npy_bool init_dest, out_needs_api;
} _align_wrap_data;
/* transfer data free function */
@@ -374,6 +374,7 @@ static NpyAuxData *_align_wrap_data_clone(NpyAuxData *data)
}
newdata->init_dest = d->init_dest;
+ newdata->out_needs_api = d->out_needs_api;
return (NpyAuxData *)newdata;
}
@@ -394,7 +395,7 @@ _strided_to_strided_contig_align_wrap(char *dst, npy_intp dst_stride,
*todata = d->todata,
*fromdata = d->fromdata;
char *bufferin = d->bufferin, *bufferout = d->bufferout;
- npy_bool init_dest = d->init_dest;
+ npy_bool init_dest = d->init_dest, out_needs_api = d->out_needs_api;
for(;;) {
if (N > NPY_LOWLEVEL_BUFFER_BLOCKSIZE) {
@@ -414,6 +415,9 @@ _strided_to_strided_contig_align_wrap(char *dst, npy_intp dst_stride,
N -= NPY_LOWLEVEL_BUFFER_BLOCKSIZE;
src += NPY_LOWLEVEL_BUFFER_BLOCKSIZE*src_stride;
dst += NPY_LOWLEVEL_BUFFER_BLOCKSIZE*dst_stride;
+ if (out_needs_api && PyErr_Occurred()) {
+ return;
+ }
}
else {
tobuffer(bufferin, inner_src_itemsize, src, src_stride, N,
@@ -442,6 +446,7 @@ _strided_to_strided_contig_align_wrap(char *dst, npy_intp dst_stride,
* wrapped - contig to contig transfer function being wrapped
* wrappeddata - data for wrapped
* init_dest - 1 means to memset the dest buffer to 0 before calling wrapped.
+ * out_needs_api - if NPY_TRUE, check for (and break on) Python API errors.
*
* Returns NPY_SUCCEED or NPY_FAIL.
*/
@@ -452,6 +457,7 @@ wrap_aligned_contig_transfer_function(
PyArray_StridedUnaryOp *frombuffer, NpyAuxData *fromdata,
PyArray_StridedUnaryOp *wrapped, NpyAuxData *wrappeddata,
int init_dest,
+ int out_needs_api,
PyArray_StridedUnaryOp **out_stransfer,
NpyAuxData **out_transferdata)
{
@@ -485,6 +491,7 @@ wrap_aligned_contig_transfer_function(
data->bufferout = data->bufferin +
NPY_LOWLEVEL_BUFFER_BLOCKSIZE*src_itemsize;
data->init_dest = (npy_bool) init_dest;
+ data->out_needs_api = (npy_bool) out_needs_api;
/* Set the function and data */
*out_stransfer = &_strided_to_strided_contig_align_wrap;
@@ -1132,6 +1139,7 @@ get_datetime_to_unicode_transfer_function(int aligned,
frombuffer, fromdata,
caststransfer, castdata,
PyDataType_FLAGCHK(str_dtype, NPY_NEEDS_INIT),
+ *out_needs_api,
out_stransfer, out_transferdata) != NPY_SUCCEED) {
NPY_AUXDATA_FREE(castdata);
NPY_AUXDATA_FREE(todata);
@@ -1254,6 +1262,7 @@ get_unicode_to_datetime_transfer_function(int aligned,
frombuffer, fromdata,
caststransfer, castdata,
PyDataType_FLAGCHK(dst_dtype, NPY_NEEDS_INIT),
+ *out_needs_api,
out_stransfer, out_transferdata) != NPY_SUCCEED) {
Py_DECREF(str_dtype);
NPY_AUXDATA_FREE(castdata);
@@ -1574,6 +1583,7 @@ get_cast_transfer_function(int aligned,
frombuffer, fromdata,
caststransfer, castdata,
PyDataType_FLAGCHK(dst_dtype, NPY_NEEDS_INIT),
+ *out_needs_api,
out_stransfer, out_transferdata) != NPY_SUCCEED) {
NPY_AUXDATA_FREE(castdata);
NPY_AUXDATA_FREE(todata);