1
#define PY_SSIZE_T_CLEAN
2
#include <Python.h>
3
#include "structmember.h"
4

5
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
6
#define _MULTIARRAYMODULE
7
#include "numpy/arrayobject.h"
8
#include "numpy/arrayscalars.h"
9

10
#include "npy_config.h"
11

12
#include "npy_pycompat.h"
13
#include "numpy/npy_math.h"
14

15
#include "array_coercion.h"
16
#include "common.h"
17
#include "ctors.h"
18
#include "dtypemeta.h"
19
#include "scalartypes.h"
20
#include "mapping.h"
21

22
#include "convert_datatype.h"
23
#include "_datetime.h"
24
#include "datetime_strings.h"
25

26

27
/*
28
 * Required length of string when converting from unsigned integer type.
29
 * Array index is integer size in bytes.
30
 * - 3 chars needed for cast to max value of 255 or 127
31
 * - 5 chars needed for cast to max value of 65535 or 32767
32
 * - 10 chars needed for cast to max value of 4294967295 or 2147483647
33
 * - 20 chars needed for cast to max value of 18446744073709551615
34
 *   or 9223372036854775807
35
 */
36
NPY_NO_EXPORT npy_intp REQUIRED_STR_LEN[] = {0, 3, 5, 10, 10, 20, 20, 20, 20};
37

38
/*NUMPY_API
39
 * For backward compatibility
40
 *
41
 * Cast an array using typecode structure.
42
 * steals reference to dtype --- cannot be NULL
43
 *
44
 * This function always makes a copy of arr, even if the dtype
45
 * doesn't change.
46
 */
47
NPY_NO_EXPORT PyObject *
48 1
PyArray_CastToType(PyArrayObject *arr, PyArray_Descr *dtype, int is_f_order)
49
{
50
    PyObject *out;
51

52 1
    Py_SETREF(dtype, PyArray_AdaptDescriptorToArray(arr, (PyObject *)dtype));
53 1
    if (dtype == NULL) {
54
        return NULL;
55
    }
56

57 1
    out = PyArray_NewFromDescr(Py_TYPE(arr), dtype,
58
                               PyArray_NDIM(arr),
59 1
                               PyArray_DIMS(arr),
60
                               NULL, NULL,
61
                               is_f_order,
62
                               (PyObject *)arr);
63

64 1
    if (out == NULL) {
65
        return NULL;
66
    }
67

68 1
    if (PyArray_CopyInto((PyArrayObject *)out, arr) < 0) {
69 0
        Py_DECREF(out);
70
        return NULL;
71
    }
72

73
    return out;
74
}
75

76
/*NUMPY_API
77
 * Get a cast function to cast from the input descriptor to the
78
 * output type_number (must be a registered data-type).
79
 * Returns NULL if un-successful.
80
 */
81
NPY_NO_EXPORT PyArray_VectorUnaryFunc *
82 1
PyArray_GetCastFunc(PyArray_Descr *descr, int type_num)
83
{
84 1
    PyArray_VectorUnaryFunc *castfunc = NULL;
85

86 1
    if (type_num < NPY_NTYPES_ABI_COMPATIBLE) {
87 1
        castfunc = descr->f->cast[type_num];
88
    }
89
    else {
90 1
        PyObject *obj = descr->f->castdict;
91 1
        if (obj && PyDict_Check(obj)) {
92
            PyObject *key;
93
            PyObject *cobj;
94

95 1
            key = PyLong_FromLong(type_num);
96 1
            cobj = PyDict_GetItem(obj, key);
97 1
            Py_DECREF(key);
98 1
            if (cobj && PyCapsule_CheckExact(cobj)) {
99 1
                castfunc = PyCapsule_GetPointer(cobj, NULL);
100 1
                if (castfunc == NULL) {
101
                    return NULL;
102
                }
103
            }
104
        }
105
    }
106 1
    if (PyTypeNum_ISCOMPLEX(descr->type_num) &&
107 1
            !PyTypeNum_ISCOMPLEX(type_num) &&
108 1
            PyTypeNum_ISNUMBER(type_num) &&
109
            !PyTypeNum_ISBOOL(type_num)) {
110 0
        PyObject *cls = NULL, *obj = NULL;
111
        int ret;
112 0
        obj = PyImport_ImportModule("numpy.core");
113

114 0
        if (obj) {
115 0
            cls = PyObject_GetAttrString(obj, "ComplexWarning");
116 0
            Py_DECREF(obj);
117
        }
118 0
        ret = PyErr_WarnEx(cls,
119
                "Casting complex values to real discards "
120
                "the imaginary part", 1);
121 0
        Py_XDECREF(cls);
122 0
        if (ret < 0) {
123
            return NULL;
124
        }
125
    }
126 1
    if (castfunc) {
127
        return castfunc;
128
    }
129

130 1
    PyErr_SetString(PyExc_ValueError,
131
            "No cast function available.");
132 1
    return NULL;
133
}
134

135
/*
136
 * Legacy function to find the correct dtype when casting from any built-in
137
 * dtype to NPY_STRING, NPY_UNICODE, NPY_VOID, and NPY_DATETIME with generic
138
 * units.
139
 *
140
 * This function returns a dtype based on flex_dtype and the values in
141
 * data_dtype. It also calls Py_DECREF on the flex_dtype. If the
142
 * flex_dtype is not flexible, it returns it as-is.
143
 *
144
 * Usually, if data_obj is not an array, dtype should be the result
145
 * given by the PyArray_GetArrayParamsFromObject function.
146
 *
147
 * If *flex_dtype is NULL, returns immediately, without setting an
148
 * exception, leaving any previous error handling intact.
149
 */
150
NPY_NO_EXPORT PyArray_Descr *
151 1
PyArray_AdaptFlexibleDType(PyArray_Descr *data_dtype, PyArray_Descr *flex_dtype)
152
{
153
    PyArray_DatetimeMetaData *meta;
154 1
    PyArray_Descr *retval = NULL;
155
    int flex_type_num;
156

157 1
    if (flex_dtype == NULL) {
158
        return retval;
159
    }
160

161 1
    flex_type_num = flex_dtype->type_num;
162

163
    /* Flexible types with expandable size */
164 1
    if (PyDataType_ISUNSIZED(flex_dtype)) {
165
        /* First replace the flex_dtype */
166 1
        retval = PyArray_DescrNew(flex_dtype);
167 1
        Py_DECREF(flex_dtype);
168 1
        if (retval == NULL) {
169
            return retval;
170
        }
171

172 1
        if (data_dtype->type_num == flex_type_num ||
173
                                    flex_type_num == NPY_VOID) {
174 1
            (retval)->elsize = data_dtype->elsize;
175
        }
176 1
        else if (flex_type_num == NPY_STRING || flex_type_num == NPY_UNICODE) {
177 1
            npy_intp size = 8;
178

179
            /*
180
             * Get a string-size estimate of the input. These
181
             * are generallly the size needed, rounded up to
182
             * a multiple of eight.
183
             */
184 1
            switch (data_dtype->type_num) {
185 1
                case NPY_BOOL:
186
                case NPY_UBYTE:
187
                case NPY_BYTE:
188
                case NPY_USHORT:
189
                case NPY_SHORT:
190
                case NPY_UINT:
191
                case NPY_INT:
192
                case NPY_ULONG:
193
                case NPY_LONG:
194
                case NPY_ULONGLONG:
195
                case NPY_LONGLONG:
196 1
                    if (data_dtype->kind == 'b') {
197
                        /* 5 chars needed for cast to 'True' or 'False' */
198
                        size = 5;
199
                    }
200 1
                    else if (data_dtype->elsize > 8 ||
201
                             data_dtype->elsize < 0) {
202
                        /*
203
                         * Element size should never be greater than 8 or
204
                         * less than 0 for integer type, but just in case...
205
                         */
206
                        break;
207
                    }
208 1
                    else if (data_dtype->kind == 'u') {
209 1
                        size = REQUIRED_STR_LEN[data_dtype->elsize];
210
                    }
211 1
                    else if (data_dtype->kind == 'i') {
212
                        /* Add character for sign symbol */
213 1
                        size = REQUIRED_STR_LEN[data_dtype->elsize] + 1;
214
                    }
215
                    break;
216 1
                case NPY_HALF:
217
                case NPY_FLOAT:
218
                case NPY_DOUBLE:
219 1
                    size = 32;
220 1
                    break;
221 1
                case NPY_LONGDOUBLE:
222 1
                    size = 48;
223 1
                    break;
224 1
                case NPY_CFLOAT:
225
                case NPY_CDOUBLE:
226 1
                    size = 2 * 32;
227 1
                    break;
228 1
                case NPY_CLONGDOUBLE:
229 1
                    size = 2 * 48;
230 1
                    break;
231 0
                case NPY_OBJECT:
232 0
                    size = 64;
233 0
                    break;
234 1
                case NPY_STRING:
235
                case NPY_VOID:
236 1
                    size = data_dtype->elsize;
237 1
                    break;
238 1
                case NPY_UNICODE:
239 1
                    size = data_dtype->elsize / 4;
240 1
                    break;
241 1
                case NPY_DATETIME:
242 1
                    meta = get_datetime_metadata_from_dtype(data_dtype);
243 1
                    if (meta == NULL) {
244 0
                        Py_DECREF(retval);
245
                        return NULL;
246
                    }
247 1
                    size = get_datetime_iso_8601_strlen(0, meta->base);
248 1
                    break;
249 1
                case NPY_TIMEDELTA:
250 1
                    size = 21;
251 1
                    break;
252
            }
253

254 1
            if (flex_type_num == NPY_STRING) {
255 1
                retval->elsize = size;
256
            }
257 1
            else if (flex_type_num == NPY_UNICODE) {
258 1
                retval->elsize = size * 4;
259
            }
260
        }
261
        else {
262
            /*
263
             * We should never get here, but just in case someone adds
264
             * a new flex dtype...
265
             */
266 0
            PyErr_SetString(PyExc_TypeError,
267
                    "don't know how to adapt flex dtype");
268 0
            Py_DECREF(retval);
269
            return NULL;
270
        }
271
    }
272
    /* Flexible type with generic time unit that adapts */
273 1
    else if (flex_type_num == NPY_DATETIME ||
274
                flex_type_num == NPY_TIMEDELTA) {
275 1
        meta = get_datetime_metadata_from_dtype(flex_dtype);
276 1
        retval = flex_dtype;
277 1
        if (meta == NULL) {
278
            return NULL;
279
        }
280

281 1
        if (meta->base == NPY_FR_GENERIC) {
282 1
            if (data_dtype->type_num == NPY_DATETIME ||
283
                    data_dtype->type_num == NPY_TIMEDELTA) {
284 0
                meta = get_datetime_metadata_from_dtype(data_dtype);
285 0
                if (meta == NULL) {
286
                    return NULL;
287
                }
288

289 0
                retval = create_datetime_dtype(flex_type_num, meta);
290 0
                Py_DECREF(flex_dtype);
291
            }
292
        }
293
    }
294
    else {
295
        retval = flex_dtype;
296
    }
297
    return retval;
298
}
299

