diff options
-rw-r--r-- | numpy/core/src/multiarray/dtype_transfer.c | 12 | ||||
-rw-r--r-- | numpy/core/tests/test_regression.py | 2 |
2 files changed, 11 insertions, 3 deletions
diff --git a/numpy/core/src/multiarray/dtype_transfer.c b/numpy/core/src/multiarray/dtype_transfer.c index 5a7bce5ff..ecaa680ec 100644 --- a/numpy/core/src/multiarray/dtype_transfer.c +++ b/numpy/core/src/multiarray/dtype_transfer.c @@ -398,6 +398,15 @@ _strided_to_strided_contig_align_wrap(char *dst, npy_intp dst_stride, npy_bool init_dest = d->init_dest, out_needs_api = d->out_needs_api; for(;;) { + /* + * The caller does not know if a previous call resulted in a Python + * exception. Much of the Python API is unsafe while an exception is in + * flight, so just skip all the work. Someone higher in the call stack + * will check for errors and propagate them. + */ + if (out_needs_api && PyErr_Occurred()) { + return; + } if (N > NPY_LOWLEVEL_BUFFER_BLOCKSIZE) { tobuffer(bufferin, inner_src_itemsize, src, src_stride, NPY_LOWLEVEL_BUFFER_BLOCKSIZE, @@ -415,9 +424,6 @@ _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, diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index 0cb1207d9..18d5b6032 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -1412,6 +1412,8 @@ class TestRegression: # gh-15790 a = np.array([u'\x80'] * 129, dtype='U3') assert_raises(UnicodeEncodeError, np.array, a, 'S') + b = a.reshape(3, 43)[:-1, :-1] + assert_raises(UnicodeEncodeError, np.array, b, 'S') def test_mixed_string_unicode_array_creation(self): a = np.array(['1234', u'123']) |