@@ -430,11 +430,25 @@ int uo_index=0; /* user_override index */
430
430
431
431
/* Wrappers for the default or any user-assigned PyDataMem_Handler */
432
432
433
+ int default_allocator_policy = 1 ;
434
+
435
+ static inline PyDataMem_Handler *
436
+ _PyDataMem_GetHandler_Internal (PyObject * mem_handler )
437
+ {
438
+ if (PyDataMem_DefaultHandler == mem_handler )
439
+ // fast path for default allocator
440
+ return & default_handler ;
441
+
442
+ PyDataMem_Handler * handler = (PyDataMem_Handler * )PyCapsule_GetPointer (
443
+ mem_handler , "mem_handler" );
444
+ return handler ;
445
+ }
446
+
433
447
NPY_NO_EXPORT void *
434
448
PyDataMem_UserNEW (size_t size , PyObject * mem_handler )
435
449
{
436
450
void * result ;
437
- PyDataMem_Handler * handler = ( PyDataMem_Handler * ) PyCapsule_GetPointer ( mem_handler , "mem_handler" );
451
+ PyDataMem_Handler * handler = _PyDataMem_GetHandler_Internal ( mem_handler );
438
452
if (handler == NULL ) {
439
453
return NULL ;
440
454
}
@@ -457,7 +471,7 @@ NPY_NO_EXPORT void *
457
471
PyDataMem_UserNEW_ZEROED (size_t nmemb , size_t size , PyObject * mem_handler )
458
472
{
459
473
void * result ;
460
- PyDataMem_Handler * handler = ( PyDataMem_Handler * ) PyCapsule_GetPointer ( mem_handler , "mem_handler" );
474
+ PyDataMem_Handler * handler = _PyDataMem_GetHandler_Internal ( mem_handler );
461
475
if (handler == NULL ) {
462
476
return NULL ;
463
477
}
@@ -479,7 +493,7 @@ PyDataMem_UserNEW_ZEROED(size_t nmemb, size_t size, PyObject *mem_handler)
479
493
NPY_NO_EXPORT void
480
494
PyDataMem_UserFREE (void * ptr , size_t size , PyObject * mem_handler )
481
495
{
482
- PyDataMem_Handler * handler = ( PyDataMem_Handler * ) PyCapsule_GetPointer ( mem_handler , "mem_handler" );
496
+ PyDataMem_Handler * handler = _PyDataMem_GetHandler_Internal ( mem_handler );
483
497
if (handler == NULL ) {
484
498
WARN_NO_RETURN (PyExc_RuntimeWarning ,
485
499
"Could not get pointer to 'mem_handler' from PyCapsule" );
@@ -502,7 +516,7 @@ NPY_NO_EXPORT void *
502
516
PyDataMem_UserRENEW (void * ptr , size_t size , PyObject * mem_handler )
503
517
{
504
518
void * result ;
505
- PyDataMem_Handler * handler = ( PyDataMem_Handler * ) PyCapsule_GetPointer ( mem_handler , "mem_handler" );
519
+ PyDataMem_Handler * handler = _PyDataMem_GetHandler_Internal ( mem_handler );
506
520
if (handler == NULL ) {
507
521
return NULL ;
508
522
}
@@ -535,6 +549,9 @@ PyDataMem_UserRENEW(void *ptr, size_t size, PyObject *mem_handler)
535
549
NPY_NO_EXPORT PyObject *
536
550
PyDataMem_SetHandler (PyObject * handler )
537
551
{
552
+ // once the user sets an allocation policy, we cannot guarantee the default allocator without checking the context
553
+ default_allocator_policy = 0 ;
554
+
538
555
PyObject * old_handler ;
539
556
PyObject * token ;
540
557
if (PyContextVar_Get (current_handler , NULL , & old_handler )) {
@@ -560,6 +577,11 @@ NPY_NO_EXPORT PyObject *
560
577
PyDataMem_GetHandler ()
561
578
{
562
579
PyObject * handler ;
580
+
581
+ if (default_allocator_policy ) {
582
+ Py_INCREF (PyDataMem_DefaultHandler );
583
+ return PyDataMem_DefaultHandler ;
584
+ }
563
585
if (PyContextVar_Get (current_handler , NULL , & handler )) {
564
586
return NULL ;
565
587
}
0 commit comments