300
/*
301
 * Must be broadcastable.
302
 * This code is very similar to PyArray_CopyInto/PyArray_MoveInto
303
 * except casting is done --- NPY_BUFSIZE is used
304
 * as the size of the casting buffer.
305
 */
306

307
/*NUMPY_API
308
 * Cast to an already created array.
309
 */
310
NPY_NO_EXPORT int
311 0
PyArray_CastTo(PyArrayObject *out, PyArrayObject *mp)
312
{
313
    /* CopyInto handles the casting now */
314 0
    return PyArray_CopyInto(out, mp);
315
}
316

317
/*NUMPY_API
318
 * Cast to an already created array.  Arrays don't have to be "broadcastable"
319
 * Only requirement is they have the same number of elements.
320
 */
321
NPY_NO_EXPORT int
322 0
PyArray_CastAnyTo(PyArrayObject *out, PyArrayObject *mp)
323
{
324
    /* CopyAnyInto handles the casting now */
325 0
    return PyArray_CopyAnyInto(out, mp);
326
}
327

328
/*NUMPY_API
329
 *Check the type coercion rules.
330
 */
331
NPY_NO_EXPORT int
332 1
PyArray_CanCastSafely(int fromtype, int totype)
333
{
334
    PyArray_Descr *from;
335

336
    /* Fast table lookup for small type numbers */
337 1
    if ((unsigned int)fromtype < NPY_NTYPES &&
338 1
                                (unsigned int)totype < NPY_NTYPES) {
339 1
        return _npy_can_cast_safely_table[fromtype][totype];
340
    }
341

342
    /* Identity */
343 1
    if (fromtype == totype) {
344
        return 1;
345
    }
346

347 1
    from = PyArray_DescrFromType(fromtype);
348
    /*
349
     * cancastto is a NPY_NOTYPE terminated C-int-array of types that
350
     * the data-type can be cast to safely.
351
     */
352 1
    if (from->f->cancastto) {
353
        int *curtype = from->f->cancastto;
354

355 1
        while (*curtype != NPY_NOTYPE) {
356 1
            if (*curtype++ == totype) {
357
                return 1;
358
            }
359
        }
360
    }
361
    return 0;
362
}
363

364
/*NUMPY_API
365
 * leaves reference count alone --- cannot be NULL
366
 *
367
 * PyArray_CanCastTypeTo is equivalent to this, but adds a 'casting'
368
 * parameter.
369
 */
370
NPY_NO_EXPORT npy_bool
371 1
PyArray_CanCastTo(PyArray_Descr *from, PyArray_Descr *to)
372
{
373 1
    int from_type_num = from->type_num;
374 1
    int to_type_num = to->type_num;
375
    npy_bool ret;
376

377 1
    ret = (npy_bool) PyArray_CanCastSafely(from_type_num, to_type_num);
378 1
    if (ret) {
379
        /* Check String and Unicode more closely */
380 1
        if (from_type_num == NPY_STRING) {
381 1
            if (to_type_num == NPY_STRING) {
382 0
                ret = (from->elsize <= to->elsize);
383
            }
384 1
            else if (to_type_num == NPY_UNICODE) {
385 0
                ret = (from->elsize << 2 <= to->elsize);
386
            }
387
        }
388 1
        else if (from_type_num == NPY_UNICODE) {
389 1
            if (to_type_num == NPY_UNICODE) {
390 0
                ret = (from->elsize <= to->elsize);
391
            }
392
        }
393
        /*
394
         * For datetime/timedelta, only treat casts moving towards
395
         * more precision as safe.
396
         */
397 1
        else if (from_type_num == NPY_DATETIME && to_type_num == NPY_DATETIME) {
398
            PyArray_DatetimeMetaData *meta1, *meta2;
399 0
            meta1 = get_datetime_metadata_from_dtype(from);
400 0
            if (meta1 == NULL) {
401 0
                PyErr_Clear();
402 0
                return 0;
403
            }
404 0
            meta2 = get_datetime_metadata_from_dtype(to);
405 0
            if (meta2 == NULL) {
406 0
                PyErr_Clear();
407 0
                return 0;
408
            }
409

410 0
            return can_cast_datetime64_metadata(meta1, meta2,
411
                                                NPY_SAFE_CASTING);
412
        }
413 1
        else if (from_type_num == NPY_TIMEDELTA &&
414 1
                                    to_type_num == NPY_TIMEDELTA) {
415
            PyArray_DatetimeMetaData *meta1, *meta2;
416 0
            meta1 = get_datetime_metadata_from_dtype(from);
417 0
            if (meta1 == NULL) {
418 0
                PyErr_Clear();
419 0
                return 0;
420
            }
421 0
            meta2 = get_datetime_metadata_from_dtype(to);
422 0
            if (meta2 == NULL) {
423 0
                PyErr_Clear();
424 0
                return 0;
425
            }
426

427 0
            return can_cast_timedelta64_metadata(meta1, meta2,
428
                                                 NPY_SAFE_CASTING);
429
        }
430
        /*
431
         * If to_type_num is STRING or unicode
432
         * see if the length is long enough to hold the
433
         * stringified value of the object.
434
         */
435 1
        else if (to_type_num == NPY_STRING || to_type_num == NPY_UNICODE) {
436
            /*
437
             * Boolean value cast to string type is 5 characters max
438
             * for string 'False'.
439
             */
440 1
            int char_size = 1;
441 1
            if (to_type_num == NPY_UNICODE) {
442 1
                char_size = 4;
443
            }
444

445 1
            ret = 0;
446 1
            if (PyDataType_ISUNSIZED(to)) {
447
                ret = 1;
448
            }
449
            /*
450
             * Need at least 5 characters to convert from boolean
451
             * to 'True' or 'False'.
452
             */
453 1
            else if (from->kind == 'b' && to->elsize >= 5 * char_size) {
454
                ret = 1;
455
            }
456 1
            else if (from->kind == 'u') {
457
                /* Guard against unexpected integer size */
458 1
                if (from->elsize > 8 || from->elsize < 0) {
459
                    ret = 0;
460
                }
461 1
                else if (to->elsize >=
462 1
                        REQUIRED_STR_LEN[from->elsize] * char_size) {
463 1
                    ret = 1;
464
                }
465
            }
466 1
            else if (from->kind == 'i') {
467
                /* Guard against unexpected integer size */
468 1
                if (from->elsize > 8 || from->elsize < 0) {
469
                    ret = 0;
470
                }
471
                /* Extra character needed for sign */
472 1
                else if (to->elsize >=
473 1
                        (REQUIRED_STR_LEN[from->elsize] + 1) * char_size) {
474 1
                    ret = 1;
475
                }
476
            }
477
        }
478
    }
479
    return ret;
480
}
481

482
/* Provides an ordering for the dtype 'kind' character codes */
483
static int
484
dtype_kind_to_ordering(char kind)
485
{
486 1
    switch (kind) {
487
        /* Boolean kind */
488
        case 'b':
489
            return 0;
490
        /* Unsigned int kind */
491
        case 'u':
492
            return 1;
493
        /* Signed int kind */
494
        case 'i':
495
            return 2;
496
        /* Float kind */
497
        case 'f':
498
            return 4;
499
        /* Complex kind */
500
        case 'c':
501
            return 5;
502
        /* String kind */
503
        case 'S':
504
        case 'a':
505
            return 6;
506
        /* Unicode kind */
507
        case 'U':
508
            return 7;
509
        /* Void kind */
510
        case 'V':
511
            return 8;
512
        /* Object kind */
513
        case 'O':
514
            return 9;
515
        /*
516
         * Anything else, like datetime, is special cased to
517
         * not fit in this hierarchy
518
         */
519
        default:
520
            return -1;
521
    }
522
}
523

524
/* Converts a type number from unsigned to signed */
525
static int
526
type_num_unsigned_to_signed(int type_num)
527
{
528 1
    switch (type_num) {
529
        case NPY_UBYTE:
530
            return NPY_BYTE;
531 1
        case NPY_USHORT:
532
            return NPY_SHORT;
533 1
        case NPY_UINT:
534
            return NPY_INT;
535 1
        case NPY_ULONG:
536
            return NPY_LONG;
537 1
        case NPY_ULONGLONG:
538
            return NPY_LONGLONG;
539 0
        default:
540
            return type_num;
541
    }
542
}
543

544
/*
545
 * Compare two field dictionaries for castability.
546
 *
547
 * Return 1 if 'field1' can be cast to 'field2' according to the rule
548
 * 'casting', 0 if not.
549
 *
550
 * Castabiliy of field dictionaries is defined recursively: 'field1' and
551
 * 'field2' must have the same field names (possibly in different
552
 * orders), and the corresponding field types must be castable according
553
 * to the given casting rule.
554
 */
555
static int
556 1
can_cast_fields(PyObject *field1, PyObject *field2, NPY_CASTING casting)
557
{
558
    Py_ssize_t ppos;
559
    PyObject *key;
560
    PyObject *tuple1, *tuple2;
561

562 1
    if (field1 == field2) {
563
        return 1;
564
    }
565 1
    if (field1 == NULL || field2 == NULL) {
566
        return 0;
567
    }
568 1
    if (PyDict_Size(field1) != PyDict_Size(field2)) {
569
        return 0;
570
    }
571

572
    /* Iterate over all the fields and compare for castability */
573 1
    ppos = 0;
574 1
    while (PyDict_Next(field1, &ppos, &key, &tuple1)) {
575 1
        if ((tuple2 = PyDict_GetItem(field2, key)) == NULL) {
576
            return 0;
577
        }
578
        /* Compare the dtype of the field for castability */
579 1
        if (!PyArray_CanCastTypeTo(
580 1
                        (PyArray_Descr *)PyTuple_GET_ITEM(tuple1, 0),
581 1
                        (PyArray_Descr *)PyTuple_GET_ITEM(tuple2, 0),
582
                        casting)) {
583
            return 0;
584
        }
585
    }
586

587
    return 1;
588
}
589

590
/*NUMPY_API
591
 * Returns true if data of type 'from' may be cast to data of type
592
 * 'to' according to the rule 'casting'.
593
 */
594
NPY_NO_EXPORT npy_bool
595 1
PyArray_CanCastTypeTo(PyArray_Descr *from, PyArray_Descr *to,
596
                                                    NPY_CASTING casting)
