@@ -312,7 +312,7 @@ typedef struct {
312
312
NpyAuxData * wrappeddata , * todata , * fromdata ;
313
313
npy_intp src_itemsize , dst_itemsize ;
314
314
char * bufferin , * bufferout ;
315
- npy_bool init_dest ;
315
+ npy_bool init_dest , out_needs_api ;
316
316
} _align_wrap_data ;
317
317
318
318
/* transfer data free function */
@@ -374,6 +374,7 @@ static NpyAuxData *_align_wrap_data_clone(NpyAuxData *data)
374
374
}
375
375
376
376
newdata -> init_dest = d -> init_dest ;
377
+ newdata -> out_needs_api = d -> out_needs_api ;
377
378
378
379
return (NpyAuxData * )newdata ;
379
380
}
@@ -394,7 +395,7 @@ _strided_to_strided_contig_align_wrap(char *dst, npy_intp dst_stride,
394
395
* todata = d -> todata ,
395
396
* fromdata = d -> fromdata ;
396
397
char * bufferin = d -> bufferin , * bufferout = d -> bufferout ;
397
- npy_bool init_dest = d -> init_dest ;
398
+ npy_bool init_dest = d -> init_dest , out_needs_api = d -> out_needs_api ;
398
399
399
400
for (;;) {
400
401
if (N > NPY_LOWLEVEL_BUFFER_BLOCKSIZE ) {
@@ -414,6 +415,9 @@ _strided_to_strided_contig_align_wrap(char *dst, npy_intp dst_stride,
414
415
N -= NPY_LOWLEVEL_BUFFER_BLOCKSIZE ;
415
416
src += NPY_LOWLEVEL_BUFFER_BLOCKSIZE * src_stride ;
416
417
dst += NPY_LOWLEVEL_BUFFER_BLOCKSIZE * dst_stride ;
418
+ if (out_needs_api && PyErr_Occurred ()) {
419
+ return ;
420
+ }
417
421
}
418
422
else {
419
423
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,
442
446
* wrapped - contig to contig transfer function being wrapped
443
447
* wrappeddata - data for wrapped
444
448
* init_dest - 1 means to memset the dest buffer to 0 before calling wrapped.
449
+ * out_needs_api - if NPY_TRUE, check for (and break on) Python API errors.
445
450
*
446
451
* Returns NPY_SUCCEED or NPY_FAIL.
447
452
*/
@@ -452,6 +457,7 @@ wrap_aligned_contig_transfer_function(
452
457
PyArray_StridedUnaryOp * frombuffer , NpyAuxData * fromdata ,
453
458
PyArray_StridedUnaryOp * wrapped , NpyAuxData * wrappeddata ,
454
459
int init_dest ,
460
+ int out_needs_api ,
455
461
PyArray_StridedUnaryOp * * out_stransfer ,
456
462
NpyAuxData * * out_transferdata )
457
463
{
@@ -485,6 +491,7 @@ wrap_aligned_contig_transfer_function(
485
491
data -> bufferout = data -> bufferin +
486
492
NPY_LOWLEVEL_BUFFER_BLOCKSIZE * src_itemsize ;
487
493
data -> init_dest = (npy_bool ) init_dest ;
494
+ data -> out_needs_api = (npy_bool ) out_needs_api ;
488
495
489
496
/* Set the function and data */
490
497
* out_stransfer = & _strided_to_strided_contig_align_wrap ;
@@ -1132,6 +1139,7 @@ get_datetime_to_unicode_transfer_function(int aligned,
1132
1139
frombuffer , fromdata ,
1133
1140
caststransfer , castdata ,
1134
1141
PyDataType_FLAGCHK (str_dtype , NPY_NEEDS_INIT ),
1142
+ * out_needs_api ,
1135
1143
out_stransfer , out_transferdata ) != NPY_SUCCEED ) {
1136
1144
NPY_AUXDATA_FREE (castdata );
1137
1145
NPY_AUXDATA_FREE (todata );
@@ -1254,6 +1262,7 @@ get_unicode_to_datetime_transfer_function(int aligned,
1254
1262
frombuffer , fromdata ,
1255
1263
caststransfer , castdata ,
1256
1264
PyDataType_FLAGCHK (dst_dtype , NPY_NEEDS_INIT ),
1265
+ * out_needs_api ,
1257
1266
out_stransfer , out_transferdata ) != NPY_SUCCEED ) {
1258
1267
Py_DECREF (str_dtype );
1259
1268
NPY_AUXDATA_FREE (castdata );
@@ -1574,6 +1583,7 @@ get_cast_transfer_function(int aligned,
1574
1583
frombuffer , fromdata ,
1575
1584
caststransfer , castdata ,
1576
1585
PyDataType_FLAGCHK (dst_dtype , NPY_NEEDS_INIT ),
1586
+ * out_needs_api ,
1577
1587
out_stransfer , out_transferdata ) != NPY_SUCCEED ) {
1578
1588
NPY_AUXDATA_FREE (castdata );
1579
1589
NPY_AUXDATA_FREE (todata );
0 commit comments