@@ -246,20 +246,11 @@ binary_resolve_descriptors(struct PyArrayMethodObject_tag *NPY_UNUSED(method),
246
246
{
247
247
PyArray_StringDTypeObject *descr1 = (PyArray_StringDTypeObject *)given_descrs[0 ];
248
248
PyArray_StringDTypeObject *descr2 = (PyArray_StringDTypeObject *)given_descrs[1 ];
249
+ int out_coerce = descr1->coerce && descr1->coerce ;
250
+ PyObject *out_na_object = NULL ;
249
251
250
- // _eq_comparison has a short-circuit pointer comparison fast path,
251
- // so no need to check here
252
- int eq_res = _eq_comparison (descr1->coerce , descr2->coerce ,
253
- descr1->na_object , descr2->na_object );
254
-
255
- if (eq_res < 0 ) {
256
- return (NPY_CASTING)-1 ;
257
- }
258
-
259
- if (eq_res != 1 ) {
260
- PyErr_SetString (PyExc_TypeError,
261
- " Can only do binary operations with equal StringDType "
262
- " instances." );
252
+ if (stringdtype_compatible_na (
253
+ descr1->na_object , descr2->na_object , &out_na_object) == -1 ) {
263
254
return (NPY_CASTING)-1 ;
264
255
}
265
256
@@ -272,8 +263,7 @@ binary_resolve_descriptors(struct PyArrayMethodObject_tag *NPY_UNUSED(method),
272
263
273
264
if (given_descrs[2 ] == NULL ) {
274
265
out_descr = (PyArray_Descr *)new_stringdtype_instance (
275
- ((PyArray_StringDTypeObject *)given_descrs[1 ])->na_object ,
276
- ((PyArray_StringDTypeObject *)given_descrs[1 ])->coerce );
266
+ out_na_object, out_coerce);
277
267
278
268
if (out_descr == NULL ) {
279
269
return (NPY_CASTING)-1 ;
@@ -562,6 +552,13 @@ string_comparison_resolve_descriptors(
562
552
PyArray_Descr *const given_descrs[],
563
553
PyArray_Descr *loop_descrs[], npy_intp *NPY_UNUSED(view_offset))
564
554
{
555
+ PyArray_StringDTypeObject *descr1 = (PyArray_StringDTypeObject *)given_descrs[0 ];
556
+ PyArray_StringDTypeObject *descr2 = (PyArray_StringDTypeObject *)given_descrs[1 ];
557
+
558
+ if (stringdtype_compatible_na (descr1->na_object , descr2->na_object , NULL ) == -1 ) {
559
+ return (NPY_CASTING)-1 ;
560
+ }
561
+
565
562
Py_INCREF (given_descrs[0 ]);
566
563
loop_descrs[0 ] = given_descrs[0 ];
567
564
Py_INCREF (given_descrs[1 ]);
@@ -789,19 +786,7 @@ string_findlike_resolve_descriptors(
789
786
PyArray_StringDTypeObject *descr1 = (PyArray_StringDTypeObject *)given_descrs[0 ];
790
787
PyArray_StringDTypeObject *descr2 = (PyArray_StringDTypeObject *)given_descrs[1 ];
791
788
792
- // _eq_comparison has a short-circuit pointer comparison fast path,
793
- // so no need to check here
794
- int eq_res = _eq_comparison (descr1->coerce , descr2->coerce ,
795
- descr1->na_object , descr2->na_object );
796
-
797
- if (eq_res < 0 ) {
798
- return (NPY_CASTING)-1 ;
799
- }
800
-
801
- if (eq_res != 1 ) {
802
- PyErr_SetString (PyExc_TypeError,
803
- " Can only do binary operations with equal StringDType "
804
- " instances." );
789
+ if (stringdtype_compatible_na (descr1->na_object , descr2->na_object , NULL ) == -1 ) {
805
790
return (NPY_CASTING)-1 ;
806
791
}
807
792
@@ -850,19 +835,7 @@ string_startswith_endswith_resolve_descriptors(
850
835
PyArray_StringDTypeObject *descr1 = (PyArray_StringDTypeObject *)given_descrs[0 ];
851
836
PyArray_StringDTypeObject *descr2 = (PyArray_StringDTypeObject *)given_descrs[1 ];
852
837
853
- // _eq_comparison has a short-circuit pointer comparison fast path, so
854
- // no need to do it here
855
- int eq_res = _eq_comparison (descr1->coerce , descr2->coerce ,
856
- descr1->na_object , descr2->na_object );
857
-
858
- if (eq_res < 0 ) {
859
- return (NPY_CASTING)-1 ;
860
- }
861
-
862
- if (eq_res != 1 ) {
863
- PyErr_SetString (PyExc_TypeError,
864
- " Can only do binary operations with equal StringDType "
865
- " instances." );
838
+ if (stringdtype_compatible_na (descr1->na_object , descr2->na_object , NULL ) == -1 ) {
866
839
return (NPY_CASTING)-1 ;
867
840
}
868
841
@@ -1061,46 +1034,6 @@ all_strings_promoter(PyObject *NPY_UNUSED(ufunc),
1061
1034
return 0 ;
1062
1035
}
1063
1036
1064
- static NPY_CASTING
1065
- strip_chars_resolve_descriptors (
1066
- struct PyArrayMethodObject_tag *NPY_UNUSED (method),
1067
- PyArray_DTypeMeta *const NPY_UNUSED(dtypes[]),
1068
- PyArray_Descr *const given_descrs[],
1069
- PyArray_Descr *loop_descrs[],
1070
- npy_intp *NPY_UNUSED(view_offset))
1071
- {
1072
- Py_INCREF (given_descrs[0 ]);
1073
- loop_descrs[0 ] = given_descrs[0 ];
1074
-
1075
- // we don't actually care about the null behavior of the second argument,
1076
- // so no need to check if the first two descrs are equal like in
1077
- // binary_resolve_descriptors
1078
-
1079
- Py_INCREF (given_descrs[1 ]);
1080
- loop_descrs[1 ] = given_descrs[1 ];
1081
-
1082
- PyArray_Descr *out_descr = NULL ;
1083
-
1084
- if (given_descrs[2 ] == NULL ) {
1085
- out_descr = (PyArray_Descr *)new_stringdtype_instance (
1086
- ((PyArray_StringDTypeObject *)given_descrs[0 ])->na_object ,
1087
- ((PyArray_StringDTypeObject *)given_descrs[0 ])->coerce );
1088
-
1089
- if (out_descr == NULL ) {
1090
- return (NPY_CASTING)-1 ;
1091
- }
1092
- }
1093
- else {
1094
- Py_INCREF (given_descrs[2 ]);
1095
- out_descr = given_descrs[2 ];
1096
- }
1097
-
1098
- loop_descrs[2 ] = out_descr;
1099
-
1100
- return NPY_NO_CASTING;
1101
- }
1102
-
1103
-
1104
1037
NPY_NO_EXPORT int
1105
1038
string_lrstrip_chars_strided_loop (
1106
1039
PyArrayMethod_Context *context, char *const data[],
@@ -1308,22 +1241,16 @@ replace_resolve_descriptors(struct PyArrayMethodObject_tag *NPY_UNUSED(method),
1308
1241
PyArray_StringDTypeObject *descr1 = (PyArray_StringDTypeObject *)given_descrs[0 ];
1309
1242
PyArray_StringDTypeObject *descr2 = (PyArray_StringDTypeObject *)given_descrs[1 ];
1310
1243
PyArray_StringDTypeObject *descr3 = (PyArray_StringDTypeObject *)given_descrs[2 ];
1244
+ int out_coerce = descr1->coerce && descr2->coerce && descr3->coerce ;
1245
+ PyObject *out_na_object = NULL ;
1311
1246
1312
- // _eq_comparison has a short-circuit pointer comparison fast path, so
1313
- // no need to do it here
1314
- int eq_res = (_eq_comparison (descr1->coerce , descr2->coerce ,
1315
- descr1->na_object , descr2->na_object ) &&
1316
- _eq_comparison (descr1->coerce , descr3->coerce ,
1317
- descr1->na_object , descr3->na_object ));
1318
-
1319
- if (eq_res < 0 ) {
1247
+ if (stringdtype_compatible_na (
1248
+ descr1->na_object , descr2->na_object , &out_na_object) == -1 ) {
1320
1249
return (NPY_CASTING)-1 ;
1321
1250
}
1322
1251
1323
- if (eq_res != 1 ) {
1324
- PyErr_SetString (PyExc_TypeError,
1325
- " String replace is only supported with equal StringDType "
1326
- " instances." );
1252
+ if (stringdtype_compatible_na (
1253
+ out_na_object, descr3->na_object , &out_na_object) == -1 ) {
1327
1254
return (NPY_CASTING)-1 ;
1328
1255
}
1329
1256
@@ -1340,8 +1267,7 @@ replace_resolve_descriptors(struct PyArrayMethodObject_tag *NPY_UNUSED(method),
1340
1267
1341
1268
if (given_descrs[4 ] == NULL ) {
1342
1269
out_descr = (PyArray_Descr *)new_stringdtype_instance (
1343
- ((PyArray_StringDTypeObject *)given_descrs[0 ])->na_object ,
1344
- ((PyArray_StringDTypeObject *)given_descrs[0 ])->coerce );
1270
+ out_na_object, out_coerce);
1345
1271
1346
1272
if (out_descr == NULL ) {
1347
1273
return (NPY_CASTING)-1 ;
@@ -1588,18 +1514,11 @@ center_ljust_rjust_resolve_descriptors(
1588
1514
{
1589
1515
PyArray_StringDTypeObject *input_descr = (PyArray_StringDTypeObject *)given_descrs[0 ];
1590
1516
PyArray_StringDTypeObject *fill_descr = (PyArray_StringDTypeObject *)given_descrs[2 ];
1517
+ int out_coerce = input_descr->coerce && fill_descr->coerce ;
1518
+ PyObject *out_na_object = NULL ;
1591
1519
1592
- int eq_res = _eq_comparison (input_descr->coerce , fill_descr->coerce ,
1593
- input_descr->na_object , fill_descr->na_object );
1594
-
1595
- if (eq_res < 0 ) {
1596
- return (NPY_CASTING)-1 ;
1597
- }
1598
-
1599
- if (eq_res != 1 ) {
1600
- PyErr_SetString (PyExc_TypeError,
1601
- " Can only do text justification operations with equal"
1602
- " StringDType instances." );
1520
+ if (stringdtype_compatible_na (
1521
+ input_descr->na_object , fill_descr->na_object , &out_na_object) == -1 ) {
1603
1522
return (NPY_CASTING)-1 ;
1604
1523
}
1605
1524
@@ -1614,8 +1533,7 @@ center_ljust_rjust_resolve_descriptors(
1614
1533
1615
1534
if (given_descrs[3 ] == NULL ) {
1616
1535
out_descr = (PyArray_Descr *)new_stringdtype_instance (
1617
- ((PyArray_StringDTypeObject *)given_descrs[1 ])->na_object ,
1618
- ((PyArray_StringDTypeObject *)given_descrs[1 ])->coerce );
1536
+ out_na_object, out_coerce);
1619
1537
1620
1538
if (out_descr == NULL ) {
1621
1539
return (NPY_CASTING)-1 ;
@@ -1888,6 +1806,7 @@ zfill_strided_loop(PyArrayMethod_Context *context,
1888
1806
return -1 ;
1889
1807
}
1890
1808
1809
+
1891
1810
static NPY_CASTING
1892
1811
string_partition_resolve_descriptors (
1893
1812
PyArrayMethodObject *self,
@@ -1901,14 +1820,25 @@ string_partition_resolve_descriptors(
1901
1820
" currently support the 'out' keyword" , self->name );
1902
1821
return (NPY_CASTING)-1 ;
1903
1822
}
1904
- for (int i=0 ; i<2 ; i++) {
1905
- Py_INCREF (given_descrs[i]);
1906
- loop_descrs[i] = given_descrs[i];
1823
+
1824
+ PyArray_StringDTypeObject *descr1 = (PyArray_StringDTypeObject *)given_descrs[0 ];
1825
+ PyArray_StringDTypeObject *descr2 = (PyArray_StringDTypeObject *)given_descrs[1 ];
1826
+ int out_coerce = descr1->coerce && descr2->coerce ;
1827
+ PyObject *out_na_object = NULL ;
1828
+
1829
+ if (stringdtype_compatible_na (
1830
+ descr1->na_object , descr2->na_object , &out_na_object) == -1 ) {
1831
+ return (NPY_CASTING)-1 ;
1907
1832
}
1908
- PyArray_StringDTypeObject *adescr = (PyArray_StringDTypeObject *)given_descrs[0 ];
1833
+
1834
+ Py_INCREF (given_descrs[0 ]);
1835
+ loop_descrs[0 ] = given_descrs[0 ];
1836
+ Py_INCREF (given_descrs[1 ]);
1837
+ loop_descrs[1 ] = given_descrs[1 ];
1838
+
1909
1839
for (int i=2 ; i<5 ; i++) {
1910
1840
loop_descrs[i] = (PyArray_Descr *)new_stringdtype_instance (
1911
- adescr-> na_object , adescr-> coerce );
1841
+ out_na_object, out_coerce );
1912
1842
if (loop_descrs[i] == NULL ) {
1913
1843
return (NPY_CASTING)-1 ;
1914
1844
}
@@ -2655,7 +2585,7 @@ init_stringdtype_ufuncs(PyObject *umath)
2655
2585
2656
2586
for (int i=0 ; i<3 ; i++) {
2657
2587
if (init_ufunc (umath, strip_chars_names[i], strip_chars_dtypes,
2658
- &strip_chars_resolve_descriptors ,
2588
+ &binary_resolve_descriptors ,
2659
2589
&string_lrstrip_chars_strided_loop,
2660
2590
2 , 1 , NPY_NO_CASTING, (NPY_ARRAYMETHOD_FLAGS) 0 ,
2661
2591
&strip_types[i]) < 0 ) {
0 commit comments