597
{
598
    /*
599
     * Fast paths for equality and for basic types.
600
     */
601 1
    if (from == to ||
602 1
        ((NPY_LIKELY(PyDataType_ISNUMBER(from)) ||
603 1
          PyDataType_ISOBJECT(from)) &&
604 1
         NPY_LIKELY(from->type_num == to->type_num) &&
605 1
         NPY_LIKELY(from->byteorder == to->byteorder))) {
606
        return 1;
607
    }
608
    /*
609
     * Cases with subarrays and fields need special treatment.
610
     */
611 1
    if (PyDataType_HASFIELDS(from)) {
612
        /*
613
         * If from is a structured data type, then it can be cast to a simple
614
         * non-object one only for unsafe casting *and* if it has a single
615
         * field; recurse just in case the single field is itself structured.
616
         */
617 1
        if (!PyDataType_HASFIELDS(to) && !PyDataType_ISOBJECT(to)) {
618 1
            if (casting == NPY_UNSAFE_CASTING &&
619 1
                    PyDict_Size(from->fields) == 1) {
620 1
                Py_ssize_t ppos = 0;
621
                PyObject *tuple;
622
                PyArray_Descr *field;
623 1
                PyDict_Next(from->fields, &ppos, NULL, &tuple);
624 1
                field = (PyArray_Descr *)PyTuple_GET_ITEM(tuple, 0);
625
                /*
626
                 * For a subarray, we need to get the underlying type;
627
                 * since we already are casting unsafely, we can ignore
628
                 * the shape.
629
                 */
630 1
                if (PyDataType_HASSUBARRAY(field)) {
631 1
                    field = field->subarray->base;
632
                }
633 1
                return PyArray_CanCastTypeTo(field, to, casting);
634
            }
635
            else {
636
                return 0;
637
            }
638
        }
639
        /*
640
         * Casting from one structured data type to another depends on the fields;
641
         * we pass that case on to the EquivTypenums case below.
642
         *
643
         * TODO: move that part up here? Need to check whether equivalent type
644
         * numbers is an addition constraint that is needed.
645
         *
646
         * TODO/FIXME: For now, always allow structured to structured for unsafe
647
         * casting; this is not correct, but needed since the treatment in can_cast
648
         * below got out of sync with astype; see gh-13667.
649
         */
650 1
        if (casting == NPY_UNSAFE_CASTING) {
651
            return 1;
652
        }
653
    }
654 1
    else if (PyDataType_HASFIELDS(to)) {
655
        /*
656
         * If "from" is a simple data type and "to" has fields, then only
657
         * unsafe casting works (and that works always, even to multiple fields).
658
         */
659 1
        return casting == NPY_UNSAFE_CASTING;
660
    }
661
    /*
662
     * Everything else we consider castable for unsafe for now.
663
     * FIXME: ensure what we do here is consistent with "astype",
664
     * i.e., deal more correctly with subarrays and user-defined dtype.
665
     */
666 1
    else if (casting == NPY_UNSAFE_CASTING) {
667
        return 1;
668
    }
669
    /*
670
     * Equivalent simple types can be cast with any value of 'casting', but
671
     * we need to be careful about structured to structured.
672
     */
673 1
    if (PyArray_EquivTypenums(from->type_num, to->type_num)) {
674
        /* For complicated case, use EquivTypes (for now) */
675 1
        if (PyTypeNum_ISUSERDEF(from->type_num) ||
676 1
                        from->subarray != NULL) {
677
            int ret;
678

679
            /* Only NPY_NO_CASTING prevents byte order conversion */
680 1
            if ((casting != NPY_NO_CASTING) &&
681 1
                                (!PyArray_ISNBO(from->byteorder) ||
682 1
                                 !PyArray_ISNBO(to->byteorder))) {
683
                PyArray_Descr *nbo_from, *nbo_to;
684

685 0
                nbo_from = PyArray_DescrNewByteorder(from, NPY_NATIVE);
686 0
                nbo_to = PyArray_DescrNewByteorder(to, NPY_NATIVE);
687 0
                if (nbo_from == NULL || nbo_to == NULL) {
688 0
                    Py_XDECREF(nbo_from);
689 0
                    Py_XDECREF(nbo_to);
690 0
                    PyErr_Clear();
691 0
                    return 0;
692
                }
693 0
                ret = PyArray_EquivTypes(nbo_from, nbo_to);
694 0
                Py_DECREF(nbo_from);
695 0
                Py_DECREF(nbo_to);
696
            }
697
            else {
698 1
                ret = PyArray_EquivTypes(from, to);
699
            }
700 1
            return ret;
701
        }
702

703 1
        if (PyDataType_HASFIELDS(from)) {
704 1
            switch (casting) {
705 1
                case NPY_EQUIV_CASTING:
706
                case NPY_SAFE_CASTING:
707
                case NPY_SAME_KIND_CASTING:
708
                    /*
709
                     * `from' and `to' must have the same fields, and
710
                     * corresponding fields must be (recursively) castable.
711
                     */
712 1
                    return can_cast_fields(from->fields, to->fields, casting);
713

714 1
                case NPY_NO_CASTING:
715
                default:
716 1
                    return PyArray_EquivTypes(from, to);
717
            }
718
        }
719

720 1
        switch (from->type_num) {
721 1
            case NPY_DATETIME: {
722
                PyArray_DatetimeMetaData *meta1, *meta2;
723 1
                meta1 = get_datetime_metadata_from_dtype(from);
724 1
                if (meta1 == NULL) {
725 0
                    PyErr_Clear();
726 0
                    return 0;
727
                }
728 1
                meta2 = get_datetime_metadata_from_dtype(to);
729 1
                if (meta2 == NULL) {
730 0
                    PyErr_Clear();
731 0
                    return 0;
732
                }
733

734 1
                if (casting == NPY_NO_CASTING) {
735 0
                    return PyArray_ISNBO(from->byteorder) ==
736 0
                                        PyArray_ISNBO(to->byteorder) &&
737 0
                            can_cast_datetime64_metadata(meta1, meta2, casting);
738
                }
739
                else {
740 1
                    return can_cast_datetime64_metadata(meta1, meta2, casting);
741
                }
742
            }
743 1
            case NPY_TIMEDELTA: {
744
                PyArray_DatetimeMetaData *meta1, *meta2;
745 1
                meta1 = get_datetime_metadata_from_dtype(from);
746 1
                if (meta1 == NULL) {
747 0
                    PyErr_Clear();
748 0
                    return 0;
749
                }
750 1
                meta2 = get_datetime_metadata_from_dtype(to);
751 1
                if (meta2 == NULL) {
752 0
                    PyErr_Clear();
753 0
                    return 0;
754
                }
755

756 1
                if (casting == NPY_NO_CASTING) {
757 0
                    return PyArray_ISNBO(from->byteorder) ==
758 0
                                        PyArray_ISNBO(to->byteorder) &&
759 0
                        can_cast_timedelta64_metadata(meta1, meta2, casting);
760
                }
761
                else {
762 1
                    return can_cast_timedelta64_metadata(meta1, meta2, casting);
763
                }
764
            }
765 1
            default:
766 1
                switch (casting) {
767 1
                    case NPY_NO_CASTING:
768 1
                        return PyArray_EquivTypes(from, to);
769 1
                    case NPY_EQUIV_CASTING:
770 1
                        return (from->elsize == to->elsize);
771 1
                    case NPY_SAFE_CASTING:
772 1
                        return (from->elsize <= to->elsize);
773
                    default:
774
                        return 1;
775
                }
776
                break;
777
        }
778
    }
779
    /* If safe or same-kind casts are allowed */
780 1
    else if (casting == NPY_SAFE_CASTING || casting == NPY_SAME_KIND_CASTING) {
781 1
        if (PyArray_CanCastTo(from, to)) {
782
            return 1;
783
        }
784 1
        else if(casting == NPY_SAME_KIND_CASTING) {
785
            /*
786
             * Also allow casting from lower to higher kinds, according
787
             * to the ordering provided by dtype_kind_to_ordering.
788
             * Some kinds, like datetime, don't fit in the hierarchy,
789
             * and are special cased as -1.
790
             */
791
            int from_order, to_order;
792

793 1
            from_order = dtype_kind_to_ordering(from->kind);
794 1
            to_order = dtype_kind_to_ordering(to->kind);
795

796 1
            if (to->kind == 'm') {
797
                /* both types being timedelta is already handled before. */
798 1
                int integer_order = dtype_kind_to_ordering('i');
799 1
                return (from_order != -1) && (from_order <= integer_order);
800
            }
801

802 1
            return (from_order != -1) && (from_order <= to_order);
803
        }
804
        else {
805
            return 0;
806
        }
807
    }
808
    /* NPY_NO_CASTING or NPY_EQUIV_CASTING was specified */
809
    else {
810
        return 0;
811
    }
812
}
813

814
/* CanCastArrayTo needs this function */
815
static int min_scalar_type_num(char *valueptr, int type_num,
816
                                            int *is_small_unsigned);
817

818
NPY_NO_EXPORT npy_bool
819 1
can_cast_scalar_to(PyArray_Descr *scal_type, char *scal_data,
820
                    PyArray_Descr *to, NPY_CASTING casting)
821
{
822
    int swap;
823 1
    int is_small_unsigned = 0, type_num;
824
    npy_bool ret;
825
    PyArray_Descr *dtype;
826

827
    /* An aligned memory buffer large enough to hold any type */
828
    npy_longlong value[4];
829

830
    /*
831
     * If the two dtypes are actually references to the same object
832
     * or if casting type is forced unsafe then always OK.
833
     */
834 1
    if (scal_type == to || casting == NPY_UNSAFE_CASTING ) {
835
        return 1;
836
    }
837

838
    /*
839
     * If the scalar isn't a number, or the rule is stricter than
840
     * NPY_SAFE_CASTING, use the straight type-based rules
841
     */
842 1
    if (!PyTypeNum_ISNUMBER(scal_type->type_num) ||
843
                            casting < NPY_SAFE_CASTING) {
844 1
        return PyArray_CanCastTypeTo(scal_type, to, casting);
845
    }
846

847 1
    swap = !PyArray_ISNBO(scal_type->byteorder);
848 1
    scal_type->f->copyswap(&value, scal_data, swap, NULL);
849

850 1
    type_num = min_scalar_type_num((char *)&value, scal_type->type_num,
851
                                    &is_small_unsigned);
852

853
    /*
854
     * If we've got a small unsigned scalar, and the 'to' type
855
     * is not unsigned, then make it signed to allow the value
856
     * to be cast more appropriately.
857
     */
858 1
    if (is_small_unsigned && !(PyTypeNum_ISUNSIGNED(to->type_num))) {
859
        type_num = type_num_unsigned_to_signed(type_num);
860
    }
861

862 1
    dtype = PyArray_DescrFromType(type_num);
863 1
    if (dtype == NULL) {
864
        return 0;
865
    }
866
#if 0
867
    printf("min scalar cast ");
868
    PyObject_Print(dtype, stdout, 0);
869
    printf(" to ");
870
    PyObject_Print(to, stdout, 0);
871
    printf("\n");
872
#endif
873 1
    ret = PyArray_CanCastTypeTo(dtype, to, casting);
874 1
    Py_DECREF(dtype);
875
    return ret;
876
}
877

