@@ -121,6 +121,50 @@ PyArray_DTypeFromObject(PyObject *obj, int maxdims, PyArray_Descr **out_dtype)
121
121
return res ;
122
122
}
123
123
124
+ /*
125
+ * Get a suitable string dtype by calling `__str__`.
126
+ * For `np.bytes_`, this assumes an ASCII encoding.
127
+ */
128
+ static PyArray_Descr *
129
+ PyArray_DTypeFromObjectStringDiscovery (
130
+ PyObject * obj , PyArray_Descr * last_dtype , int string_type )
131
+ {
132
+ int itemsize ;
133
+ PyObject * temp ;
134
+
135
+ if (string_type == NPY_STRING ) {
136
+ if ((temp = PyObject_Str (obj )) == NULL ) {
137
+ return NULL ;
138
+ }
139
+ itemsize = PyUnicode_GetLength (temp );
140
+ }
141
+ else if (string_type == NPY_UNICODE ) {
142
+ if ((temp = PyObject_Str (obj )) == NULL ) {
143
+ return NULL ;
144
+ }
145
+ itemsize = PyUnicode_GET_DATA_SIZE (temp );
146
+ #ifndef Py_UNICODE_WIDE
147
+ itemsize <<= 1 ;
148
+ #endif
149
+ }
150
+ else {
151
+ return NULL ;
152
+ }
153
+ Py_DECREF (temp );
154
+ if (last_dtype != NULL &&
155
+ last_dtype -> type_num == string_type &&
156
+ last_dtype -> elsize >= itemsize ) {
157
+ Py_INCREF (last_dtype );
158
+ return last_dtype ;
159
+ }
160
+ PyArray_Descr * dtype = PyArray_DescrNewFromType (string_type );
161
+ if (dtype == NULL ) {
162
+ return NULL ;
163
+ }
164
+ dtype -> elsize = itemsize ;
165
+ return dtype ;
166
+ }
167
+
124
168
NPY_NO_EXPORT int
125
169
PyArray_DTypeFromObjectHelper (PyObject * obj , int maxdims ,
126
170
PyArray_Descr * * out_dtype , int string_type )
@@ -158,38 +202,17 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
158
202
}
159
203
}
160
204
else {
161
- int itemsize ;
162
- PyObject * temp ;
163
-
164
- if (string_type == NPY_STRING ) {
165
- if ((temp = PyObject_Str (obj )) == NULL ) {
166
- goto fail ;
167
- }
168
- itemsize = PyUnicode_GetLength (temp );
169
- }
170
- else if (string_type == NPY_UNICODE ) {
171
- if ((temp = PyObject_Str (obj )) == NULL ) {
172
- goto fail ;
173
- }
174
- itemsize = PyUnicode_GET_DATA_SIZE (temp );
175
- #ifndef Py_UNICODE_WIDE
176
- itemsize <<= 1 ;
177
- #endif
178
- }
179
- else {
205
+ dtype = PyArray_DTypeFromObjectStringDiscovery (
206
+ obj , * out_dtype , string_type );
207
+ if (dtype == NULL ) {
180
208
goto fail ;
181
209
}
182
- Py_DECREF ( temp );
183
- if ( * out_dtype != NULL &&
184
- ( * out_dtype ) -> type_num == string_type &&
185
- ( * out_dtype ) -> elsize >= itemsize ) {
210
+
211
+ /* nothing to do, dtype is already correct */
212
+ if ( dtype == * out_dtype ){
213
+ Py_DECREF ( dtype );
186
214
return 0 ;
187
215
}
188
- dtype = PyArray_DescrNewFromType (string_type );
189
- if (dtype == NULL ) {
190
- goto fail ;
191
- }
192
- dtype -> elsize = itemsize ;
193
216
}
194
217
goto promote_types ;
195
218
}
@@ -198,42 +221,19 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
198
221
dtype = _array_find_python_scalar_type (obj );
199
222
if (dtype != NULL ) {
200
223
if (string_type ) {
201
- int itemsize ;
202
- PyObject * temp ;
203
-
204
224
/* dtype is not used in this (string discovery) branch */
205
225
Py_DECREF (dtype );
206
- dtype = NULL ;
207
-
208
- if (string_type == NPY_STRING ) {
209
- if ((temp = PyObject_Str (obj )) == NULL ) {
210
- goto fail ;
211
- }
212
- itemsize = PyUnicode_GetLength (temp );
213
- }
214
- else if (string_type == NPY_UNICODE ) {
215
- if ((temp = PyObject_Str (obj )) == NULL ) {
216
- goto fail ;
217
- }
218
- itemsize = PyUnicode_GET_DATA_SIZE (temp );
219
- #ifndef Py_UNICODE_WIDE
220
- itemsize <<= 1 ;
221
- #endif
222
- }
223
- else {
226
+ dtype = PyArray_DTypeFromObjectStringDiscovery (
227
+ obj , * out_dtype , string_type );
228
+ if (dtype == NULL ) {
224
229
goto fail ;
225
230
}
226
- Py_DECREF ( temp );
227
- if ( * out_dtype != NULL &&
228
- ( * out_dtype ) -> type_num == string_type &&
229
- ( * out_dtype ) -> elsize >= itemsize ) {
231
+
232
+ /* nothing to do, dtype is already correct */
233
+ if ( dtype == * out_dtype ){
234
+ Py_DECREF ( dtype );
230
235
return 0 ;
231
236
}
232
- dtype = PyArray_DescrNewFromType (string_type );
233
- if (dtype == NULL ) {
234
- goto fail ;
235
- }
236
- dtype -> elsize = itemsize ;
237
237
}
238
238
goto promote_types ;
239
239
}
0 commit comments