@@ -72,13 +72,12 @@ string_to_string(PyArrayMethod_Context *context, char *const data[],
72
72
npy_intp const dimensions [], npy_intp const strides [],
73
73
NpyAuxData * NPY_UNUSED (auxdata ))
74
74
{
75
- StringDTypeObject * in_descr =
76
- ((StringDTypeObject * )context -> descriptors [0 ]);
77
- StringDTypeObject * out_descr =
78
- ((StringDTypeObject * )context -> descriptors [1 ]);
79
- int in_hasnull = in_descr -> na_object != NULL ;
80
- int out_hasnull = out_descr -> na_object != NULL ;
81
- const npy_static_string * in_na_name = & in_descr -> na_name ;
75
+ StringDTypeObject * idescr = (StringDTypeObject * )context -> descriptors [0 ];
76
+ StringDTypeObject * odescr = (StringDTypeObject * )context -> descriptors [1 ];
77
+ npy_string_allocator * allocator = odescr -> allocator ;
78
+ int in_hasnull = idescr -> na_object != NULL ;
79
+ int out_hasnull = odescr -> na_object != NULL ;
80
+ const npy_static_string * in_na_name = & idescr -> na_name ;
82
81
npy_intp N = dimensions [0 ];
83
82
char * in = data [0 ];
84
83
char * out = data [1 ];
@@ -89,17 +88,17 @@ string_to_string(PyArrayMethod_Context *context, char *const data[],
89
88
const npy_packed_static_string * s = (npy_packed_static_string * )in ;
90
89
npy_packed_static_string * os = (npy_packed_static_string * )out ;
91
90
if (in != out ) {
92
- npy_string_free (os );
91
+ npy_string_free (os , allocator );
93
92
if (in_hasnull && !out_hasnull && npy_string_isnull (s )) {
94
93
// lossy but this is an unsafe cast so this is OK
95
- if (npy_string_newsize (in_na_name -> buf , in_na_name -> size , os ) <
96
- 0 ) {
94
+ if (npy_string_newsize (
95
+ in_na_name -> buf , in_na_name -> size , os , allocator ) < 0 ) {
97
96
gil_error (PyExc_MemoryError ,
98
97
"Failed to allocate string in string to string "
99
98
"cast." );
100
99
}
101
100
}
102
- else if (npy_string_dup (s , os ) < 0 ) {
101
+ else if (npy_string_dup (s , os , allocator ) < 0 ) {
103
102
gil_error (PyExc_MemoryError , "npy_string_dup failed" );
104
103
return -1 ;
105
104
}
@@ -211,6 +210,8 @@ unicode_to_string(PyArrayMethod_Context *context, char *const data[],
211
210
NpyAuxData * NPY_UNUSED (auxdata ))
212
211
{
213
212
PyArray_Descr * * descrs = context -> descriptors ;
213
+ npy_string_allocator * allocator =
214
+ ((StringDTypeObject * )descrs [1 ])-> allocator ;
214
215
long max_in_size = (descrs [0 ]-> elsize ) / 4 ;
215
216
216
217
npy_intp N = dimensions [0 ];
@@ -230,8 +231,8 @@ unicode_to_string(PyArrayMethod_Context *context, char *const data[],
230
231
return -1 ;
231
232
}
232
233
npy_packed_static_string * out_pss = (npy_packed_static_string * )out ;
233
- npy_string_free (out_pss );
234
- if (npy_string_newemptysize (out_num_bytes , out_pss ) < 0 ) {
234
+ npy_string_free (out_pss , allocator );
235
+ if (npy_string_newemptysize (out_num_bytes , out_pss , allocator ) < 0 ) {
235
236
gil_error (PyExc_MemoryError ,
236
237
"Failed to allocate string in unicode to string cast" );
237
238
return -1 ;
@@ -493,7 +494,7 @@ static char *s2b_name = "cast_StringDType_to_Bool";
493
494
// bool to string
494
495
495
496
static int
496
- bool_to_string (PyArrayMethod_Context * NPY_UNUSED ( context ) , char * const data [],
497
+ bool_to_string (PyArrayMethod_Context * context , char * const data [],
497
498
npy_intp const dimensions [], npy_intp const strides [],
498
499
NpyAuxData * NPY_UNUSED (auxdata ))
499
500
{
@@ -504,9 +505,12 @@ bool_to_string(PyArrayMethod_Context *NPY_UNUSED(context), char *const data[],
504
505
npy_intp in_stride = strides [0 ];
505
506
npy_intp out_stride = strides [1 ];
506
507
508
+ StringDTypeObject * descr = (StringDTypeObject * )context -> descriptors [1 ];
509
+ npy_string_allocator * allocator = descr -> allocator ;
510
+
507
511
while (N -- ) {
508
512
npy_packed_static_string * out_pss = (npy_packed_static_string * )out ;
509
- npy_string_free (out_pss );
513
+ npy_string_free (out_pss , allocator );
510
514
char * ret_val = NULL ;
511
515
size_t size = 0 ;
512
516
if ((npy_bool )(* in ) == 1 ) {
@@ -522,7 +526,7 @@ bool_to_string(PyArrayMethod_Context *NPY_UNUSED(context), char *const data[],
522
526
"invalid value encountered in bool to string cast" );
523
527
return -1 ;
524
528
}
525
- if (npy_string_newsize (ret_val , size , out_pss ) < 0 ) {
529
+ if (npy_string_newsize (ret_val , size , out_pss , allocator ) < 0 ) {
526
530
// execution should never get here because this will be a small
527
531
// string on all platforms
528
532
gil_error (PyExc_MemoryError ,
@@ -605,7 +609,7 @@ string_to_int(char *in, npy_longlong *value, int hasnull,
605
609
}
606
610
607
611
static int
608
- pyobj_to_string (PyObject * obj , char * out )
612
+ pyobj_to_string (PyObject * obj , char * out , npy_string_allocator * allocator )
609
613
{
610
614
if (obj == NULL ) {
611
615
return -1 ;
@@ -622,8 +626,8 @@ pyobj_to_string(PyObject *obj, char *out)
622
626
return -1 ;
623
627
}
624
628
npy_packed_static_string * out_ss = (npy_packed_static_string * )out ;
625
- npy_string_free (out_ss );
626
- if (npy_string_newsize (cstr_val , length , out_ss ) < 0 ) {
629
+ npy_string_free (out_ss , allocator );
630
+ if (npy_string_newsize (cstr_val , length , out_ss , allocator ) < 0 ) {
627
631
PyErr_SetString (PyExc_MemoryError ,
628
632
"Failed to allocate numpy string when converting from "
629
633
"python string." );
@@ -636,17 +640,18 @@ pyobj_to_string(PyObject *obj, char *out)
636
640
}
637
641
638
642
static int
639
- int_to_string (long long in , char * out )
643
+ int_to_string (long long in , char * out , npy_string_allocator * allocator )
640
644
{
641
645
PyObject * pylong_val = PyLong_FromLongLong (in );
642
- return pyobj_to_string (pylong_val , out );
646
+ return pyobj_to_string (pylong_val , out , allocator );
643
647
}
644
648
645
649
static int
646
- uint_to_string (unsigned long long in , char * out )
650
+ uint_to_string (unsigned long long in , char * out ,
651
+ npy_string_allocator * allocator )
647
652
{
648
653
PyObject * pylong_val = PyLong_FromUnsignedLongLong (in );
649
- return pyobj_to_string (pylong_val , out );
654
+ return pyobj_to_string (pylong_val , out , allocator );
650
655
}
651
656
652
657
#define STRING_INT_CASTS (typename , typekind , shortname , numpy_tag , \
@@ -720,7 +725,7 @@ uint_to_string(unsigned long long in, char *out)
720
725
static char *s2##shortname##_name = "cast_StringDType_to_" #typename; \
721
726
\
722
727
static int typename##_to_string( \
723
- PyArrayMethod_Context *NPY_UNUSED( context) , char *const data[], \
728
+ PyArrayMethod_Context *context, char *const data[], \
724
729
npy_intp const dimensions[], npy_intp const strides[], \
725
730
NpyAuxData *NPY_UNUSED(auxdata)) \
726
731
{ \
@@ -731,8 +736,12 @@ uint_to_string(unsigned long long in, char *out)
731
736
npy_intp in_stride = strides[0] / sizeof(npy_##typename); \
732
737
npy_intp out_stride = strides[1]; \
733
738
\
739
+ StringDTypeObject *descr = \
740
+ (StringDTypeObject *)context->descriptors[1]; \
741
+ npy_string_allocator *allocator = descr->allocator; \
742
+ \
734
743
while (N--) { \
735
- if (typekind##_to_string((longtype)*in, out) != 0) { \
744
+ if (typekind##_to_string((longtype)*in, out, allocator ) != 0) { \
736
745
return -1; \
737
746
} \
738
747
\
@@ -917,9 +926,13 @@ string_to_pyfloat(char *in, int hasnull,
917
926
npy_intp in_stride = strides[0] / sizeof(npy_##typename); \
918
927
npy_intp out_stride = strides[1]; \
919
928
\
929
+ StringDTypeObject *descr = \
930
+ (StringDTypeObject *)context->descriptors[1]; \
931
+ npy_string_allocator *allocator = descr->allocator; \
932
+ \
920
933
while (N--) { \
921
934
PyObject *scalar_val = PyArray_Scalar(in, float_descr, NULL); \
922
- if (pyobj_to_string(scalar_val, out) == -1) { \
935
+ if (pyobj_to_string(scalar_val, out, allocator ) == -1) { \
923
936
return -1; \
924
937
} \
925
938
\
@@ -1096,9 +1109,12 @@ datetime_to_string(PyArrayMethod_Context *context, char *const data[],
1096
1109
// buffer passed to numpy to build datetime string
1097
1110
char datetime_buf [NPY_DATETIME_MAX_ISO8601_STRLEN ];
1098
1111
1112
+ StringDTypeObject * sdescr = (StringDTypeObject * )context -> descriptors [1 ];
1113
+ npy_string_allocator * allocator = sdescr -> allocator ;
1114
+
1099
1115
while (N -- ) {
1100
1116
npy_packed_static_string * out_pss = (npy_packed_static_string * )out ;
1101
- npy_string_free (out_pss );
1117
+ npy_string_free (out_pss , allocator );
1102
1118
if (* in == NPY_DATETIME_NAT ) {
1103
1119
* out_pss = * NPY_NULL_STRING ;
1104
1120
}
@@ -1117,8 +1133,8 @@ datetime_to_string(PyArrayMethod_Context *context, char *const data[],
1117
1133
return -1 ;
1118
1134
}
1119
1135
1120
- if (npy_string_newsize (datetime_buf , strlen (datetime_buf ),
1121
- out_pss ) < 0 ) {
1136
+ if (npy_string_newsize (datetime_buf , strlen (datetime_buf ), out_pss ,
1137
+ allocator ) < 0 ) {
1122
1138
PyErr_SetString (PyExc_MemoryError ,
1123
1139
"Failed to allocate string when converting "
1124
1140
"from a datetime." );
0 commit comments