878
/*NUMPY_API
879
 * Returns 1 if the array object may be cast to the given data type using
880
 * the casting rule, 0 otherwise.  This differs from PyArray_CanCastTo in
881
 * that it handles scalar arrays (0 dimensions) specially, by checking
882
 * their value.
883
 */
884
NPY_NO_EXPORT npy_bool
885 1
PyArray_CanCastArrayTo(PyArrayObject *arr, PyArray_Descr *to,
886
                        NPY_CASTING casting)
887
{
888 1
    PyArray_Descr *from = PyArray_DESCR(arr);
889

890
    /* If it's a scalar, check the value */
891 1
    if (PyArray_NDIM(arr) == 0 && !PyArray_HASFIELDS(arr)) {
892 1
        return can_cast_scalar_to(from, PyArray_DATA(arr), to, casting);
893
    }
894

895
    /* Otherwise, use the standard rules */
896 1
    return PyArray_CanCastTypeTo(from, to, casting);
897
}
898

899

900
NPY_NO_EXPORT const char *
901 1
npy_casting_to_string(NPY_CASTING casting)
902
{
903 1
    switch (casting) {
904
        case NPY_NO_CASTING:
905
            return "'no'";
906 1
        case NPY_EQUIV_CASTING:
907 0
            return "'equiv'";
908 1
        case NPY_SAFE_CASTING:
909 1
            return "'safe'";
910 1
        case NPY_SAME_KIND_CASTING:
911 1
            return "'same_kind'";
912 1
        case NPY_UNSAFE_CASTING:
913 0
            return "'unsafe'";
914 0
        default:
915 0
            return "<unknown>";
916
    }
917
}
918

919

920
/**
921
 * Helper function to set a useful error when casting is not possible.
922
 *
923
 * @param src_dtype
924
 * @param dst_dtype
925
 * @param casting
926
 * @param scalar Whether this was a "scalar" cast (includes 0-D array with
927
 *               PyArray_CanCastArrayTo result).
928
 */
929
NPY_NO_EXPORT void
930 1
npy_set_invalid_cast_error(
931
        PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
932
        NPY_CASTING casting, npy_bool scalar)
933
{
934
    char *msg;
935

936 1
    if (!scalar) {
937
        msg = "Cannot cast array data from %R to %R according to the rule %s";
938
    }
939
    else {
940 1
        msg = "Cannot cast scalar from %R to %R according to the rule %s";
941
    }
942 1
    PyErr_Format(PyExc_TypeError,
943
            msg, src_dtype, dst_dtype, npy_casting_to_string(casting));
944
}
945

946

947
/*NUMPY_API
948
 * See if array scalars can be cast.
949
 *
950
 * TODO: For NumPy 2.0, add a NPY_CASTING parameter.
951
 */
952
NPY_NO_EXPORT npy_bool
953 0
PyArray_CanCastScalar(PyTypeObject *from, PyTypeObject *to)
954
{
955
    int fromtype;
956
    int totype;
957

958 0
    fromtype = _typenum_fromtypeobj((PyObject *)from, 0);
959 0
    totype = _typenum_fromtypeobj((PyObject *)to, 0);
960 0
    if (fromtype == NPY_NOTYPE || totype == NPY_NOTYPE) {
961
        return NPY_FALSE;
962
    }
963 0
    return (npy_bool) PyArray_CanCastSafely(fromtype, totype);
964
}
965

966
/*
967
 * Internal promote types function which handles unsigned integers which
968
 * fit in same-sized signed integers specially.
969
 */
970
static PyArray_Descr *
971 1
promote_types(PyArray_Descr *type1, PyArray_Descr *type2,
972
                        int is_small_unsigned1, int is_small_unsigned2)
973
{
974 1
    if (is_small_unsigned1) {
975 1
        int type_num1 = type1->type_num;
976 1
        int type_num2 = type2->type_num;
977
        int ret_type_num;
978

979 1
        if (type_num2 < NPY_NTYPES && !(PyTypeNum_ISBOOL(type_num2) ||
980 1
                                        PyTypeNum_ISUNSIGNED(type_num2))) {
981
            /* Convert to the equivalent-sized signed integer */
982 1
            type_num1 = type_num_unsigned_to_signed(type_num1);
983

984 1
            ret_type_num = _npy_type_promotion_table[type_num1][type_num2];
985
            /* The table doesn't handle string/unicode/void, check the result */
986 1
            if (ret_type_num >= 0) {
987 1
                return PyArray_DescrFromType(ret_type_num);
988
            }
989
        }
990

991 1
        return PyArray_PromoteTypes(type1, type2);
992
    }
993 1
    else if (is_small_unsigned2) {
994 1
        int type_num1 = type1->type_num;
995 1
        int type_num2 = type2->type_num;
996
        int ret_type_num;
997

998 1
        if (type_num1 < NPY_NTYPES && !(PyTypeNum_ISBOOL(type_num1) ||
999 1
                                        PyTypeNum_ISUNSIGNED(type_num1))) {
1000
            /* Convert to the equivalent-sized signed integer */
1001 1
            type_num2 = type_num_unsigned_to_signed(type_num2);
1002

1003 1
            ret_type_num = _npy_type_promotion_table[type_num1][type_num2];
1004
            /* The table doesn't handle string/unicode/void, check the result */
1005 1
            if (ret_type_num >= 0) {
1006 1
                return PyArray_DescrFromType(ret_type_num);
1007
            }
1008
        }
1009

1010 1
        return PyArray_PromoteTypes(type1, type2);
1011
    }
1012
    else {
1013 1
        return PyArray_PromoteTypes(type1, type2);
1014
    }
1015

1016
}
1017

1018
/*
1019
 * Returns a new reference to type if it is already NBO, otherwise
1020
 * returns a copy converted to NBO.
1021
 */
1022
static PyArray_Descr *
1023
ensure_dtype_nbo(PyArray_Descr *type)
1024
{
1025 1
    if (PyArray_ISNBO(type->byteorder)) {
1026 1
        Py_INCREF(type);
1027
        return type;
1028
    }
1029
    else {
1030 1
        return PyArray_DescrNewByteorder(type, NPY_NATIVE);
1031
    }
1032
}
1033

1034
/*NUMPY_API
1035
 * Produces the smallest size and lowest kind type to which both
1036
 * input types can be cast.
1037
 */
