diff options
author | Brandt Bucher <brandtbucher@gmail.com> | 2020-03-23 17:20:44 -0700 |
---|---|---|
committer | Brandt Bucher <brandtbucher@gmail.com> | 2020-03-23 17:24:31 -0700 |
commit | 7ceb5428ad6d97f71295815c2d3d1d785affa3dd (patch) | |
tree | 05e932d0fe02ce884196cd44bf64ed8a6a4a3d69 | |
parent | 367c5a2138d4bfdeb41c0de9ac8db8b974656f2e (diff) | |
download | numpy-7ceb5428ad6d97f71295815c2d3d1d785affa3dd.tar.gz |
BUG: Break on errors when performing strided casts.
Closed gh-15790.
-rw-r--r-- | numpy/core/src/multiarray/dtype_transfer.c | 14 |
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); |