1038
NPY_NO_EXPORT PyArray_Descr *
1039 1
PyArray_PromoteTypes(PyArray_Descr *type1, PyArray_Descr *type2)
1040
{
1041
    int type_num1, type_num2, ret_type_num;
1042

1043
    /*
1044
     * Fast path for identical dtypes.
1045
     *
1046
     * Non-native-byte-order types are converted to native ones below, so we
1047
     * can't quit early.
1048
     */
1049 1
    if (type1 == type2 && PyArray_ISNBO(type1->byteorder)) {
1050 1
        Py_INCREF(type1);
1051 1
        return type1;
1052
    }
1053

1054 1
    type_num1 = type1->type_num;
1055 1
    type_num2 = type2->type_num;
1056

1057
    /* If they're built-in types, use the promotion table */
1058 1
    if (type_num1 < NPY_NTYPES && type_num2 < NPY_NTYPES) {
1059 1
        ret_type_num = _npy_type_promotion_table[type_num1][type_num2];
1060
        /*
1061
         * The table doesn't handle string/unicode/void/datetime/timedelta,
1062
         * so check the result
1063
         */
1064 1
        if (ret_type_num >= 0) {
1065 1
            return PyArray_DescrFromType(ret_type_num);
1066
        }
1067
    }
1068
    /* If one or both are user defined, calculate it */
1069
    else {
1070 1
        int skind1 = NPY_NOSCALAR, skind2 = NPY_NOSCALAR, skind;
1071

1072 1
        if (PyArray_CanCastTo(type2, type1)) {
1073
            /* Promoted types are always native byte order */
1074
            return ensure_dtype_nbo(type1);
1075
        }
1076 1
        else if (PyArray_CanCastTo(type1, type2)) {
1077
            /* Promoted types are always native byte order */
1078
            return ensure_dtype_nbo(type2);
1079
        }
1080

1081
        /* Convert the 'kind' char into a scalar kind */
1082 1
        switch (type1->kind) {
1083
            case 'b':
1084
                skind1 = NPY_BOOL_SCALAR;
1085
                break;
1086
            case 'u':
1087
                skind1 = NPY_INTPOS_SCALAR;
1088
                break;
1089
            case 'i':
1090
                skind1 = NPY_INTNEG_SCALAR;
1091
                break;
1092
            case 'f':
1093
                skind1 = NPY_FLOAT_SCALAR;
1094
                break;
1095
            case 'c':
1096
                skind1 = NPY_COMPLEX_SCALAR;
1097
                break;
1098
        }
1099 1
        switch (type2->kind) {
1100
            case 'b':
1101
                skind2 = NPY_BOOL_SCALAR;
1102
                break;
1103
            case 'u':
1104
                skind2 = NPY_INTPOS_SCALAR;
1105
                break;
1106
            case 'i':
1107
                skind2 = NPY_INTNEG_SCALAR;
1108
                break;
1109
            case 'f':
1110
                skind2 = NPY_FLOAT_SCALAR;
1111
                break;
1112
            case 'c':
1113
                skind2 = NPY_COMPLEX_SCALAR;
1114
                break;
1115
        }
1116

1117
        /* If both are scalars, there may be a promotion possible */
1118 1
        if (skind1 != NPY_NOSCALAR && skind2 != NPY_NOSCALAR) {
1119

1120
            /* Start with the larger scalar kind */
1121 0
            skind = (skind1 > skind2) ? skind1 : skind2;
1122 0
            ret_type_num = _npy_smallest_type_of_kind_table[skind];
1123

1124
            for (;;) {
1125

1126
                /* If there is no larger type of this kind, try a larger kind */
1127 0
                if (ret_type_num < 0) {
1128 0
                    ++skind;
1129
                    /* Use -1 to signal no promoted type found */
1130 0
                    if (skind < NPY_NSCALARKINDS) {
1131 0
                        ret_type_num = _npy_smallest_type_of_kind_table[skind];
1132
                    }
1133
                    else {
1134
                        break;
1135
                    }
1136
                }
1137

1138
                /* If we found a type to which we can promote both, done! */
1139 0
                if (PyArray_CanCastSafely(type_num1, ret_type_num) &&
1140 0
                            PyArray_CanCastSafely(type_num2, ret_type_num)) {
1141 0
                    return PyArray_DescrFromType(ret_type_num);
1142
                }
1143

1144
                /* Try the next larger type of this kind */
1145 0
                ret_type_num = _npy_next_larger_type_table[ret_type_num];
1146
            }
1147

1148
        }
1149

1150 1
        PyErr_SetString(PyExc_TypeError,
1151
                "invalid type promotion with custom data type");
1152 1
        return NULL;
1153
    }
1154

1155 1
    switch (type_num1) {
1156
        /* BOOL can convert to anything except datetime/void */
1157 1
        case NPY_BOOL:
1158 1
            if (type_num2 == NPY_STRING || type_num2 == NPY_UNICODE) {
1159 1
                int char_size = 1;
1160 1
                if (type_num2 == NPY_UNICODE) {
1161 1
                    char_size = 4;
1162
                }
1163 1
                if (type2->elsize < 5 * char_size) {
1164 1
                    PyArray_Descr *ret = NULL;
1165 1
                    PyArray_Descr *temp = PyArray_DescrNew(type2);
1166 1
                    ret = ensure_dtype_nbo(temp);
1167 1
                    ret->elsize = 5 * char_size;
1168 1
                    Py_DECREF(temp);
1169
                    return ret;
1170
                }
1171
                return ensure_dtype_nbo(type2);
1172
            }
1173 1
            else if (type_num2 != NPY_DATETIME && type_num2 != NPY_VOID) {
1174
                return ensure_dtype_nbo(type2);
1175
            }
1176
            break;
1177
        /* For strings and unicodes, take the larger size */
1178 1
        case NPY_STRING:
1179 1
            if (type_num2 == NPY_STRING) {
1180 1
                if (type1->elsize > type2->elsize) {
1181
                    return ensure_dtype_nbo(type1);
1182
                }
1183
                else {
1184
                    return ensure_dtype_nbo(type2);
1185
                }
1186
            }
1187 1
            else if (type_num2 == NPY_UNICODE) {
1188 1
                if (type2->elsize >= type1->elsize * 4) {
1189
                    return ensure_dtype_nbo(type2);
1190
                }
1191
                else {
1192 1
                    PyArray_Descr *d = PyArray_DescrNewFromType(NPY_UNICODE);
1193 1
                    if (d == NULL) {
1194
                        return NULL;
1195
                    }
1196 1
                    d->elsize = type1->elsize * 4;
1197 1
                    return d;
1198
                }
1199
            }
1200
            /* Allow NUMBER -> STRING */
1201 1
            else if (PyTypeNum_ISNUMBER(type_num2)) {
1202 1
                PyArray_Descr *ret = NULL;
1203 1
                PyArray_Descr *temp = PyArray_DescrNew(type1);
1204 1
                PyDataType_MAKEUNSIZED(temp);
1205

1206 1
                temp = PyArray_AdaptFlexibleDType(type2, temp);
1207 1
                if (temp == NULL) {
1208
                    return NULL;
1209
                }
1210 1
                if (temp->elsize > type1->elsize) {
1211
                    ret = ensure_dtype_nbo(temp);
1212
                }
1213
                else {
1214
                    ret = ensure_dtype_nbo(type1);
1215
                }
1216 1
                Py_DECREF(temp);
1217
                return ret;
1218
            }
1219
            break;
1220 1
        case NPY_UNICODE:
1221 1
            if (type_num2 == NPY_UNICODE) {
1222 1
                if (type1->elsize > type2->elsize) {
1223
                    return ensure_dtype_nbo(type1);
1224
                }
1225
                else {
1226
                    return ensure_dtype_nbo(type2);
1227
                }
1228
            }
1229 1
            else if (type_num2 == NPY_STRING) {
1230 1
                if (type1->elsize >= type2->elsize * 4) {
1231
                    return ensure_dtype_nbo(type1);
1232
                }
1233
                else {
1234 1
                    PyArray_Descr *d = PyArray_DescrNewFromType(NPY_UNICODE);
1235 1
                    if (d == NULL) {
1236
                        return NULL;
1237
                    }
1238 1
                    d->elsize = type2->elsize * 4;
1239 1
                    return d;
1240
                }
1241
            }
1242
            /* Allow NUMBER -> UNICODE */
1243 1
            else if (PyTypeNum_ISNUMBER(type_num2)) {
1244 1
                PyArray_Descr *ret = NULL;
1245 1
                PyArray_Descr *temp = PyArray_DescrNew(type1);
1246 1
                PyDataType_MAKEUNSIZED(temp);
1247 1
                temp = PyArray_AdaptFlexibleDType(type2, temp);
1248 1
                if (temp == NULL) {
1249
                    return NULL;
1250
                }
1251 1
                if (temp->elsize > type1->elsize) {
1252
                    ret = ensure_dtype_nbo(temp);
1253
                }
1254
                else {
1255
                    ret = ensure_dtype_nbo(type1);
1256
                }
1257 1
                Py_DECREF(temp);
1258
                return ret;
1259
            }
1260
            break;
1261 1
        case NPY_DATETIME:
1262
        case NPY_TIMEDELTA:
1263 1
            if (type_num2 == NPY_DATETIME || type_num2 == NPY_TIMEDELTA) {
1264 1
                return datetime_type_promotion(type1, type2);
1265
            }
1266
            break;
1267
    }
1268

1269 1
    switch (type_num2) {
1270
        /* BOOL can convert to almost anything */
1271 1
        case NPY_BOOL:
1272 1
            if (type_num2 == NPY_STRING || type_num2 == NPY_UNICODE) {
1273 0
                int char_size = 1;
1274 0
                if (type_num2 == NPY_UNICODE) {
1275 0
                    char_size = 4;
1276
                }
1277 0
                if (type2->elsize < 5 * char_size) {
1278 0
                    PyArray_Descr *ret = NULL;
1279 0
                    PyArray_Descr *temp = PyArray_DescrNew(type2);
1280 0
                    ret = ensure_dtype_nbo(temp);
1281 0
                    ret->elsize = 5 * char_size;
1282 0
                    Py_DECREF(temp);
1283
                    return ret;
1284
                }
1285
                return ensure_dtype_nbo(type2);
1286
            }
1287 1
            else if (type_num1 != NPY_DATETIME && type_num1 != NPY_TIMEDELTA &&
1288
                                    type_num1 != NPY_VOID) {
1289
                return ensure_dtype_nbo(type1);
1290
            }
1291
            break;
1292 1
        case NPY_STRING:
1293
            /* Allow NUMBER -> STRING */
1294 1
            if (PyTypeNum_ISNUMBER(type_num1)) {
1295 1
                PyArray_Descr *ret = NULL;
1296 1
                PyArray_Descr *temp = PyArray_DescrNew(type2);
1297 1
                PyDataType_MAKEUNSIZED(temp);
1298 1
                temp = PyArray_AdaptFlexibleDType(type1, temp);
1299 1
                if (temp == NULL) {
1300
                    return NULL;
1301
                }
1302 1
                if (temp->elsize > type2->elsize) {
1303
                    ret = ensure_dtype_nbo(temp);
1304
                }
1305
                else {
1306
                    ret = ensure_dtype_nbo(type2);
1307
                }
1308 1
                Py_DECREF(temp);
1309
                return ret;
1310
            }
1311
            break;
1312 1
        case NPY_UNICODE:
1313
            /* Allow NUMBER -> UNICODE */
1314 1
            if (PyTypeNum_ISNUMBER(type_num1)) {
1315 1
                PyArray_Descr *ret = NULL;
1316 1
                PyArray_Descr *temp = PyArray_DescrNew(type2);
1317 1
                PyDataType_MAKEUNSIZED(temp);
1318 1
                temp = PyArray_AdaptFlexibleDType(type1, temp);
1319 1
                if (temp == NULL) {
1320
                    return NULL;
1321
                }
1322 1
                if (temp->elsize > type2->elsize) {
1323
                    ret = ensure_dtype_nbo(temp);
1324
                }
1325
                else {
1326
                    ret = ensure_dtype_nbo(type2);
1327
                }
1328 1
                Py_DECREF(temp);
1329
                return ret;
1330
            }
1331
            break;
1332 1
        case NPY_TIMEDELTA:
1333 1
            if (PyTypeNum_ISSIGNED(type_num1)) {
1334
                return ensure_dtype_nbo(type2);
1335
            }
1336
            break;
1337
    }
1338

1339
    /* For types equivalent up to endianness, can return either */
1340 1
    if (PyArray_CanCastTypeTo(type1, type2, NPY_EQUIV_CASTING)) {
1341
        return ensure_dtype_nbo(type1);
1342
    }
1343

1344
    /* TODO: Also combine fields, subarrays, strings, etc */
1345

1346
    /*
1347
    printf("invalid type promotion: ");
1348
    PyObject_Print(type1, stdout, 0);
1349
    printf(" ");
1350
    PyObject_Print(type2, stdout, 0);
1351
    printf("\n");
1352
    */
1353 1
    PyErr_SetString(PyExc_TypeError, "invalid type promotion");
1354 1
    return NULL;
1355
}
1356

1357
/*
1358
 * Produces the smallest size and lowest kind type to which all
1359
 * input types can be cast.
1360
 *
1361
 * Equivalent to functools.reduce(PyArray_PromoteTypes, types)
1362
 */
1363
NPY_NO_EXPORT PyArray_Descr *
1364 1
PyArray_PromoteTypeSequence(PyArray_Descr **types, npy_intp ntypes)
1365
{
1366
    npy_intp i;
1367 1
    PyArray_Descr *ret = NULL;
1368 1
    if (ntypes == 0) {
1369 1
        PyErr_SetString(PyExc_TypeError, "at least one type needed to promote");
1370 1
        return NULL;
1371
    }
1372 1
    ret = types[0];
1373 1
    Py_INCREF(ret);
1374 1
    for (i = 1; i < ntypes; ++i) {
1375 1
        PyArray_Descr *tmp = PyArray_PromoteTypes(types[i], ret);
1376 1
        Py_DECREF(ret);
1377 1
        ret = tmp;
1378 1
        if (ret == NULL) {
1379
            return NULL;
1380
        }
1381
    }
1382
    return ret;
1383
}
1384

1385
/*
1386
 * NOTE: While this is unlikely to be a performance problem, if
1387
 *       it is it could be reverted to a simple positive/negative
1388
 *       check as the previous system used.
1389
 *
1390
 * The is_small_unsigned output flag indicates whether it's an unsigned integer,
1391
 * and would fit in a signed integer of the same bit size.
1392
 */
1393 1
static int min_scalar_type_num(char *valueptr, int type_num,
1394
                                            int *is_small_unsigned)
1395
{
1396 1
    switch (type_num) {
1397
        case NPY_BOOL: {
1398
            return NPY_BOOL;
1399
        }
1400 1
        case NPY_UBYTE: {
1401 1
            npy_ubyte value = *(npy_ubyte *)valueptr;
1402 1
            if (value <= NPY_MAX_BYTE) {
1403 1
                *is_small_unsigned = 1;
1404
            }
1405
            return NPY_UBYTE;
1406
        }
1407 1
        case NPY_BYTE: {
1408 1
            npy_byte value = *(npy_byte *)valueptr;
1409 1
            if (value >= 0) {
1410 1
                *is_small_unsigned = 1;
1411 1
                return NPY_UBYTE;
1412
            }
1413
            break;
1414
        }
1415 1
        case NPY_USHORT: {
1416 1
            npy_ushort value = *(npy_ushort *)valueptr;
1417 1
            if (value <= NPY_MAX_UBYTE) {
1418 1
                if (value <= NPY_MAX_BYTE) {
1419 1
                    *is_small_unsigned = 1;
1420
                }
1421
                return NPY_UBYTE;
1422
            }
1423

1424 1
            if (value <= NPY_MAX_SHORT) {
1425 1
                *is_small_unsigned = 1;
1426
            }
1427
            break;
1428
        }
1429 1
        case NPY_SHORT: {
1430 1
            npy_short value = *(npy_short *)valueptr;
1431 1
            if (value >= 0) {
1432
                return min_scalar_type_num(valueptr, NPY_USHORT, is_small_unsigned);
1433
            }
1434 1
            else if (value >= NPY_MIN_BYTE) {
1435
                return NPY_BYTE;
1436
            }
1437
            break;
1438
        }
1439
#if NPY_SIZEOF_LONG == NPY_SIZEOF_INT
1440
        case NPY_ULONG:
1441
#endif
1442 1
        case NPY_UINT: {
1443 1
            npy_uint value = *(npy_uint *)valueptr;
1444 1
            if (value <= NPY_MAX_UBYTE) {
1445 1
                if (value <= NPY_MAX_BYTE) {
1446 1
                    *is_small_unsigned = 1;
1447
                }
1448
                return NPY_UBYTE;
1449
            }
1450 1
            else if (value <= NPY_MAX_USHORT) {
1451 1
                if (value <= NPY_MAX_SHORT) {
1452 1
                    *is_small_unsigned = 1;
1453
                }
1454
                return NPY_USHORT;
1455
            }
1456

1457 1
            if (value <= NPY_MAX_INT) {
1458 1
                *is_small_unsigned = 1;
1459
            }
1460
            break;
1461
        }
1462
#if NPY_SIZEOF_LONG == NPY_SIZEOF_INT
1463
        case NPY_LONG:
1464
#endif
1465 1
        case NPY_INT: {
1466 1
            npy_int value = *(npy_int *)valueptr;
1467 1
            if (value >= 0) {
1468
                return min_scalar_type_num(valueptr, NPY_UINT, is_small_unsigned);
1469
            }
1470 1
            else if (value >= NPY_MIN_BYTE) {
1471
                return NPY_BYTE;
1472
            }
1473 1
            else if (value >= NPY_MIN_SHORT) {
1474
                return NPY_SHORT;
1475
            }
1476
            break;
1477
        }
1478
#if NPY_SIZEOF_LONG != NPY_SIZEOF_INT && NPY_SIZEOF_LONG != NPY_SIZEOF_LONGLONG
1479
        case NPY_ULONG: {
1480
            npy_ulong value = *(npy_ulong *)valueptr;
1481
            if (value <= NPY_MAX_UBYTE) {
1482
                if (value <= NPY_MAX_BYTE) {
1483
                    *is_small_unsigned = 1;
1484
                }
1485
                return NPY_UBYTE;
1486
            }
1487
            else if (value <= NPY_MAX_USHORT) {
1488
                if (value <= NPY_MAX_SHORT) {
1489
                    *is_small_unsigned = 1;
1490
                }
1491
                return NPY_USHORT;
1492
            }
1493
            else if (value <= NPY_MAX_UINT) {
1494
                if (value <= NPY_MAX_INT) {
1495
                    *is_small_unsigned = 1;
1496
                }
1497
                return NPY_UINT;
1498
            }
1499

1500
            if (value <= NPY_MAX_LONG) {
1501
                *is_small_unsigned = 1;
1502
            }
1503
            break;
1504
        }
1505
        case NPY_LONG: {
1506
            npy_long value = *(npy_long *)valueptr;
1507
            if (value >= 0) {
1508
                return min_scalar_type_num(valueptr, NPY_ULONG, is_small_unsigned);
1509
            }
1510
            else if (value >= NPY_MIN_BYTE) {
1511
                return NPY_BYTE;
1512
            }
1513
            else if (value >= NPY_MIN_SHORT) {
1514
                return NPY_SHORT;
1515
            }
1516
            else if (value >= NPY_MIN_INT) {
1517
                return NPY_INT;
1518
            }
1519
            break;
1520
        }
1521
#endif
1522
#if NPY_SIZEOF_LONG == NPY_SIZEOF_LONGLONG
1523 1
        case NPY_ULONG:
1524
#endif
1525
        case NPY_ULONGLONG: {
1526 1
            npy_ulonglong value = *(npy_ulonglong *)valueptr;
1527 1
            if (value <= NPY_MAX_UBYTE) {
1528 1
                if (value <= NPY_MAX_BYTE) {
1529 1
                    *is_small_unsigned = 1;
1530
                }
1531
                return NPY_UBYTE;
1532
            }
1533 1
            else if (value <= NPY_MAX_USHORT) {
1534 1
                if (value <= NPY_MAX_SHORT) {
1535 1
                    *is_small_unsigned = 1;
1536
                }
1537
                return NPY_USHORT;
1538
            }
1539 1
            else if (value <= NPY_MAX_UINT) {
1540 1
                if (value <= NPY_MAX_INT) {
1541 1
                    *is_small_unsigned = 1;
1542
                }
1543
                return NPY_UINT;
1544
            }
1545
#if NPY_SIZEOF_LONG != NPY_SIZEOF_INT && NPY_SIZEOF_LONG != NPY_SIZEOF_LONGLONG
1546
            else if (value <= NPY_MAX_ULONG) {
1547
                if (value <= NPY_MAX_LONG) {
1548
                    *is_small_unsigned = 1;
1549
                }
1550
                return NPY_ULONG;
1551
            }
1552
#endif
1553

1554 1
            if (value <= NPY_MAX_LONGLONG) {
1555 1
                *is_small_unsigned = 1;
1556
            }
1557
            break;
1558
        }
1559
#if NPY_SIZEOF_LONG == NPY_SIZEOF_LONGLONG
1560 1
        case NPY_LONG:
1561
#endif
1562
        case NPY_LONGLONG: {
1563 1
            npy_longlong value = *(npy_longlong *)valueptr;
1564 1
            if (value >= 0) {
1565
                return min_scalar_type_num(valueptr, NPY_ULONGLONG, is_small_unsigned);
1566
            }
1567 1
            else if (value >= NPY_MIN_BYTE) {
1568
                return NPY_BYTE;
1569
            }
1570 1
            else if (value >= NPY_MIN_SHORT) {
1571
                return NPY_SHORT;
1572
            }
1573 1
            else if (value >= NPY_MIN_INT) {
1574
                return NPY_INT;
1575
            }
1576
#if NPY_SIZEOF_LONG != NPY_SIZEOF_INT && NPY_SIZEOF_LONG != NPY_SIZEOF_LONGLONG
1577
            else if (value >= NPY_MIN_LONG) {
1578
                return NPY_LONG;
1579
            }
1580
#endif
1581
            break;
1582
        }
1583
        /*
1584
         * Float types aren't allowed to be demoted to integer types,
1585
         * but precision loss is allowed.
1586
         */
1587 1
        case NPY_HALF: {
1588 1
            return NPY_HALF;
1589
        }
1590 1
        case NPY_FLOAT: {
1591 1
            float value = *(float *)valueptr;
1592 1
            if ((value > -65000 && value < 65000) || !npy_isfinite(value)) {
1593
                return NPY_HALF;
1594
            }
1595
            break;
1596
        }
1597 1
        case NPY_DOUBLE: {
1598 1
            double value = *(double *)valueptr;
1599 1
            if ((value > -65000 && value < 65000) || !npy_isfinite(value)) {
1600
                return NPY_HALF;
1601
            }
1602 1
            else if (value > -3.4e38 && value < 3.4e38) {
1603
                return NPY_FLOAT;
1604
            }
1605
            break;
1606
        }
1607 1
        case NPY_LONGDOUBLE: {
1608 1
            npy_longdouble value = *(npy_longdouble *)valueptr;
1609 1
            if ((value > -65000 && value < 65000) || !npy_isfinite(value)) {
1610
                return NPY_HALF;
1611
            }
1612 0
            else if (value > -3.4e38 && value < 3.4e38) {
1613
                return NPY_FLOAT;
1614
            }
1615 0
            else if (value > -1.7e308 && value < 1.7e308) {
1616
                return NPY_DOUBLE;
1617
            }
1618
            break;
1619
        }
1620
        /*
1621
         * The code to demote complex to float is disabled for now,
1622
         * as forcing complex by adding 0j is probably desirable.
1623
         */
1624
        case NPY_CFLOAT: {
1625
            /*
1626
            npy_cfloat value = *(npy_cfloat *)valueptr;
1627
            if (value.imag == 0) {
1628
                return min_scalar_type_num((char *)&value.real,
1629
                                            NPY_FLOAT, is_small_unsigned);
1630
            }
1631
            */
1632
            break;
1633
        }
1634 1
        case NPY_CDOUBLE: {
1635 1
            npy_cdouble value = *(npy_cdouble *)valueptr;
1636
            /*
1637
            if (value.imag == 0) {
1638
                return min_scalar_type_num((char *)&value.real,
1639
                                            NPY_DOUBLE, is_small_unsigned);
1640
            }
1641
            */
1642 1
            if (value.real > -3.4e38 && value.real < 3.4e38 &&
1643 1
                     value.imag > -3.4e38 && value.imag < 3.4e38) {
1644
                return NPY_CFLOAT;
1645
            }
1646
            break;
1647
        }
1648 1
        case NPY_CLONGDOUBLE: {
1649 1
            npy_clongdouble value = *(npy_clongdouble *)valueptr;
1650
            /*
1651
            if (value.imag == 0) {
1652
                return min_scalar_type_num((char *)&value.real,
1653
                                            NPY_LONGDOUBLE, is_small_unsigned);
1654
            }
1655
            */
1656 1
            if (value.real > -3.4e38 && value.real < 3.4e38 &&
1657 1
                     value.imag > -3.4e38 && value.imag < 3.4e38) {
1658
                return NPY_CFLOAT;
1659
            }
1660 0
            else if (value.real > -1.7e308 && value.real < 1.7e308 &&
1661 0
                     value.imag > -1.7e308 && value.imag < 1.7e308) {
1662
                return NPY_CDOUBLE;
1663
            }
1664
            break;
1665
        }
1666
    }
1667

1668
    return type_num;
1669
}
1670

1671

1672
NPY_NO_EXPORT PyArray_Descr *
1673 1
PyArray_MinScalarType_internal(PyArrayObject *arr, int *is_small_unsigned)
1674
{
1675 1
    PyArray_Descr *dtype = PyArray_DESCR(arr);
1676 1
    *is_small_unsigned = 0;
1677
    /*
1678
     * If the array isn't a numeric scalar, just return the array's dtype.
1679
     */
1680 1
    if (PyArray_NDIM(arr) > 0 || !PyTypeNum_ISNUMBER(dtype->type_num)) {
1681 1
        Py_INCREF(dtype);
1682 1
        return dtype;
1683
    }
1684
    else {
1685 1
        char *data = PyArray_BYTES(arr);
1686 1
        int swap = !PyArray_ISNBO(dtype->byteorder);
1687
        /* An aligned memory buffer large enough to hold any type */
1688
        npy_longlong value[4];
1689 1
        dtype->f->copyswap(&value, data, swap, NULL);
1690

1691 1
        return PyArray_DescrFromType(
1692
                        min_scalar_type_num((char *)&value,
1693
                                dtype->type_num, is_small_unsigned));
1694

1695
    }
1696
}
1697

1698
/*NUMPY_API
1699
 * If arr is a scalar (has 0 dimensions) with a built-in number data type,
1700
 * finds the smallest type size/kind which can still represent its data.
1701
 * Otherwise, returns the array's data type.
1702
 *
1703
 */
1704
NPY_NO_EXPORT PyArray_Descr *
1705 1
PyArray_MinScalarType(PyArrayObject *arr)
1706
{
1707
    int is_small_unsigned;
1708 1
    return PyArray_MinScalarType_internal(arr, &is_small_unsigned);
1709
}
1710

1711
/*
1712
 * Provides an ordering for the dtype 'kind' character codes, to help
1713
 * determine when to use the min_scalar_type function. This groups
1714
 * 'kind' into boolean, integer, floating point, and everything else.
1715
 */
1716
static int
1717
dtype_kind_to_simplified_ordering(char kind)
1718
{
1719 1
    switch (kind) {
1720
        /* Boolean kind */
1721
        case 'b':
1722
            return 0;
1723
        /* Unsigned int kind */
1724
        case 'u':
1725
        /* Signed int kind */
1726
        case 'i':
1727
            return 1;
1728
        /* Float kind */
1729
        case 'f':
1730
        /* Complex kind */
1731
        case 'c':
1732
            return 2;
1733
        /* Anything else */
1734
        default:
1735
            return 3;
1736
    }
1737
}
1738

1739

1740
/*
1741
 * Determine if there is a mix of scalars and arrays/dtypes.
1742
 * If this is the case, the scalars should be handled as the minimum type
1743
 * capable of holding the value when the maximum "category" of the scalars
1744
 * surpasses the maximum "category" of the arrays/dtypes.
1745
 * If the scalars are of a lower or same category as the arrays, they may be
1746
 * demoted to a lower type within their category (the lowest type they can
1747
 * be cast to safely according to scalar casting rules).
1748
 */
1749
NPY_NO_EXPORT int
1750 1
should_use_min_scalar(npy_intp narrs, PyArrayObject **arr,
1751
                      npy_intp ndtypes, PyArray_Descr **dtypes)
1752
{
1753 1
    int use_min_scalar = 0;
1754

1755 1
    if (narrs > 0) {
1756
        int all_scalars;
1757 1
        int max_scalar_kind = -1;
1758 1
        int max_array_kind = -1;
1759

1760 1
        all_scalars = (ndtypes > 0) ? 0 : 1;
1761

1762
        /* Compute the maximum "kinds" and whether everything is scalar */
1763 1
        for (npy_intp i = 0; i < narrs; ++i) {
1764 1
            if (PyArray_NDIM(arr[i]) == 0) {
1765 1
                int kind = dtype_kind_to_simplified_ordering(
1766 1
                                    PyArray_DESCR(arr[i])->kind);
1767 1
                if (kind > max_scalar_kind) {
1768 1
                    max_scalar_kind = kind;
1769
                }
1770
            }
1771
            else {
1772 1
                int kind = dtype_kind_to_simplified_ordering(
1773 1
                                    PyArray_DESCR(arr[i])->kind);
1774 1
                if (kind > max_array_kind) {
1775 1
                    max_array_kind = kind;
1776
                }
1777
                all_scalars = 0;
1778
            }
1779
        }
1780
        /*
1781
         * If the max scalar kind is bigger than the max array kind,
1782
         * finish computing the max array kind
1783
         */
1784 1
        for (npy_intp i = 0; i < ndtypes; ++i) {
1785 1
            int kind = dtype_kind_to_simplified_ordering(dtypes[i]->kind);
1786 1
            if (kind > max_array_kind) {
1787 1
                max_array_kind = kind;
1788
            }
1789
        }
1790

1791
        /* Indicate whether to use the min_scalar_type function */
1792 1
        if (!all_scalars && max_array_kind >= max_scalar_kind) {
1793 1
            use_min_scalar = 1;
1794
        }
1795
    }
1796 1
    return use_min_scalar;
1797
}
1798

1799

1800
/*NUMPY_API
1801
 * Produces the result type of a bunch of inputs, using the UFunc
1802
 * type promotion rules. Use this function when you have a set of
1803
 * input arrays, and need to determine an output array dtype.
1804
 *
1805
 * If all the inputs are scalars (have 0 dimensions) or the maximum "kind"
1806
 * of the scalars is greater than the maximum "kind" of the arrays, does
1807
 * a regular type promotion.
1808
 *
1809
 * Otherwise, does a type promotion on the MinScalarType
1810
 * of all the inputs.  Data types passed directly are treated as array
1811
 * types.
1812
 *
1813
 */
1814
NPY_NO_EXPORT PyArray_Descr *
1815 1
PyArray_ResultType(npy_intp narrs, PyArrayObject **arr,
1816
                    npy_intp ndtypes, PyArray_Descr **dtypes)
1817
{
1818
    npy_intp i;
1819

1820
    /* If there's just one type, pass it through */
1821 1
    if (narrs + ndtypes == 1) {
1822 1
        PyArray_Descr *ret = NULL;
1823 1
        if (narrs == 1) {
1824 1
            ret = PyArray_DESCR(arr[0]);
1825
        }
1826
        else {
1827 1
            ret = dtypes[0];
1828
        }
1829 1
        Py_INCREF(ret);
1830 1
        return ret;
1831
    }
1832

1833 1
    int use_min_scalar = should_use_min_scalar(narrs, arr, ndtypes, dtypes);
1834

1835
    /* Loop through all the types, promoting them */
1836 1
    if (!use_min_scalar) {
1837
        PyArray_Descr *ret;
1838

1839
        /* Build a single array of all the dtypes */
1840 1
        PyArray_Descr **all_dtypes = PyArray_malloc(
1841 1
            sizeof(*all_dtypes) * (narrs + ndtypes));
1842 1
        if (all_dtypes == NULL) {
1843 0
            PyErr_NoMemory();
1844 0
            return NULL;
1845
        }
1846 1
        for (i = 0; i < narrs; ++i) {
1847 1
            all_dtypes[i] = PyArray_DESCR(arr[i]);
1848
        }
1849 1
        for (i = 0; i < ndtypes; ++i) {
1850 1
            all_dtypes[narrs + i] = dtypes[i];
1851
        }
1852 1
        ret = PyArray_PromoteTypeSequence(all_dtypes, narrs + ndtypes);
1853 1
        PyArray_free(all_dtypes);
1854 1
        return ret;
1855
    }
1856
    else {
1857
        int ret_is_small_unsigned = 0;
1858
        PyArray_Descr *ret = NULL;
1859

1860 1
        for (i = 0; i < narrs; ++i) {
1861
            int tmp_is_small_unsigned;
1862 1
            PyArray_Descr *tmp = PyArray_MinScalarType_internal(
1863 1
                arr[i], &tmp_is_small_unsigned);
1864 1
            if (tmp == NULL) {
1865 0
                Py_XDECREF(ret);
1866 1
                return NULL;
1867
            }
1868
            /* Combine it with the existing type */
1869 1
            if (ret == NULL) {
1870 1
                ret = tmp;
1871 1
                ret_is_small_unsigned = tmp_is_small_unsigned;
1872
            }
1873
            else {
1874 1
                PyArray_Descr *tmpret = promote_types(
1875
                    tmp, ret, tmp_is_small_unsigned, ret_is_small_unsigned);
1876 1
                Py_DECREF(tmp);
1877 1
                Py_DECREF(ret);
1878 1
                ret = tmpret;
1879 1
                if (ret == NULL) {
1880
                    return NULL;
1881
                }
1882

1883 1
                ret_is_small_unsigned = tmp_is_small_unsigned &&
1884
                                        ret_is_small_unsigned;
1885
            }
1886
        }
1887

1888 1
        for (i = 0; i < ndtypes; ++i) {
1889 1
            PyArray_Descr *tmp = dtypes[i];
1890
            /* Combine it with the existing type */
1891 1
            if (ret == NULL) {
1892 0
                ret = tmp;
1893 0
                Py_INCREF(ret);
1894
            }
1895
            else {
1896 1
                PyArray_Descr *tmpret = promote_types(
1897
                    tmp, ret, 0, ret_is_small_unsigned);
1898 1
                Py_DECREF(ret);
1899 1
                ret = tmpret;
1900 1
                if (ret == NULL) {
1901
                    return NULL;
1902
                }
1903
            }
1904
        }
1905
        /* None of the above loops ran */
1906 1
        if (ret == NULL) {
1907 0
            PyErr_SetString(PyExc_TypeError,
1908
                    "no arrays or types available to calculate result type");
1909
        }
1910

1911
        return ret;
1912
    }
1913
}
1914

1915
/*NUMPY_API
1916
 * Is the typenum valid?
1917
 */
1918
NPY_NO_EXPORT int
1919 0
PyArray_ValidType(int type)
1920
{
1921
    PyArray_Descr *descr;
1922 0
    int res=NPY_TRUE;
1923

1924 0
    descr = PyArray_DescrFromType(type);
1925 0
    if (descr == NULL) {
1926 0
        res = NPY_FALSE;
1927
    }
1928 0
    Py_DECREF(descr);
1929 0
    return res;
1930
}
1931

1932
/* Backward compatibility only */
1933
/* In both Zero and One
1934

1935
***You must free the memory once you are done with it
1936
using PyDataMem_FREE(ptr) or you create a memory leak***
1937

1938
If arr is an Object array you are getting a
1939
BORROWED reference to Zero or One.
1940
Do not DECREF.
1941
Please INCREF if you will be hanging on to it.
1942

1943
The memory for the ptr still must be freed in any case;
1944
*/
1945

1946
static int
1947
_check_object_rec(PyArray_Descr *descr)
1948
{
1949 1
    if (PyDataType_HASFIELDS(descr) && PyDataType_REFCHK(descr)) {
1950 0
        PyErr_SetString(PyExc_TypeError, "Not supported for this data-type.");
1951
        return -1;
1952
    }
1953
    return 0;
1954
}
1955

1956
/*NUMPY_API
1957
  Get pointer to zero of correct type for array.
1958
*/
1959
NPY_NO_EXPORT char *
1960 1
PyArray_Zero(PyArrayObject *arr)
1961
{
1962
    char *zeroval;
1963
    int ret, storeflags;
1964
    static PyObject * zero_obj = NULL;
1965

1966 1
    if (_check_object_rec(PyArray_DESCR(arr)) < 0) {
1967
        return NULL;
1968
    }
1969 1
    zeroval = PyDataMem_NEW(PyArray_DESCR(arr)->elsize);
1970 1
    if (zeroval == NULL) {
1971 0
        PyErr_SetNone(PyExc_MemoryError);
1972 0
        return NULL;
1973
    }
1974

1975 1
    if (zero_obj == NULL) {
1976 1
        zero_obj = PyLong_FromLong((long) 0);
1977 1
        if (zero_obj == NULL) {
1978
            return NULL;
1979
        }
1980
    }
1981 1
    if (PyArray_ISOBJECT(arr)) {
1982
        /* XXX this is dangerous, the caller probably is not
1983
           aware that zeroval is actually a static PyObject*
1984
           In the best case they will only use it as-is, but
1985
           if they simply memcpy it into a ndarray without using
1986
           setitem(), refcount errors will occur
1987
        */
1988 1
        memcpy(zeroval, &zero_obj, sizeof(PyObject *));
1989 1
        return zeroval;
1990
    }
1991 1
    storeflags = PyArray_FLAGS(arr);
1992 1
    PyArray_ENABLEFLAGS(arr, NPY_ARRAY_BEHAVED);
1993 1
    ret = PyArray_SETITEM(arr, zeroval, zero_obj);
1994 1
    ((PyArrayObject_fields *)arr)->flags = storeflags;
1995 1
    if (ret < 0) {
1996 0
        PyDataMem_FREE(zeroval);
1997 0
        return NULL;
1998
    }
1999
    return zeroval;
2000
}
2001

2002
/*NUMPY_API
2003
  Get pointer to one of correct type for array
2004
*/
2005
NPY_NO_EXPORT char *
2006 1
PyArray_One(PyArrayObject *arr)
2007
{
2008
    char *oneval;
2009
    int ret, storeflags;
2010
    static PyObject * one_obj = NULL;
2011

2012 1
    if (_check_object_rec(PyArray_DESCR(arr)) < 0) {
2013
        return NULL;
2014
    }
2015 1
    oneval = PyDataMem_NEW(PyArray_DESCR(arr)->elsize);
2016 1
    if (oneval == NULL) {
2017 0
        PyErr_SetNone(PyExc_MemoryError);
2018 0
        return NULL;
2019
    }
2020

2021 1
    if (one_obj == NULL) {
2022 1
        one_obj = PyLong_FromLong((long) 1);
2023 1
        if (one_obj == NULL) {
2024
            return NULL;
2025
        }
2026
    }
2027 1
    if (PyArray_ISOBJECT(arr)) {
2028
        /* XXX this is dangerous, the caller probably is not
2029
           aware that oneval is actually a static PyObject*
2030
           In the best case they will only use it as-is, but
2031
           if they simply memcpy it into a ndarray without using
2032
           setitem(), refcount errors will occur
2033
        */
2034 1
        memcpy(oneval, &one_obj, sizeof(PyObject *));
2035 1
        return oneval;
2036
    }
2037

2038 1
    storeflags = PyArray_FLAGS(arr);
2039 1
    PyArray_ENABLEFLAGS(arr, NPY_ARRAY_BEHAVED);
2040 1
    ret = PyArray_SETITEM(arr, oneval, one_obj);
2041 1
    ((PyArrayObject_fields *)arr)->flags = storeflags;
2042 1
    if (ret < 0) {
2043 0
        PyDataMem_FREE(oneval);
2044 0
        return NULL;
2045
    }
2046
    return oneval;
2047
}
2048

2049
/* End deprecated */
2050

2051
/*NUMPY_API
2052
 * Return the typecode of the array a Python object would be converted to
2053
 *
2054
 * Returns the type number the result should have, or NPY_NOTYPE on error.
2055
 */
2056
NPY_NO_EXPORT int
2057 1
PyArray_ObjectType(PyObject *op, int minimum_type)
2058
{
2059 1
    PyArray_Descr *dtype = NULL;
2060
    int ret;
2061

2062 1
    if (minimum_type != NPY_NOTYPE && minimum_type >= 0) {
2063 1
        dtype = PyArray_DescrFromType(minimum_type);
2064 1
        if (dtype == NULL) {
2065
            return NPY_NOTYPE;
2066
        }
2067
    }
2068 1
    if (PyArray_DTypeFromObject(op, NPY_MAXDIMS, &dtype) < 0) {
2069
        return NPY_NOTYPE;
2070
    }
2071

2072 1
    if (dtype == NULL) {
2073
        ret = NPY_DEFAULT_TYPE;
2074
    }
2075 1
    else if (!NPY_DTYPE(dtype)->legacy) {
2076
        /*
2077
         * TODO: If we keep all type number style API working, by defining
2078
         *       type numbers always. We may be able to allow this again.
2079
         */
2080 0
        PyErr_Format(PyExc_TypeError,
2081
                "This function currently only supports native NumPy dtypes "
2082
                "and old-style user dtypes, but the dtype was %S.\n"
2083
                "(The function may need to be updated to support arbitrary"
2084
                "user dtypes.)",
2085
                dtype);
2086 0
        ret = NPY_NOTYPE;
2087
    }
2088
    else {
2089 1
        ret = dtype->type_num;
2090
    }
2091

2092 1
    Py_XDECREF(dtype);
2093

2094
    return ret;
2095
}
2096

2097
/* Raises error when len(op) == 0 */
2098

2099
/*NUMPY_API
2100
 *
2101
 * This function is only used in one place within NumPy and should
2102
 * generally be avoided. It is provided mainly for backward compatibility.
2103
 *
2104
 * The user of the function has to free the returned array.
2105
 */
2106
NPY_NO_EXPORT PyArrayObject **
2107 1
PyArray_ConvertToCommonType(PyObject *op, int *retn)
2108
{
2109
    int i, n;
2110 1
    PyArray_Descr *common_descr = NULL;
2111 1
    PyArrayObject **mps = NULL;
2112

2113 1
    *retn = n = PySequence_Length(op);
2114 1
    if (n == 0) {
2115 1
        PyErr_SetString(PyExc_ValueError, "0-length sequence.");
2116
    }
2117 1
    if (PyErr_Occurred()) {
2118 1
        *retn = 0;
2119 1
        return NULL;
2120
    }
2121 1
    mps = (PyArrayObject **)PyDataMem_NEW(n*sizeof(PyArrayObject *));
2122 1
    if (mps == NULL) {
2123 0
        *retn = 0;
2124 0
        return (void*)PyErr_NoMemory();
2125
    }
2126

2127 1
    if (PyArray_Check(op)) {
2128 0
        for (i = 0; i < n; i++) {
2129 0
            mps[i] = (PyArrayObject *) array_item_asarray((PyArrayObject *)op, i);
2130
        }
2131 0
        if (!PyArray_ISCARRAY((PyArrayObject *)op)) {
2132 0
            for (i = 0; i < n; i++) {
2133
                PyObject *obj;
2134 0
                obj = PyArray_NewCopy(mps[i], NPY_CORDER);
2135 0
                Py_DECREF(mps[i]);
2136 0
                mps[i] = (PyArrayObject *)obj;
2137
            }
2138
        }
2139
        return mps;
2140
    }
2141

2142 1
    for (i = 0; i < n; i++) {
2143 1
        mps[i] = NULL;
2144
    }
2145

2146 1
    for (i = 0; i < n; i++) {
2147
        /* Convert everything to an array, this could be optimized away */
2148 1
        PyObject *tmp = PySequence_GetItem(op, i);
2149 1
        if (tmp == NULL) {
2150
            goto fail;
2151
        }
2152

2153 1
        mps[i] = (PyArrayObject *)PyArray_FROM_O(tmp);
2154 1
        Py_DECREF(tmp);
2155 1
        if (mps[i] == NULL) {
2156
            goto fail;
2157
        }
2158
    }
2159

2160 1
    common_descr = PyArray_ResultType(n, mps, 0, NULL);
2161 1
    if (common_descr == NULL) {
2162
        goto fail;
2163
    }
2164

2165
    /* Make sure all arrays are contiguous and have the correct dtype. */
2166 1
    for (i = 0; i < n; i++) {
2167 1
        int flags = NPY_ARRAY_CARRAY;
2168 1
        PyArrayObject *tmp = mps[i];
2169

2170 1
        Py_INCREF(common_descr);
2171 1
        mps[i] = (PyArrayObject *)PyArray_FromArray(tmp, common_descr, flags);
2172 1
        Py_DECREF(tmp);
2173 1
        if (mps[i] == NULL) {
2174
            goto fail;
2175
        }
2176
    }
2177 1
    Py_DECREF(common_descr);
2178
    return mps;
2179

2180 1
 fail:
2181 1
    Py_XDECREF(common_descr);
2182 1
    *retn = 0;
2183 1
    for (i = 0; i < n; i++) {
2184 1
        Py_XDECREF(mps[i]);
2185
    }
2186 1
    PyDataMem_FREE(mps);
2187 1
    return NULL;
2188
}

Read our documentation on viewing source code .

Loading