1
/* -*-c-*- */
2
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
3
#include <Python.h>
4
#define _NPY_NO_DEPRECATIONS /* for NPY_CHAR */
5
#include "numpy/arrayobject.h"
6
#include "numpy/arrayscalars.h"
7
#include "numpy/npy_math.h"
8
#include "numpy/halffloat.h"
9
#include "common.h"
10
#include "mem_overlap.h"
11
#include "npy_extint128.h"
12

13
#if defined(MS_WIN32) || defined(__CYGWIN__)
14
#define EXPORT(x) __declspec(dllexport) x
15
#else
16
#define EXPORT(x) x
17
#endif
18

19
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
20

21
/* test PyArray_IsPythonScalar, before including private py3 compat header */
22
static PyObject *
23 1
IsPythonScalar(PyObject * dummy, PyObject *args)
24
{
25 1
    PyObject *arg = NULL;
26 1
    if (!PyArg_ParseTuple(args, "O", &arg)) {
27
        return NULL;
28
    }
29 1
    if (PyArray_IsPythonScalar(arg)) {
30 1
        Py_RETURN_TRUE;
31
    }
32
    else {
33 0
        Py_RETURN_FALSE;
34
    }
35
}
36

37
#include "npy_pycompat.h"
38

39
/** Function to test calling via ctypes */
40 1
EXPORT(void*) forward_pointer(void *x)
41
{
42 1
    return x;
43
}
44

45
/*
46
 * TODO:
47
 *  - Handle mode
48
 */
49

50
/**begin repeat
51
 * #name = double, int#
52
 * #type = npy_double, npy_int#
53
 * #typenum = NPY_DOUBLE, NPY_INT#
54
 */
55 1
static int copy_@name@(PyArrayIterObject *itx, PyArrayNeighborhoodIterObject *niterx,
56
        npy_intp const *bounds,
57
        PyObject **out)
58
{
59
    npy_intp i, j;
60
    @type@ *ptr;
61
    npy_intp odims[NPY_MAXDIMS];
62
    PyArrayObject *aout;
63

64
    /*
65
     * For each point in itx, copy the current neighborhood into an array which
66
     * is appended at the output list
67
     */
68 1
    for (i = 0; i < itx->size; ++i) {
69 1
        PyArrayNeighborhoodIter_Reset(niterx);
70

71 1
        for (j = 0; j < PyArray_NDIM(itx->ao); ++j) {
72 1
            odims[j] = bounds[2 * j + 1] - bounds[2 * j] + 1;
73
        }
74 1
        aout = (PyArrayObject*)PyArray_SimpleNew(
75
                                PyArray_NDIM(itx->ao), odims, @typenum@);
76 1
        if (aout == NULL) {
77
            return -1;
78
        }
79

80 1
        ptr = (@type@*)PyArray_DATA(aout);
81

82 1
        for (j = 0; j < niterx->size; ++j) {
83 1
            *ptr = *((@type@*)niterx->dataptr);
84 1
            PyArrayNeighborhoodIter_Next(niterx);
85 1
            ptr += 1;
86
        }
87

88 1
        PyList_Append(*out, (PyObject*)aout);
89 1
        Py_DECREF(aout);
90 1
        PyArray_ITER_NEXT(itx);
91
    }
92

93
    return 0;
94
}
95
/**end repeat**/
96

97 1
static int copy_object(PyArrayIterObject *itx, PyArrayNeighborhoodIterObject *niterx,
98
        npy_intp const *bounds,
99
        PyObject **out)
100
{
101
    npy_intp i, j;
102
    npy_intp odims[NPY_MAXDIMS];
103
    PyArrayObject *aout;
104 1
    PyArray_CopySwapFunc *copyswap = PyArray_DESCR(itx->ao)->f->copyswap;
105 1
    npy_int itemsize = PyArray_ITEMSIZE(itx->ao);
106

107
    /*
108
     * For each point in itx, copy the current neighborhood into an array which
109
     * is appended at the output list
110
     */
111 1
    for (i = 0; i < itx->size; ++i) {
112 1
        PyArrayNeighborhoodIter_Reset(niterx);
113

114 1
        for (j = 0; j < PyArray_NDIM(itx->ao); ++j) {
115 1
            odims[j] = bounds[2 * j + 1] - bounds[2 * j] + 1;
116
        }
117 1
        aout = (PyArrayObject*)PyArray_SimpleNew(PyArray_NDIM(itx->ao), odims, NPY_OBJECT);
118 1
        if (aout == NULL) {
119
            return -1;
120
        }
121

122 1
        for (j = 0; j < niterx->size; ++j) {
123 1
            copyswap(PyArray_BYTES(aout) + j * itemsize, niterx->dataptr, 0, NULL);
124 1
            PyArrayNeighborhoodIter_Next(niterx);
125
        }
126

127 1
        PyList_Append(*out, (PyObject*)aout);
128 1
        Py_DECREF(aout);
129 1
        PyArray_ITER_NEXT(itx);
130
    }
131

132
    return 0;
133
}
134

135
static PyObject*
136 1
test_neighborhood_iterator(PyObject* NPY_UNUSED(self), PyObject* args)
137
{
138
    PyObject *x, *fill, *out, *b;
139
    PyArrayObject *ax, *afill;
140
    PyArrayIterObject *itx;
141
    int i, typenum, mode, st;
142
    npy_intp bounds[NPY_MAXDIMS*2];
143
    PyArrayNeighborhoodIterObject *niterx;
144

145 1
    if (!PyArg_ParseTuple(args, "OOOi", &x, &b, &fill, &mode)) {
146
        return NULL;
147
    }
148

149 1
    if (!PySequence_Check(b)) {
150
        return NULL;
151
    }
152

153 1
    typenum = PyArray_ObjectType(x, 0);
154 1
    typenum = PyArray_ObjectType(fill, typenum);
155

156 1
    ax = (PyArrayObject*)PyArray_FromObject(x, typenum, 1, 10);
157 1
    if (ax == NULL) {
158
        return NULL;
159
    }
160 1
    if (PySequence_Size(b) != 2 * PyArray_NDIM(ax)) {
161 0
        PyErr_SetString(PyExc_ValueError,
162
                "bounds sequence size not compatible with x input");
163 0
        goto clean_ax;
164
    }
165

166 1
    out = PyList_New(0);
167 1
    if (out == NULL) {
168
        goto clean_ax;
169
    }
170

171 1
    itx = (PyArrayIterObject*)PyArray_IterNew(x);
172 1
    if (itx == NULL) {
173
        goto clean_out;
174
    }
175

176
    /* Compute boundaries for the neighborhood iterator */
177 1
    for (i = 0; i < 2 * PyArray_NDIM(ax); ++i) {
178
        PyObject* bound;
179 1
        bound = PySequence_GetItem(b, i);
180 1
        if (bound == NULL) {
181
            goto clean_itx;
182
        }
183 1
        if (!PyInt_Check(bound)) {
184 0
            PyErr_SetString(PyExc_ValueError,
185
                    "bound not long");
186 0
            Py_DECREF(bound);
187
            goto clean_itx;
188
        }
189 1
        bounds[i] = PyLong_AsSsize_t(bound);
190 1
        Py_DECREF(bound);
191
    }
192

193
    /* Create the neighborhood iterator */
194 1
    afill = NULL;
195 1
    if (mode == NPY_NEIGHBORHOOD_ITER_CONSTANT_PADDING) {
196 1
            afill = (PyArrayObject *)PyArray_FromObject(fill, typenum, 0, 0);
197 1
            if (afill == NULL) {
198
            goto clean_itx;
199
        }
200
    }
201

202 1
    niterx = (PyArrayNeighborhoodIterObject*)PyArray_NeighborhoodIterNew(
203
                    (PyArrayIterObject*)itx, bounds, mode, afill);
204 1
    if (niterx == NULL) {
205
        goto clean_afill;
206
    }
207

208 1
    switch (typenum) {
209 1
        case NPY_OBJECT:
210 1
            st = copy_object(itx, niterx, bounds, &out);
211 1
            break;
212 0
        case NPY_INT:
213 0
            st = copy_int(itx, niterx, bounds, &out);
214 0
            break;
215 1
        case NPY_DOUBLE:
216 1
            st = copy_double(itx, niterx, bounds, &out);
217 1
            break;
218 0
        default:
219 0
            PyErr_SetString(PyExc_ValueError,
220
                    "Type not supported");
221 0
            goto clean_niterx;
222
    }
223

224 1
    if (st) {
225
        goto clean_niterx;
226
    }
227

228 1
    Py_DECREF(niterx);
229 1
    Py_XDECREF(afill);
230 1
    Py_DECREF(itx);
231

232 1
    Py_DECREF(ax);
233

234 1
    return out;
235

236 0
clean_niterx:
237 0
    Py_DECREF(niterx);
238 0
clean_afill:
239 0
    Py_XDECREF(afill);
240 0
clean_itx:
241 0
    Py_DECREF(itx);
242 0
clean_out:
243 0
    Py_DECREF(out);
244 0
clean_ax:
245 0
    Py_DECREF(ax);
246
    return NULL;
247
}
248

249
static int
250 1
copy_double_double(PyArrayNeighborhoodIterObject *itx,
251
        PyArrayNeighborhoodIterObject *niterx,
252
        npy_intp const *bounds,
253
        PyObject **out)
254
{
255
    npy_intp i, j;
256
    double *ptr;
257
    npy_intp odims[NPY_MAXDIMS];
258
    PyArrayObject *aout;
259

260
    /*
261
     * For each point in itx, copy the current neighborhood into an array which
262
     * is appended at the output list
263
     */
264 1
    PyArrayNeighborhoodIter_Reset(itx);
265 1
    for (i = 0; i < itx->size; ++i) {
266 1
        for (j = 0; j < PyArray_NDIM(itx->ao); ++j) {
267 1
            odims[j] = bounds[2 * j + 1] - bounds[2 * j] + 1;
268
        }
269 1
        aout = (PyArrayObject*)PyArray_SimpleNew(
270
                            PyArray_NDIM(itx->ao), odims, NPY_DOUBLE);
271 1
        if (aout == NULL) {
272
            return -1;
273
        }
274

275 1
        ptr = (double*)PyArray_DATA(aout);
276

277 1
        PyArrayNeighborhoodIter_Reset(niterx);
278 1
        for (j = 0; j < niterx->size; ++j) {
279 1
            *ptr = *((double*)niterx->dataptr);
280 1
            ptr += 1;
281 1
            PyArrayNeighborhoodIter_Next(niterx);
282
        }
283 1
        PyList_Append(*out, (PyObject*)aout);
284 1
        Py_DECREF(aout);
285 1
        PyArrayNeighborhoodIter_Next(itx);
286
    }
287
    return 0;
288
}
289

290
static PyObject*
291 1
test_neighborhood_iterator_oob(PyObject* NPY_UNUSED(self), PyObject* args)
292
{
293
    PyObject *x, *out, *b1, *b2;
294
    PyArrayObject *ax;
295
    PyArrayIterObject *itx;
296
    int i, typenum, mode1, mode2, st;
297
    npy_intp bounds[NPY_MAXDIMS*2];
298
    PyArrayNeighborhoodIterObject *niterx1, *niterx2;
299

300 1
    if (!PyArg_ParseTuple(args, "OOiOi", &x, &b1, &mode1, &b2, &mode2)) {
301
        return NULL;
302
    }
303

304 1
    if (!PySequence_Check(b1) || !PySequence_Check(b2)) {
305
        return NULL;
306
    }
307

308 1
    typenum = PyArray_ObjectType(x, 0);
309

310 1
    ax = (PyArrayObject*)PyArray_FromObject(x, typenum, 1, 10);
311 1
    if (ax == NULL) {
312
        return NULL;
313
    }
314 1
    if (PySequence_Size(b1) != 2 * PyArray_NDIM(ax)) {
315 0
        PyErr_SetString(PyExc_ValueError,
316
                "bounds sequence 1 size not compatible with x input");
317 0
        goto clean_ax;
318
    }
319 1
    if (PySequence_Size(b2) != 2 * PyArray_NDIM(ax)) {
320 0
        PyErr_SetString(PyExc_ValueError,
321
                "bounds sequence 2 size not compatible with x input");
322 0
        goto clean_ax;
323
    }
324

325 1
    out = PyList_New(0);
326 1
    if (out == NULL) {
327
        goto clean_ax;
328
    }
329

330 1
    itx = (PyArrayIterObject*)PyArray_IterNew(x);
331 1
    if (itx == NULL) {
332
        goto clean_out;
333
    }
334

335
    /* Compute boundaries for the neighborhood iterator */
336 1
    for (i = 0; i < 2 * PyArray_NDIM(ax); ++i) {
337
        PyObject* bound;
338 1
        bound = PySequence_GetItem(b1, i);
339 1
        if (bound == NULL) {
340
            goto clean_itx;
341
        }
342 1
        if (!PyInt_Check(bound)) {
343 0
            PyErr_SetString(PyExc_ValueError,
344
                    "bound not long");
345 0
            Py_DECREF(bound);
346
            goto clean_itx;
347
        }
348 1
        bounds[i] = PyLong_AsSsize_t(bound);
349 1
        Py_DECREF(bound);
350
    }
351

352
    /* Create the neighborhood iterator */
353 1
    niterx1 = (PyArrayNeighborhoodIterObject*)PyArray_NeighborhoodIterNew(
354
                    (PyArrayIterObject*)itx, bounds,
355
                    mode1, NULL);
356 1
    if (niterx1 == NULL) {
357
        goto clean_out;
358
    }
359

360 1
    for (i = 0; i < 2 * PyArray_NDIM(ax); ++i) {
361
        PyObject* bound;
362 1
        bound = PySequence_GetItem(b2, i);
363 1
        if (bound == NULL) {
364
            goto clean_itx;
365
        }
366 1
        if (!PyInt_Check(bound)) {
367 0
            PyErr_SetString(PyExc_ValueError,
368
                    "bound not long");
369 0
            Py_DECREF(bound);
370
            goto clean_itx;
371
        }
372 1
        bounds[i] = PyLong_AsSsize_t(bound);
373 1
        Py_DECREF(bound);
374
    }
375

376 1
    niterx2 = (PyArrayNeighborhoodIterObject*)PyArray_NeighborhoodIterNew(
377
                    (PyArrayIterObject*)niterx1, bounds,
378
                    mode2, NULL);
379
    if (niterx1 == NULL) {
380
        goto clean_niterx1;
381
    }
382

383 1
    switch (typenum) {
384 1
        case NPY_DOUBLE:
385 1
            st = copy_double_double(niterx1, niterx2, bounds, &out);
386
            break;
387 0
        default:
388 0
            PyErr_SetString(PyExc_ValueError,
389
                    "Type not supported");
390 0
            goto clean_niterx2;
391
    }
392

393 1
    if (st) {
394
        goto clean_niterx2;
395
    }
396

397 1
    Py_DECREF(niterx2);
398 1
    Py_DECREF(niterx1);
399 1
    Py_DECREF(itx);
400 1
    Py_DECREF(ax);
401 1
    return out;
402

403 0
clean_niterx2:
404 0
    Py_DECREF(niterx2);
405 0
clean_niterx1:
406 0
    Py_DECREF(niterx1);
407 0
clean_itx:
408 0
    Py_DECREF(itx);
409 0
clean_out:
410 0
    Py_DECREF(out);
411 0
clean_ax:
412 0
    Py_DECREF(ax);
413
    return NULL;
414
}
415

416
/* PyDataMem_SetHook tests */
417
static int malloc_free_counts[2];
418
static PyDataMem_EventHookFunc *old_hook = NULL;
419
static void *old_data;
420

421 1
static void test_hook(void *old, void *new, size_t size, void *user_data)
422
{
423 1
    int* counters = (int *) user_data;
424 1
    if (old == NULL) {
425 1
        counters[0]++; /* malloc counter */
426
    }
427 1
    if (size == 0) {
428 1
        counters[1]++; /* free counter */
429
    }
430 1
}
431

432
static PyObject*
433 1
test_pydatamem_seteventhook_start(PyObject* NPY_UNUSED(self), PyObject* NPY_UNUSED(args))
434
{
435 1
    malloc_free_counts[0] = malloc_free_counts[1] = 0;
436 1
    old_hook = PyDataMem_SetEventHook(test_hook, (void *) malloc_free_counts, &old_data);
437 1
    Py_RETURN_NONE;
438
}
439

440
static PyObject*
441 1
test_pydatamem_seteventhook_end(PyObject* NPY_UNUSED(self), PyObject* NPY_UNUSED(args))
442
{
443
    PyDataMem_EventHookFunc *my_hook;
444
    void *my_data;
445

446 1
    my_hook = PyDataMem_SetEventHook(old_hook, old_data, &my_data);
447 1
    if ((my_hook != test_hook) || (my_data != (void *) malloc_free_counts)) {
448 0
        PyErr_SetString(PyExc_ValueError,
449
                        "hook/data was not the expected test hook");
450 0
        return NULL;
451
    }
452

453 1
    if (malloc_free_counts[0] == 0) {
454 0
        PyErr_SetString(PyExc_ValueError,
455
                        "malloc count is zero after test");
456 0
        return NULL;
457
    }
458 1
    if (malloc_free_counts[1] == 0) {
459 0
        PyErr_SetString(PyExc_ValueError,
460
                        "free count is zero after test");
461 0
        return NULL;
462
    }
463

464 1
    Py_RETURN_NONE;
465
}
466

467

468
typedef void (*inplace_map_binop)(PyArrayMapIterObject *, PyArrayIterObject *);
469

470 1
static void npy_float64_inplace_add(PyArrayMapIterObject *mit, PyArrayIterObject *it)
471
{
472 1
    int index = mit->size;
473 1
    while (index--) {
474 1
        ((npy_float64*)mit->dataptr)[0] = ((npy_float64*)mit->dataptr)[0] + ((npy_float64*)it->dataptr)[0];
475

476 1
        PyArray_MapIterNext(mit);
477 1
        PyArray_ITER_NEXT(it);
478
    }
479 1
}
480

481
inplace_map_binop addition_funcs[] = {
482
npy_float64_inplace_add,
483
NULL};
484

485
int type_numbers[] = {
486
NPY_FLOAT64,
487
-1000};
488

489

490

491
static int
492 1
map_increment(PyArrayMapIterObject *mit, PyObject *op, inplace_map_binop add_inplace)
493
{
494 1
    PyArrayObject *arr = NULL;
495
    PyArrayIterObject *it;
496
    PyArray_Descr *descr;
497

498 1
    if (mit->ait == NULL) {
499
        return -1;
500
    }
501 1
    descr = PyArray_DESCR(mit->ait->ao);
502 1
    Py_INCREF(descr);
503 1
    arr = (PyArrayObject *)PyArray_FromAny(op, descr,
504
                                0, 0, NPY_ARRAY_FORCECAST, NULL);
505 1
    if (arr == NULL) {
506
        return -1;
507
    }
508

509 1
    if ((mit->subspace != NULL) && (mit->consec)) {
510 0
        PyArray_MapIterSwapAxes(mit, (PyArrayObject **)&arr, 0);
511 0
        if (arr == NULL) {
512
            return -1;
513
        }
514
    }
515

516 1
    if ((it = (PyArrayIterObject *)\
517 1
            PyArray_BroadcastToShape((PyObject *)arr, mit->dimensions,
518
                                     mit->nd)) == NULL) {
519 0
        Py_DECREF(arr);
520

521
        return -1;
522
    }
523

524 1
    (*add_inplace)(mit, it);
525

526 1
    Py_DECREF(arr);
527 1
    Py_DECREF(it);
528
    return 0;
529
}
530

531

532
static PyObject *
533 1
inplace_increment(PyObject *dummy, PyObject *args)
534
{
535 1
    PyObject *arg_a = NULL, *index=NULL, *inc=NULL;
536
    PyArrayObject *a;
537 1
    inplace_map_binop add_inplace = NULL;
538 1
    int type_number = -1;
539 1
    int i =0;
540
    PyArrayMapIterObject * mit;
541

542 1
    if (!PyArg_ParseTuple(args, "OOO", &arg_a, &index,
543
            &inc)) {
544
        return NULL;
545
    }
546 1
    if (!PyArray_Check(arg_a)) {
547 0
         PyErr_SetString(PyExc_ValueError, "needs an ndarray as first argument");
548 0
         return NULL;
549
    }
550 1
    a = (PyArrayObject *) arg_a;
551

552 1
    if (PyArray_FailUnlessWriteable(a, "input/output array") < 0) {
553
        return NULL;
554
    }
555

556 1
    if (PyArray_NDIM(a) == 0) {
557 0
        PyErr_SetString(PyExc_IndexError, "0-d arrays can't be indexed.");
558 0
        return NULL;
559
    }
560 1
    type_number = PyArray_TYPE(a);
561

562 1
    while (type_numbers[i] >= 0 && addition_funcs[i] != NULL){
563 1
        if (type_number == type_numbers[i]) {
564
            add_inplace = addition_funcs[i];
565
            break;
566
        }
567 0
        i++ ;
568
    }
569

570 1
    if (add_inplace == NULL) {
571 0
        PyErr_SetString(PyExc_TypeError, "unsupported type for a");
572 0
        return NULL;
573
    }
574

575 1
    mit = (PyArrayMapIterObject *) PyArray_MapIterArray(a, index);
576 1
    if (mit == NULL) {
577
        goto fail;
578
    }
579

580 1
    if (map_increment(mit, inc, add_inplace) != 0) {
581
        goto fail;
582
    }
583

584 1
    Py_DECREF(mit);
585

586 1
    Py_RETURN_NONE;
587

588 0
fail:
589 0
    Py_XDECREF(mit);
590

591
    return NULL;
592
}
593

594
/*
595
 * Helper to test fromstring of 0 terminated strings, as the C-API supports
596
 * the -1 length identifier.
597
 */
598
static PyObject *
599 1
fromstring_null_term_c_api(PyObject *dummy, PyObject *byte_obj)
600
{
601
    char *string;
602
    PyArray_Descr *descr;
603

604 1
    string = PyBytes_AsString(byte_obj);
605 1
    if (string == NULL) {
606
        return NULL;
607
    }
608 1
    descr = PyArray_DescrNewFromType(NPY_FLOAT64);
609 1
    return PyArray_FromString(string, -1, descr, -1, " ");
610
}
611

612

613
/* check no elison for avoided increfs */
614
static PyObject *
615 1
incref_elide(PyObject *dummy, PyObject *args)
616
{
617 1
    PyObject *arg = NULL, *res, *tup;
618 1
    if (!PyArg_ParseTuple(args, "O", &arg)) {
619
        return NULL;
620
    }
621

622
    /* refcount 1 array but should not be elided */
623 1
    arg = PyArray_NewCopy((PyArrayObject*)arg, NPY_KEEPORDER);
624 1
    res = PyNumber_Add(arg, arg);
625

626
    /* return original copy, should be equal to input */
627 1
    tup = PyTuple_Pack(2, arg, res);
628 1
    Py_DECREF(arg);
629 1
    Py_DECREF(res);
630
    return tup;
631
}
632

633
/* check no elison for get from list without incref */
634
static PyObject *
635 1
incref_elide_l(PyObject *dummy, PyObject *args)
636
{
637 1
    PyObject *arg = NULL, *r, *res;
638 1
    if (!PyArg_ParseTuple(args, "O", &arg)) {
639
        return NULL;
640
    }
641
    /* get item without increasing refcount, item may still be on the python
642
     * stack but above the inaccessible top */
643 1
    r = PyList_GetItem(arg, 4);
644 1
    res = PyNumber_Add(r, r);
645

646 1
    return res;
647
}
648

649
/* used to test NPY_CHAR usage emits deprecation warning */
650
static PyObject*
651 1
npy_char_deprecation(PyObject* NPY_UNUSED(self), PyObject* NPY_UNUSED(args))
652
{
653 1
    PyArray_Descr * descr = PyArray_DescrFromType(NPY_CHAR);
654 1
    return (PyObject *)descr;
655
}
656

657
/* used to test UPDATEIFCOPY usage emits deprecation warning */
658
static PyObject*
659 1
npy_updateifcopy_deprecation(PyObject* NPY_UNUSED(self), PyObject* args)
660
{
661
    int flags;
662
    PyObject* array;
663 1
    if (!PyArray_Check(args)) {
664 0
        PyErr_SetString(PyExc_TypeError, "test needs ndarray input");
665 0
        return NULL;
666
    }
667 1
    flags = NPY_ARRAY_CARRAY | NPY_ARRAY_UPDATEIFCOPY;
668 1
    array = PyArray_FromArray((PyArrayObject*)args, NULL, flags);
669 1
    if (array == NULL)
670
        return NULL;
671 1
    PyArray_ResolveWritebackIfCopy((PyArrayObject*)array);
672 1
    Py_DECREF(array);
673 1
    Py_RETURN_NONE;
674
}
675

676
/* used to test PyArray_As1D usage emits not implemented error */
677
static PyObject*
678 1
npy_pyarrayas1d_deprecation(PyObject* NPY_UNUSED(self), PyObject* NPY_UNUSED(args))
679
{
680 1
    PyObject *op = Py_BuildValue("i", 42);
681 1
    PyObject *result = op;
682 1
    int dim = 4;
683 1
    double arg[2] = {1, 2};
684 1
    int temp = PyArray_As1D(&result, (char **)&arg, &dim, NPY_DOUBLE);
685 1
    if (temp < 0) {
686 1
        Py_DECREF(op);
687
        return NULL;
688
    }
689
    /* op != result */
690 0
    Py_DECREF(op);
691 0
    return result;
692
}
693

694
/* used to test PyArray_As2D usage emits not implemented error */
695
static PyObject*
696 1
npy_pyarrayas2d_deprecation(PyObject* NPY_UNUSED(self), PyObject* NPY_UNUSED(args))
697
{
698 1
    PyObject *op = Py_BuildValue("i", 42);
699 1
    PyObject *result = op;
700 1
    int dim1 = 4;
701 1
    int dim2 = 6;
702 1
    double arg[2][2] = {{1, 2}, {3, 4}};
703 1
    int temp = PyArray_As2D(&result, (char ***)&arg, &dim1, &dim2, NPY_DOUBLE);
704 1
    if (temp < 0) {
705 1
        Py_DECREF(op);
706
        return NULL;
707
    }
708
    /* op != result */
709 0
    Py_DECREF(op);
710 0
    return result;
711
}
712

713
/* used to create array with WRITEBACKIFCOPY flag */
714
static PyObject*
715 1
npy_create_writebackifcopy(PyObject* NPY_UNUSED(self), PyObject* args)
716
{
717
    int flags;
718
    PyObject* array;
719 1
    if (!PyArray_Check(args)) {
720 0
        PyErr_SetString(PyExc_TypeError, "test needs ndarray input");
721 0
        return NULL;
722
    }
723 1
    flags = NPY_ARRAY_CARRAY | NPY_ARRAY_WRITEBACKIFCOPY;
724 1
    array = PyArray_FromArray((PyArrayObject*)args, NULL, flags);
725 1
    if (array == NULL)
726
        return NULL;
727 1
    return array;
728
}
729

730
/* used to test WRITEBACKIFCOPY without resolution emits runtime warning */
731
static PyObject*
732 1
npy_abuse_writebackifcopy(PyObject* NPY_UNUSED(self), PyObject* args)
733
{
734
    int flags;
735
    PyObject* array;
736 1
    if (!PyArray_Check(args)) {
737 0
        PyErr_SetString(PyExc_TypeError, "test needs ndarray input");
738 0
        return NULL;
739
    }
740 1
    flags = NPY_ARRAY_CARRAY | NPY_ARRAY_WRITEBACKIFCOPY;
741 1
    array = PyArray_FromArray((PyArrayObject*)args, NULL, flags);
742 1
    if (array == NULL)
743
        return NULL;
744 1
    Py_DECREF(array); /* calls array_dealloc even on PyPy */
745 1
    Py_RETURN_NONE;
746
}
747

748
/* resolve WRITEBACKIFCOPY */
749
static PyObject*
750 1
npy_resolve(PyObject* NPY_UNUSED(self), PyObject* args)
751
{
752 1
    if (!PyArray_Check(args)) {
753 0
        PyErr_SetString(PyExc_TypeError, "test needs ndarray input");
754 0
        return NULL;
755
    }
756 1
    PyArray_ResolveWritebackIfCopy((PyArrayObject*)args);
757 1
    Py_RETURN_NONE;
758
}
759

760
/* resolve WRITEBACKIFCOPY */
761
static PyObject*
762 1
npy_discard(PyObject* NPY_UNUSED(self), PyObject* args)
763
{
764 1
    if (!PyArray_Check(args)) {
765 0
        PyErr_SetString(PyExc_TypeError, "test needs ndarray input");
766 0
        return NULL;
767
    }
768 1
    PyArray_DiscardWritebackIfCopy((PyArrayObject*)args);
769 1
    Py_RETURN_NONE;
770
}
771

772
/*
773
 * Create python string from a FLAG and or the corresponding PyBuf flag
774
 * for the use in get_buffer_info.
775
 */
776
#define GET_PYBUF_FLAG(FLAG)                                        \
777
    buf_flag = PyUnicode_FromString(#FLAG);                         \
778
    flag_matches = PyObject_RichCompareBool(buf_flag, tmp, Py_EQ);  \
779
    Py_DECREF(buf_flag);                                            \
780
    if (flag_matches == 1) {                                        \
781
        Py_DECREF(tmp);                                             \
782
        flags |= PyBUF_##FLAG;                                      \
783
        continue;                                                   \
784
    }                                                               \
785
    else if (flag_matches == -1) {                                  \
786
        Py_DECREF(tmp);                                             \
787
        return NULL;                                                \
788
    }
789

790

791
/*
792
 * Get information for a buffer through PyBuf_GetBuffer with the
793
 * corresponding flags or'ed. Note that the python caller has to
794
 * make sure that or'ing those flags actually makes sense.
795
 * More information should probably be returned for future tests.
796
 */
797
static PyObject *
798 1
get_buffer_info(PyObject *NPY_UNUSED(self), PyObject *args)
799
{
800
    PyObject *buffer_obj, *pyflags;
801
    PyObject *tmp, *buf_flag;
802
    Py_buffer buffer;
803
    PyObject *shape, *strides;
804
    Py_ssize_t i, n;
805
    int flag_matches;
806 1
    int flags = 0;
807

808 1
    if (!PyArg_ParseTuple(args, "OO", &buffer_obj, &pyflags)) {
809
        return NULL;
810
    }
811

812 1
    n = PySequence_Length(pyflags);
813 1
    if (n < 0) {
814
        return NULL;
815
    }
816

817 1
    for (i=0; i < n; i++) {
818 1
        tmp = PySequence_GetItem(pyflags, i);
819 1
        if (tmp == NULL) {
820
            return NULL;
821
        }
822

823 1
        GET_PYBUF_FLAG(SIMPLE);
824 1
        GET_PYBUF_FLAG(WRITABLE);
825 1
        GET_PYBUF_FLAG(STRIDES);
826 1
        GET_PYBUF_FLAG(ND);
827 1
        GET_PYBUF_FLAG(C_CONTIGUOUS);
828 1
        GET_PYBUF_FLAG(F_CONTIGUOUS);
829 0
        GET_PYBUF_FLAG(ANY_CONTIGUOUS);
830 0
        GET_PYBUF_FLAG(INDIRECT);
831 0
        GET_PYBUF_FLAG(FORMAT);
832 0
        GET_PYBUF_FLAG(STRIDED);
833 0
        GET_PYBUF_FLAG(STRIDED_RO);
834 0
        GET_PYBUF_FLAG(RECORDS);
835 0
        GET_PYBUF_FLAG(RECORDS_RO);
836 0
        GET_PYBUF_FLAG(FULL);
837 0
        GET_PYBUF_FLAG(FULL_RO);
838 0
        GET_PYBUF_FLAG(CONTIG);
839 0
        GET_PYBUF_FLAG(CONTIG_RO);
840

841 0
        Py_DECREF(tmp);
842

843
        /* One of the flags must match */
844 0
        PyErr_SetString(PyExc_ValueError, "invalid flag used.");
845 0
        return NULL;
846
    }
847

848 1
    if (PyObject_GetBuffer(buffer_obj, &buffer, flags) < 0) {
849
        return NULL;
850
    }
851

852 1
    if (buffer.shape == NULL) {
853 0
        Py_INCREF(Py_None);
854 0
        shape = Py_None;
855
    }
856
    else {
857 1
        shape = PyTuple_New(buffer.ndim);
858 1
        for (i=0; i < buffer.ndim; i++) {
859 1
            PyTuple_SET_ITEM(shape, i, PyLong_FromSsize_t(buffer.shape[i]));
860
        }
861
    }
862

863 1
    if (buffer.strides == NULL) {
864 0
        Py_INCREF(Py_None);
865 0
        strides = Py_None;
866
    }
867
    else {
868 1
        strides = PyTuple_New(buffer.ndim);
869 1
        for (i=0; i < buffer.ndim; i++) {
870 1
            PyTuple_SET_ITEM(strides, i, PyLong_FromSsize_t(buffer.strides[i]));
871
        }
872
    }
873

874 1
    PyBuffer_Release(&buffer);
875 1
    return Py_BuildValue("(NN)", shape, strides);
876
}
877

878
#undef GET_PYBUF_FLAG
879

880
/*
881
 * Return a new array object wrapping existing C-allocated (dummy) data.
882
 * Such an array does not own its data (must not free it), but because it
883
 * wraps C data, it also has no base object. Used to test arr.flags.writeable
884
 * setting behaviour.
885
 */
886
static PyObject*
887 1
get_c_wrapping_array(PyObject* NPY_UNUSED(self), PyObject* arg)
888
{
889
    int writeable, flags;
890
    PyArray_Descr *descr;
891 1
    npy_intp zero = 0;
892

893 1
    writeable = PyObject_IsTrue(arg);
894 1
    if (error_converting(writeable)) {
895
        return NULL;
896
    }
897

898 1
    flags = writeable ? NPY_ARRAY_WRITEABLE : 0;
899
    /* Create an empty array (which points to a random place) */
900 1
    descr =  PyArray_DescrNewFromType(NPY_INTP);
901 1
    return PyArray_NewFromDescr(&PyArray_Type, descr,
902
                                1, &zero, NULL, &zero, flags, NULL);
903
}
904

905

906
/*
907
 * Test C-api level item getting.
908
 */
909
static PyObject *
910 1
array_indexing(PyObject *NPY_UNUSED(self), PyObject *args)
911
{
912
    int mode;
913
    Py_ssize_t i;
914 1
    PyObject *arr, *op = NULL;
915

916 1
    if (!PyArg_ParseTuple(args, "iOn|O", &mode, &arr, &i, &op)) {
917
        return NULL;
918
    }
919

920 1
    if (mode == 0) {
921 1
        return PySequence_GetItem(arr, i);
922
    }
923 1
    if (mode == 1) {
924 1
        if (PySequence_SetItem(arr, i, op) < 0) {
925
            return NULL;
926
        }
927 1
        Py_RETURN_NONE;
928
    }
929

930 0
    PyErr_SetString(PyExc_ValueError,
931
                    "invalid mode. 0: item 1: assign");
932 0
    return NULL;
933
}
934

935
/*
936
 * Test C-api PyArray_AsCArray item getter
937
 */
938
static PyObject *
939 1
test_as_c_array(PyObject *NPY_UNUSED(self), PyObject *args)
940
{
941
    PyArrayObject *array_obj;
942
    npy_intp dims[3];   /* max 3-dim */
943 1
    npy_intp i=0, j=0, k=0;
944 1
    npy_intp num_dims = 0;
945 1
    PyArray_Descr *descr = NULL;
946 1
    double *array1 = NULL;
947 1
    double **array2 = NULL;
948 1
    double ***array3 = NULL;
949 1
    double temp = 9999;
950

951 1
    if (!PyArg_ParseTuple(args, "O!l|ll",
952 1
                &PyArray_Type, &array_obj,
953
                &i, &j, &k)) {
954
        return NULL;
955
    }
956

957 1
    if (NULL == array_obj) {
958
        return NULL;
959
    }
960

961 1
    num_dims = PyArray_NDIM(array_obj);
962 1
    descr = PyArray_DESCR(array_obj);
963 1
    Py_INCREF(descr);  /* PyArray_AsCArray steals a reference to this */
964

965 1
    switch (num_dims) {
966 1
        case 1:
967 1
            if (PyArray_AsCArray(
968
                    (PyObject **) &array_obj,
969
                    (void *) &array1,
970
                    dims,
971
                    1,
972
                    descr) < 0) {
973 0
                PyErr_SetString(PyExc_RuntimeError, "error converting 1D array");
974 0
                return NULL;
975
            }
976 1
            temp = array1[i];
977 1
            PyArray_Free((PyObject *) array_obj, (void *) array1);
978 1
            break;
979 1
        case 2:
980 1
            if (PyArray_AsCArray(
981
                    (PyObject **) &array_obj,
982
                    (void **) &array2,
983
                    dims,
984
                    2,
985
                    descr) < 0) {
986 0
                PyErr_SetString(PyExc_RuntimeError, "error converting 2D array");
987 0
                return NULL;
988
            }
989 1
            temp = array2[i][j];
990 1
            PyArray_Free((PyObject *) array_obj, (void *) array2);
991 1
            break;
992 1
        case 3:
993 1
            if (PyArray_AsCArray(
994
                    (PyObject **) &array_obj,
995
                    (void ***) &array3,
996
                    dims,
997
                    3,
998
                    descr) < 0) {
999 0
                PyErr_SetString(PyExc_RuntimeError, "error converting 3D array");
1000 0
                return NULL;
1001
            }
1002 1
            temp = array3[i][j][k];
1003 1
            PyArray_Free((PyObject *) array_obj, (void *) array3);
1004 1
            break;
1005 0
        default:
1006 0
            Py_DECREF(descr);
1007 0
            PyErr_SetString(PyExc_ValueError, "array.ndim not in [1, 3]");
1008 0
            return NULL;
1009
    }
1010 1
    return Py_BuildValue("f", temp);
1011
}
1012

1013
/*
1014
 * Test nditer of too large arrays using remove axis, etc.
1015
 */
1016
static PyObject *
1017 1
test_nditer_too_large(PyObject *NPY_UNUSED(self), PyObject *args) {
1018
    NpyIter *iter;
1019
    PyObject *array_tuple, *arr;
1020
    PyArrayObject *arrays[NPY_MAXARGS];
1021
    npy_uint32 op_flags[NPY_MAXARGS];
1022
    Py_ssize_t nop;
1023
    int i, axis, mode;
1024

1025 1
    npy_intp index[NPY_MAXARGS] = {0};
1026
    char *msg;
1027

1028 1
    if (!PyArg_ParseTuple(args, "Oii", &array_tuple, &axis, &mode)) {
1029
        return NULL;
1030
    }
1031

1032 1
    if (!PyTuple_CheckExact(array_tuple)) {
1033 0
        PyErr_SetString(PyExc_ValueError, "tuple required as first argument");
1034 0
        return NULL;
1035
    }
1036 1
    nop = PyTuple_Size(array_tuple);
1037 1
    if (nop > NPY_MAXARGS) {
1038 0
        PyErr_SetString(PyExc_ValueError, "tuple must be smaller then maxargs");
1039 0
        return NULL;
1040
    }
1041

1042 1
    for (i=0; i < nop; i++) {
1043 1
        arr = PyTuple_GET_ITEM(array_tuple, i);
1044 1
        if (!PyArray_CheckExact(arr)) {
1045 0
            PyErr_SetString(PyExc_ValueError, "require base class ndarray");
1046 0
            return NULL;
1047
        }
1048 1
        arrays[i] = (PyArrayObject *)arr;
1049 1
        op_flags[i] = NPY_ITER_READONLY;
1050
    }
1051

1052 1
    iter = NpyIter_MultiNew(nop, arrays, NPY_ITER_MULTI_INDEX | NPY_ITER_RANGED,
1053
                            NPY_KEEPORDER, NPY_NO_CASTING, op_flags, NULL);
1054

1055 1
    if (iter == NULL) {
1056
        return NULL;
1057
    }
1058

1059
    /* Remove an axis (negative, do not remove any) */
1060 1
    if (axis >= 0) {
1061 1
        if (!NpyIter_RemoveAxis(iter, axis)) {
1062
            goto fail;
1063
        }
1064
    }
1065

1066 1
    switch (mode) {
1067
        /* Test IterNext getting */
1068 1
        case 0:
1069 1
            if (NpyIter_GetIterNext(iter, NULL) == NULL) {
1070
                goto fail;
1071
            }
1072
            break;
1073 1
        case 1:
1074 1
            if (NpyIter_GetIterNext(iter, &msg) == NULL) {
1075 1
                PyErr_SetString(PyExc_ValueError, msg);
1076 1
                goto fail;
1077
            }
1078
            break;
1079
        /* Test Multi Index removal */
1080 1
        case 2:
1081 1
            if (!NpyIter_RemoveMultiIndex(iter)) {
1082
                goto fail;
1083
            }
1084
            break;
1085
        /* Test GotoMultiIndex (just 0 hardcoded) */
1086 1
        case 3:
1087 1
            if (!NpyIter_GotoMultiIndex(iter, index)) {
1088
                goto fail;
1089
            }
1090
            break;
1091
        /* Test setting iterrange (hardcoded range of 0, 1) */
1092 1
        case 4:
1093 1
            if (!NpyIter_ResetToIterIndexRange(iter, 0, 1, NULL)) {
1094
                goto fail;
1095
            }
1096
            break;
1097 1
        case 5:
1098 1
            if (!NpyIter_ResetToIterIndexRange(iter, 0, 1, &msg)) {
1099 1
                PyErr_SetString(PyExc_ValueError, msg);
1100 1
                goto fail;
1101
            }
1102
            break;
1103
        /* Do nothing */
1104
        default:
1105
            break;
1106
    }
1107

1108 1
    NpyIter_Deallocate(iter);
1109 1
    Py_RETURN_NONE;
1110 1
  fail:
1111 1
    NpyIter_Deallocate(iter);
1112 1
    return NULL;
1113
}
1114

1115
static PyObject *
1116 1
array_solve_diophantine(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
1117
{
1118 1
    PyObject *A = NULL;
1119 1
    PyObject *U = NULL;
1120 1
    Py_ssize_t b_input = 0;
1121 1
    Py_ssize_t max_work = -1;
1122 1
    int simplify = 0;
1123 1
    int require_ub_nontrivial = 0;
1124
    static char *kwlist[] = {"A", "U", "b", "max_work", "simplify",
1125
                             "require_ub_nontrivial", NULL};
1126

1127
    diophantine_term_t terms[2*NPY_MAXDIMS+2];
1128
    npy_int64 x[2*NPY_MAXDIMS+2];
1129
    npy_int64 b;
1130
    unsigned int nterms, j;
1131 1
    mem_overlap_t result = MEM_OVERLAP_YES;
1132 1
    PyObject *retval = NULL;
1133 1
    NPY_BEGIN_THREADS_DEF;
1134

1135 1
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!n|nii", kwlist,
1136
                                     &PyTuple_Type, &A,
1137
                                     &PyTuple_Type, &U,
1138
                                     &b_input, &max_work, &simplify,
1139
                                     &require_ub_nontrivial)) {
1140
        return NULL;
1141
    }
1142

1143 1
    if (PyTuple_GET_SIZE(A) > (Py_ssize_t)ARRAY_SIZE(terms)) {
1144 0
        PyErr_SetString(PyExc_ValueError, "too many terms in equation");
1145
        goto fail;
1146
    }
1147

1148 1
    nterms = PyTuple_GET_SIZE(A);
1149

1150 1
    if (PyTuple_GET_SIZE(U) != nterms) {
1151 0
        PyErr_SetString(PyExc_ValueError, "A, U must be tuples of equal length");
1152
        goto fail;
1153
    }
1154

1155 1
    for (j = 0; j < nterms; ++j) {
1156 1
        terms[j].a = (npy_int64)PyLong_AsSsize_t(PyTuple_GET_ITEM(A, j));
1157 1
        if (error_converting(terms[j].a)) {
1158
            goto fail;
1159
        }
1160 1
        terms[j].ub = (npy_int64)PyLong_AsSsize_t(PyTuple_GET_ITEM(U, j));
1161 1
        if (error_converting(terms[j].ub)) {
1162
            goto fail;
1163
        }
1164
    }
1165

1166 1
    b = b_input;
1167

1168 1
    NPY_BEGIN_THREADS;
1169 1
    if (simplify && !require_ub_nontrivial) {
1170 1
        if (diophantine_simplify(&nterms, terms, b)) {
1171
            result = MEM_OVERLAP_OVERFLOW;
1172
        }
1173
    }
1174
    if (result == MEM_OVERLAP_YES) {
1175 1
        result = solve_diophantine(nterms, terms, b, max_work, require_ub_nontrivial, x);
1176
    }
1177 1
    NPY_END_THREADS;
1178

1179 1
    if (result == MEM_OVERLAP_YES) {
1180 1
        retval = PyTuple_New(nterms);
1181 1
        if (retval == NULL) {
1182
            goto fail;
1183
        }
1184

1185 1
        for (j = 0; j < nterms; ++j) {
1186
            PyObject *obj;
1187 1
            obj = PyLong_FromSsize_t(x[j]);
1188 1
            if (obj == NULL) {
1189
                goto fail;
1190
            }
1191 1
            PyTuple_SET_ITEM(retval, j, obj);
1192
        }
1193
    }
1194 1
    else if (result == MEM_OVERLAP_NO) {
1195 1
        retval = Py_None;
1196 1
        Py_INCREF(retval);
1197
    }
1198 0
    else if (result == MEM_OVERLAP_ERROR) {
1199 0
        PyErr_SetString(PyExc_ValueError, "Invalid arguments");
1200
    }
1201 0
    else if (result == MEM_OVERLAP_OVERFLOW) {
1202 0
        PyErr_SetString(PyExc_OverflowError, "Integer overflow");
1203
    }
1204 0
    else if (result == MEM_OVERLAP_TOO_HARD) {
1205 0
        PyErr_SetString(PyExc_RuntimeError, "Too much work done");
1206
    }
1207
    else {
1208 0
        PyErr_SetString(PyExc_RuntimeError, "Unknown error");
1209
    }
1210

1211
    return retval;
1212

1213 0
fail:
1214 0
    Py_XDECREF(retval);
1215
    return NULL;
1216
}
1217

1218

1219
static PyObject *
1220 1
array_internal_overlap(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
1221
{
1222 1
    PyArrayObject * self = NULL;
1223
    static char *kwlist[] = {"self", "max_work", NULL};
1224

1225
    mem_overlap_t result;
1226 1
    Py_ssize_t max_work = NPY_MAY_SHARE_EXACT;
1227 1
    NPY_BEGIN_THREADS_DEF;
1228

1229 1
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|n", kwlist,
1230 1
                                     PyArray_Converter, &self,
1231
                                     &max_work)) {
1232
        return NULL;
1233
    }
1234

1235 1
    if (max_work < -2) {
1236 0
        PyErr_SetString(PyExc_ValueError, "Invalid value for max_work");
1237
        goto fail;
1238
    }
1239

1240 1
    NPY_BEGIN_THREADS;
1241 1
    result = solve_may_have_internal_overlap(self, max_work);
1242 1
    NPY_END_THREADS;
1243

1244 1
    Py_XDECREF(self);
1245

1246 1
    if (result == MEM_OVERLAP_NO) {
1247 1
        Py_RETURN_FALSE;
1248
    }
1249 1
    else if (result == MEM_OVERLAP_YES) {
1250 1
        Py_RETURN_TRUE;
1251
    }
1252 0
    else if (result == MEM_OVERLAP_OVERFLOW) {
1253 0
        PyErr_SetString(PyExc_OverflowError,
1254
                        "Integer overflow in computing overlap");
1255 0
        return NULL;
1256
    }
1257 0
    else if (result == MEM_OVERLAP_TOO_HARD) {
1258 0
        PyErr_SetString(PyExc_ValueError,
1259
                        "Exceeded max_work");
1260 0
        return NULL;
1261
    }
1262
    else {
1263
        /* Doesn't happen usually */
1264 0
        PyErr_SetString(PyExc_RuntimeError,
1265
                        "Error in computing overlap");
1266 0
        return NULL;
1267
    }
1268

1269 0
fail:
1270 0
    Py_XDECREF(self);
1271
    return NULL;
1272
}
1273

1274

1275
static PyObject *
1276 1
pylong_from_int128(npy_extint128_t value)
1277
{
1278 1
    PyObject *val_64 = NULL, *val = NULL, *tmp = NULL, *tmp2 = NULL;
1279

1280 1
    val_64 = PyLong_FromLong(64);
1281 1
    if (val_64 == NULL) {
1282
        goto fail;
1283
    }
1284

1285 1
    val = PyLong_FromUnsignedLongLong(value.hi);
1286 1
    if (val == NULL) {
1287
        goto fail;
1288
    }
1289

1290 1
    tmp = PyNumber_Lshift(val, val_64);
1291 1
    if (tmp == NULL) {
1292
        goto fail;
1293
    }
1294

1295 1
    Py_DECREF(val);
1296 1
    Py_DECREF(val_64);
1297 1
    val = tmp;
1298 1
    val_64 = NULL;
1299

1300 1
    tmp = PyLong_FromUnsignedLongLong(value.lo);
1301 1
    if (tmp == NULL) {
1302
        goto fail;
1303
    }
1304

1305 1
    tmp2 = PyNumber_Or(val, tmp);
1306 1
    if (tmp2 == NULL) {
1307
        goto fail;
1308
    }
1309

1310 1
    Py_DECREF(val);
1311 1
    Py_DECREF(tmp);
1312

1313 1
    val = NULL;
1314 1
    tmp = NULL;
1315

1316 1
    if (value.sign < 0) {
1317 1
        val = PyNumber_Negative(tmp2);
1318 1
        if (val == NULL) {
1319
            goto fail;
1320
        }
1321 1
        Py_DECREF(tmp2);
1322
        return val;
1323
    }
1324
    else {
1325
        val = tmp2;
1326
    }
1327
    return val;
1328

1329 0
fail:
1330 0
    Py_XDECREF(val_64);
1331 0
    Py_XDECREF(tmp);
1332 0
    Py_XDECREF(tmp2);
1333 0
    Py_XDECREF(val);
1334
    return NULL;
1335
}
1336

1337

1338
static int
1339 1
int128_from_pylong(PyObject *obj, npy_extint128_t *result)
1340
{
1341 1
    PyObject *long_obj = NULL, *val_64 = NULL, *val_0 = NULL,
1342 1
        *mask_64 = NULL, *max_128 = NULL, *hi_bits = NULL,
1343 1
        *lo_bits = NULL, *tmp = NULL;
1344
    int cmp;
1345 1
    int negative_zero = 0;
1346

1347 1
    if (PyBool_Check(obj)) {
1348
        /* False means negative zero */
1349 1
        negative_zero = 1;
1350
    }
1351

1352 1
    long_obj = PyObject_CallFunction((PyObject*)&PyLong_Type, "O", obj);
1353 1
    if (long_obj == NULL) {
1354
        goto fail;
1355
    }
1356

1357 1
    val_0 = PyLong_FromLong(0);
1358 1
    if (val_0 == NULL) {
1359
        goto fail;
1360
    }
1361

1362 1
    val_64 = PyLong_FromLong(64);
1363 1
    if (val_64 == NULL) {
1364
        goto fail;
1365
    }
1366

1367 1
    mask_64 = PyLong_FromUnsignedLongLong(0xffffffffffffffffULL);
1368 1
    if (mask_64 == NULL) {
1369
        goto fail;
1370
    }
1371

1372 1
    tmp = PyNumber_Lshift(mask_64, val_64);
1373 1
    if (tmp == NULL) {
1374
        goto fail;
1375
    }
1376 1
    max_128 = PyNumber_Or(tmp, mask_64);
1377 1
    if (max_128 == NULL) {
1378
        goto fail;
1379
    }
1380 1
    Py_DECREF(tmp);
1381 1
    tmp = NULL;
1382

1383 1
    cmp = PyObject_RichCompareBool(long_obj, val_0, Py_LT);
1384 1
    if (cmp == -1) {
1385
        goto fail;
1386
    }
1387 1
    else if (cmp == 1) {
1388 1
        tmp = PyNumber_Negative(long_obj);
1389 1
        if (tmp == NULL) {
1390
            goto fail;
1391
        }
1392 1
        Py_DECREF(long_obj);
1393 1
        long_obj = tmp;
1394 1
        tmp = NULL;
1395 1
        result->sign = -1;
1396
    }
1397
    else {
1398 1
        result->sign = 1;
1399
    }
1400

1401 1
    cmp = PyObject_RichCompareBool(long_obj, max_128, Py_GT);
1402 1
    if (cmp == 1) {
1403 0
        PyErr_SetString(PyExc_OverflowError, "");
1404 0
        goto fail;
1405
    }
1406 1
    else if (cmp == -1) {
1407
        goto fail;
1408
    }
1409

1410 1
    hi_bits = PyNumber_Rshift(long_obj, val_64);
1411 1
    if (hi_bits == NULL) {
1412
        goto fail;
1413
    }
1414

1415 1
    lo_bits = PyNumber_And(long_obj, mask_64);
1416 1
    if (lo_bits == NULL) {
1417
        goto fail;
1418
    }
1419

1420 1
    result->hi = PyLong_AsUnsignedLongLong(hi_bits);
1421 1
    if (result->hi == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) {
1422
        goto fail;
1423
    }
1424

1425 1
    result->lo = PyLong_AsUnsignedLongLong(lo_bits);
1426 1
    if (result->lo == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) {
1427
        goto fail;
1428
    }
1429

1430 1
    if (negative_zero && result->hi == 0 && result->lo == 0) {
1431 1
        result->sign = -1;
1432
    }
1433

1434 1
    Py_XDECREF(long_obj);
1435 1
    Py_XDECREF(val_64);
1436 1
    Py_XDECREF(val_0);
1437 1
    Py_XDECREF(mask_64);
1438 1
    Py_XDECREF(max_128);
1439 1
    Py_XDECREF(hi_bits);
1440 1
    Py_XDECREF(lo_bits);
1441
    Py_XDECREF(tmp);
1442
    return 0;
1443

1444 0
fail:
1445 0
    Py_XDECREF(long_obj);
1446 0
    Py_XDECREF(val_64);
1447 0
    Py_XDECREF(val_0);
1448 0
    Py_XDECREF(mask_64);
1449 0
    Py_XDECREF(max_128);
1450 0
    Py_XDECREF(hi_bits);
1451 0
    Py_XDECREF(lo_bits);
1452 0
    Py_XDECREF(tmp);
1453
    return -1;
1454
}
1455

1456

1457
static PyObject *
1458 1
extint_safe_binop(PyObject *NPY_UNUSED(self), PyObject *args) {
1459
    PY_LONG_LONG a, b, c;
1460
    int op;
1461 1
    char overflow = 0;
1462 1
    if (!PyArg_ParseTuple(args, "LLi", &a, &b, &op)) {
1463
        return NULL;
1464
    }
1465 1
    if (op == 1) {
1466 1
        c = safe_add(a, b, &overflow);
1467
    }
1468 1
    else if (op == 2) {
1469 1
        c = safe_sub(a, b, &overflow);
1470
    }
1471 1
    else if (op == 3) {
1472 1
        c = safe_mul(a, b, &overflow);
1473
    }
1474
    else {
1475 0
        PyErr_SetString(PyExc_ValueError, "invalid op");
1476 0
        return NULL;
1477
    }
1478 1
    if (overflow) {
1479 1
        PyErr_SetString(PyExc_OverflowError, "");
1480 1
        return NULL;
1481
    }
1482 1
    return PyLong_FromLongLong(c);
1483
}
1484

1485

1486
static PyObject *
1487 1
extint_to_128(PyObject *NPY_UNUSED(self), PyObject *args) {
1488
    PY_LONG_LONG a;
1489 1
    if (!PyArg_ParseTuple(args, "L", &a)) {
1490
        return NULL;
1491
    }
1492 1
    return pylong_from_int128(to_128(a));
1493
}
1494

1495

1496
static PyObject *
1497 1
extint_to_64(PyObject *NPY_UNUSED(self), PyObject *args) {
1498
    PyObject *a_obj;
1499
    npy_extint128_t a;
1500
    PY_LONG_LONG r;
1501 1
    char overflow = 0;
1502 1
    if (!PyArg_ParseTuple(args, "O", &a_obj)) {
1503
        return NULL;
1504
    }
1505 1
    if (int128_from_pylong(a_obj, &a)) {
1506
        return NULL;
1507
    }
1508 1
    r = to_64(a, &overflow);
1509
    if (overflow) {
1510 1
        PyErr_SetString(PyExc_OverflowError, "");
1511 1
        return NULL;
1512
    }
1513 1
    return PyLong_FromLongLong(r);
1514
}
1515

1516

1517
static PyObject *
1518 1
extint_mul_64_64(PyObject *NPY_UNUSED(self), PyObject *args) {
1519
    PY_LONG_LONG a, b;
1520
    npy_extint128_t c;
1521 1
    if (!PyArg_ParseTuple(args, "LL", &a, &b)) {
1522
        return NULL;
1523
    }
1524 1
    c = mul_64_64(a, b);
1525 1
    return pylong_from_int128(c);
1526
}
1527

1528

1529
static PyObject *
1530 1
extint_add_128(PyObject *NPY_UNUSED(self), PyObject *args) {
1531
    PyObject *a_obj, *b_obj;
1532
    npy_extint128_t a, b, c;
1533 1
    char overflow = 0;
1534 1
    if (!PyArg_ParseTuple(args, "OO", &a_obj, &b_obj)) {
1535
        return NULL;
1536
    }
1537 1
    if (int128_from_pylong(a_obj, &a) || int128_from_pylong(b_obj, &b)) {
1538
        return NULL;
1539
    }
1540 1
    c = add_128(a, b, &overflow);
1541 1
    if (overflow) {
1542 1
        PyErr_SetString(PyExc_OverflowError, "");
1543 1
        return NULL;
1544
    }
1545 1
    return pylong_from_int128(c);
1546
}
1547

1548

1549
static PyObject *
1550 1
extint_sub_128(PyObject *NPY_UNUSED(self), PyObject *args) {
1551
    PyObject *a_obj, *b_obj;
1552
    npy_extint128_t a, b, c;
1553 1
    char overflow = 0;
1554 1
    if (!PyArg_ParseTuple(args, "OO", &a_obj, &b_obj)) {
1555
        return NULL;
1556
    }
1557 1
    if (int128_from_pylong(a_obj, &a) || int128_from_pylong(b_obj, &b)) {
1558
        return NULL;
1559
    }
1560 1
    c = sub_128(a, b, &overflow);
1561 1
    if (overflow) {
1562 1
        PyErr_SetString(PyExc_OverflowError, "");
1563 1
        return NULL;
1564
    }
1565 1
    return pylong_from_int128(c);
1566
}
1567

1568

1569
static PyObject *
1570 1
extint_neg_128(PyObject *NPY_UNUSED(self), PyObject *args) {
1571
    PyObject *a_obj;
1572
    npy_extint128_t a, b;
1573 1
    if (!PyArg_ParseTuple(args, "O", &a_obj)) {
1574
        return NULL;
1575
    }
1576 1
    if (int128_from_pylong(a_obj, &a)) {
1577
        return NULL;
1578
    }
1579 1
    b = neg_128(a);
1580 1
    return pylong_from_int128(b);
1581
}
1582

1583

1584
static PyObject *
1585 1
extint_shl_128(PyObject *NPY_UNUSED(self), PyObject *args) {
1586
    PyObject *a_obj;
1587
    npy_extint128_t a, b;
1588 1
    if (!PyArg_ParseTuple(args, "O", &a_obj)) {
1589
        return NULL;
1590
    }
1591 1
    if (int128_from_pylong(a_obj, &a)) {
1592
        return NULL;
1593
    }
1594 1
    b = shl_128(a);
1595 1
    return pylong_from_int128(b);
1596
}
1597

1598

1599
static PyObject *
1600 1
extint_shr_128(PyObject *NPY_UNUSED(self), PyObject *args) {
1601
    PyObject *a_obj;
1602
    npy_extint128_t a, b;
1603 1
    if (!PyArg_ParseTuple(args, "O", &a_obj)) {
1604
        return NULL;
1605
    }
1606 1
    if (int128_from_pylong(a_obj, &a)) {
1607
        return NULL;
1608
    }
1609 1
    b = shr_128(a);
1610 1
    return pylong_from_int128(b);
1611
}
1612

1613

1614
static PyObject *
1615 1
extint_gt_128(PyObject *NPY_UNUSED(self), PyObject *args) {
1616
    PyObject *a_obj, *b_obj;
1617
    npy_extint128_t a, b;
1618 1
    if (!PyArg_ParseTuple(args, "OO", &a_obj, &b_obj)) {
1619
        return NULL;
1620
    }
1621 1
    if (int128_from_pylong(a_obj, &a) || int128_from_pylong(b_obj, &b)) {
1622
        return NULL;
1623
    }
1624 1
    if (gt_128(a, b)) {
1625 1
        Py_RETURN_TRUE;
1626
    }
1627
    else {
1628 1
        Py_RETURN_FALSE;
1629
    }
1630
}
1631

1632

1633
static PyObject *
1634 1
extint_divmod_128_64(PyObject *NPY_UNUSED(self), PyObject *args) {
1635 1
    PyObject *a_obj, *ret = NULL, *tmp = NULL;
1636
    npy_extint128_t a, c;
1637
    PY_LONG_LONG b;
1638
    npy_int64 mod;
1639 1
    if (!PyArg_ParseTuple(args, "OL", &a_obj, &b)) {
1640
        goto fail;
1641
    }
1642 1
    if (b <= 0) {
1643 0
        PyErr_SetString(PyExc_ValueError, "");
1644
        goto fail;
1645
    }
1646 1
    if (int128_from_pylong(a_obj, &a)) {
1647
        goto fail;
1648
    }
1649

1650 1
    c = divmod_128_64(a, b, &mod);
1651

1652 1
    ret = PyTuple_New(2);
1653

1654 1
    tmp = pylong_from_int128(c);
1655 1
    if (tmp == NULL) {
1656
        goto fail;
1657
    }
1658 1
    PyTuple_SET_ITEM(ret, 0, tmp);
1659

1660 1
    tmp = PyLong_FromLongLong(mod);
1661 1
    if (tmp == NULL) {
1662
        goto fail;
1663
    }
1664 1
    PyTuple_SET_ITEM(ret, 1, tmp);
1665 1
    return ret;
1666

1667 0
fail:
1668 0
    Py_XDECREF(ret);
1669 0
    Py_XDECREF(tmp);
1670
    return NULL;
1671
}
1672

1673

1674
static PyObject *
1675 1
extint_floordiv_128_64(PyObject *NPY_UNUSED(self), PyObject *args) {
1676
    PyObject *a_obj;
1677
    npy_extint128_t a, c;
1678
    PY_LONG_LONG b;
1679 1
    if (!PyArg_ParseTuple(args, "OL", &a_obj, &b)) {
1680
        return NULL;
1681
    }
1682 1
    if (b <= 0) {
1683 0
        PyErr_SetString(PyExc_ValueError, "");
1684 0
        return NULL;
1685
    }
1686 1
    if (int128_from_pylong(a_obj, &a)) {
1687
        return NULL;
1688
    }
1689 1
    c = floordiv_128_64(a, b);
1690 1
    return pylong_from_int128(c);
1691
}
1692

1693

1694
static PyObject *
1695 1
extint_ceildiv_128_64(PyObject *NPY_UNUSED(self), PyObject *args) {
1696
    PyObject *a_obj;
1697
    npy_extint128_t a, c;
1698
    PY_LONG_LONG b;
1699 1
    if (!PyArg_ParseTuple(args, "OL", &a_obj, &b)) {
1700
        return NULL;
1701
    }
1702 1
    if (b <= 0) {
1703 0
        PyErr_SetString(PyExc_ValueError, "");
1704 0
        return NULL;
1705
    }
1706 1
    if (int128_from_pylong(a_obj, &a)) {
1707
        return NULL;
1708
    }
1709 1
    c = ceildiv_128_64(a, b);
1710 1
    return pylong_from_int128(c);
1711
}
1712

1713
struct TestStruct1 {
1714
    npy_uint8 a;
1715
    npy_complex64 b;
1716
};
1717

1718
struct TestStruct2 {
1719
    npy_uint32 a;
1720
    npy_complex64 b;
1721
};
1722

1723
struct TestStruct3 {
1724
    npy_uint8 a;
1725
    struct TestStruct1 b;
1726
};
1727

1728
static PyObject *
1729 1
get_struct_alignments(PyObject *NPY_UNUSED(self), PyObject *args) {
1730 1
    PyObject *ret = PyTuple_New(3);
1731
    PyObject *alignment, *size, *val;
1732

1733
/**begin repeat
1734
 * #N = 1,2,3#
1735
 */
1736 1
    alignment = PyLong_FromLong(_ALIGN(struct TestStruct@N@));
1737 1
    size = PyLong_FromLong(sizeof(struct TestStruct@N@));
1738 1
    val = PyTuple_Pack(2, alignment, size);
1739 1
    Py_DECREF(alignment);
1740 1
    Py_DECREF(size);
1741 1
    if (val == NULL) {
1742
        return NULL;
1743
    }
1744 1
    PyTuple_SET_ITEM(ret, @N@-1, val);
1745
/**end repeat**/
1746 1
    return ret;
1747
}
1748

1749

1750
static char get_fpu_mode_doc[] = (
1751
    "get_fpu_mode()\n"
1752
    "\n"
1753
    "Get the current FPU control word, in a platform-dependent format.\n"
1754
    "Returns None if not implemented on current platform.");
1755

1756
static PyObject *
1757 1
get_fpu_mode(PyObject *NPY_UNUSED(self), PyObject *args)
1758
{
1759 1
    if (!PyArg_ParseTuple(args, "")) {
1760
        return NULL;
1761
    }
1762

1763
#if defined(_MSC_VER)
1764
    {
1765
        unsigned int result = 0;
1766
        result = _controlfp(0, 0);
1767
        return PyLong_FromLongLong(result);
1768
    }
1769
#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
1770
    {
1771 1
        unsigned short cw = 0;
1772 1
        __asm__("fstcw %w0" : "=m" (cw));
1773 1
        return PyLong_FromLongLong(cw);
1774
    }
1775
#else
1776
    Py_RETURN_NONE;
1777
#endif
1778
}
1779

1780
/*
1781
 * npymath wrappers
1782
 */
1783

1784
/**begin repeat
1785
 * #name = cabs, carg#
1786
 */
1787

1788
/**begin repeat1
1789
 * #itype = npy_cfloat, npy_cdouble, npy_clongdouble#
1790
 * #ITYPE = NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE#
1791
 * #otype = npy_float, npy_double, npy_longdouble#
1792
 * #OTYPE = NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE#
1793
 * #suffix= f, , l#
1794
 */
1795

1796
static PyObject *
1797 1
call_npy_@name@@suffix@(PyObject *NPY_UNUSED(self), PyObject *args)
1798
{
1799 1
    PyObject *z_py = NULL, *z_arr = NULL, *w_arr = NULL;
1800

1801 1
    if (!PyArg_ParseTuple(args, "O", &z_py)) {
1802
        return NULL;
1803
    }
1804

1805 1
    z_arr = PyArray_FROMANY(z_py, @ITYPE@, 0, 0, NPY_ARRAY_CARRAY_RO);
1806 1
    if (z_arr == NULL) {
1807
        return NULL;
1808
    }
1809

1810 1
    w_arr = PyArray_SimpleNew(0, NULL, @OTYPE@);
1811 1
    if (w_arr == NULL) {
1812 0
        Py_DECREF(z_arr);
1813
        return NULL;
1814
    }
1815

1816 1
    *(@otype@*)PyArray_DATA((PyArrayObject *)w_arr) =
1817 1
        npy_@name@@suffix@(*(@itype@*)PyArray_DATA((PyArrayObject *)z_arr));
1818

1819 1
    Py_DECREF(z_arr);
1820
    return w_arr;
1821
}
1822

1823
/**end repeat1**/
1824

1825
/**end repeat**/
1826

1827
/**begin repeat
1828
 * #name = log10, cosh, sinh, tan, tanh#
1829
 */
1830

1831
/**begin repeat1
1832
 * #type = npy_float, npy_double, npy_longdouble#
1833
 * #TYPE = NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE#
1834
 * #suffix= f, , l#
1835
 */
1836

1837
static PyObject *
1838 1
call_npy_@name@@suffix@(PyObject *NPY_UNUSED(self), PyObject *args)
1839
{
1840 1
    PyObject *z_py = NULL, *z_arr = NULL, *w_arr = NULL;
1841

1842 1
    if (!PyArg_ParseTuple(args, "O", &z_py)) {
1843
        return NULL;
1844
    }
1845

1846 1
    z_arr = PyArray_FROMANY(z_py, @TYPE@, 0, 0, NPY_ARRAY_CARRAY_RO);
1847 1
    if (z_arr == NULL) {
1848
        return NULL;
1849
    }
1850

1851 1
    w_arr = PyArray_SimpleNew(0, NULL, @TYPE@);
1852 1
    if (w_arr == NULL) {
1853 0
        Py_DECREF(z_arr);
1854
        return NULL;
1855
    }
1856

1857 1
    *(@type@*)PyArray_DATA((PyArrayObject *)w_arr) =
1858 1
        npy_@name@@suffix@(*(@type@*)PyArray_DATA((PyArrayObject *)z_arr));
1859

1860 1
    Py_DECREF(z_arr);
1861
    return w_arr;
1862
}
1863

1864
/**end repeat1**/
1865

1866
/**end repeat**/
1867

1868
/*
1869
 * For development/testing purposes, it's convenient to have access to the
1870
 * system printf for floats. This is a very simple printf interface.
1871
 */
1872
PyObject *
1873 0
PrintFloat_Printf_g(PyObject *obj, int precision)
1874
{
1875
    char str[1024];
1876

1877 0
    if (PyArray_IsScalar(obj, Half)) {
1878 0
        npy_half x = PyArrayScalar_VAL(obj, Half);
1879 0
        PyOS_snprintf(str, sizeof(str), "%.*g", precision,
1880
                      npy_half_to_double(x));
1881
    }
1882 0
    else if (PyArray_IsScalar(obj, Float)) {
1883 0
        npy_float x = PyArrayScalar_VAL(obj, Float);
1884 0
        PyOS_snprintf(str, sizeof(str), "%.*g", precision, x);
1885
    }
1886 0
    else if (PyArray_IsScalar(obj, Double)) {
1887 0
        npy_double x = PyArrayScalar_VAL(obj, Double);
1888 0
        PyOS_snprintf(str, sizeof(str), "%.*g", precision, x);
1889
        /* would be better to use lg, but not available in C90 */
1890
    }
1891 0
    else if (PyArray_IsScalar(obj, LongDouble)) {
1892 0
        npy_longdouble x = PyArrayScalar_VAL(obj, LongDouble);
1893 0
        PyOS_snprintf(str, sizeof(str), "%.*Lg", precision, x);
1894
    }
1895
    else{
1896 0
        double val = PyFloat_AsDouble(obj);
1897 0
        if (error_converting(val)) {
1898
            return NULL;
1899
        }
1900 0
        PyOS_snprintf(str, sizeof(str), "%.*g", precision, val);
1901
    }
1902

1903 0
    return PyUnicode_FromString(str);
1904
}
1905

1906

1907
static PyObject *
1908 0
printf_float_g(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds)
1909
{
1910
    PyObject *obj;
1911
    int precision;
1912

1913 0
    if (!PyArg_ParseTuple(args,"Oi:format_float_OSprintf_g", &obj,
1914
                                                             &precision)) {
1915
        return NULL;
1916
    }
1917

1918 0
    if (precision < 0) {
1919 0
        PyErr_SetString(PyExc_TypeError, "precision must be non-negative");
1920 0
        return NULL;
1921
    }
1922

1923 0
    return PrintFloat_Printf_g(obj, precision);
1924
}
1925

1926
static PyObject *
1927 1
getset_numericops(PyObject* NPY_UNUSED(self), PyObject* NPY_UNUSED(args))
1928
{
1929
    PyObject *ret;
1930 1
    PyObject *ops = PyArray_GetNumericOps();
1931 1
    if (ops == NULL) {
1932
        return NULL;
1933
    }
1934 1
    ret = PyLong_FromLong(PyArray_SetNumericOps(ops));
1935 1
    Py_DECREF(ops);
1936
    return ret;
1937
}
1938

1939
static PyObject *
1940 1
run_byteorder_converter(PyObject* NPY_UNUSED(self), PyObject *args)
1941
{
1942
    char byteorder;
1943 1
    if (!PyArg_ParseTuple(args, "O&", PyArray_ByteorderConverter, &byteorder)) {
1944
        return NULL;
1945
    }
1946 1
    switch (byteorder) {
1947 1
        case NPY_BIG: return PyUnicode_FromString("NPY_BIG");
1948 1
        case NPY_LITTLE: return PyUnicode_FromString("NPY_LITTLE");
1949 1
        case NPY_NATIVE: return PyUnicode_FromString("NPY_NATIVE");
1950 1
        case NPY_SWAP: return PyUnicode_FromString("NPY_SWAP");
1951 1
        case NPY_IGNORE: return PyUnicode_FromString("NPY_IGNORE");
1952
    }
1953 0
    return PyLong_FromLong(byteorder);
1954
}
1955

1956
static PyObject *
1957 1
run_sortkind_converter(PyObject* NPY_UNUSED(self), PyObject *args)
1958
{
1959
    NPY_SORTKIND kind;
1960 1
    if (!PyArg_ParseTuple(args, "O&", PyArray_SortkindConverter, &kind)) {
1961
        return NULL;
1962
    }
1963 1
    switch (kind) {
1964 1
        case NPY_QUICKSORT: return PyUnicode_FromString("NPY_QUICKSORT");
1965 1
        case NPY_HEAPSORT: return PyUnicode_FromString("NPY_HEAPSORT");
1966 1
        case NPY_STABLESORT: return PyUnicode_FromString("NPY_STABLESORT");
1967
    }
1968 0
    return PyLong_FromLong(kind);
1969
}
1970

1971
static PyObject *
1972 1
run_selectkind_converter(PyObject* NPY_UNUSED(self), PyObject *args)
1973
{
1974
    NPY_SELECTKIND kind;
1975 1
    if (!PyArg_ParseTuple(args, "O&", PyArray_SelectkindConverter, &kind)) {
1976
        return NULL;
1977
    }
1978 1
    switch (kind) {
1979 1
        case NPY_INTROSELECT: return PyUnicode_FromString("NPY_INTROSELECT");
1980
    }
1981 0
    return PyLong_FromLong(kind);
1982
}
1983

1984
static PyObject *
1985 1
run_searchside_converter(PyObject* NPY_UNUSED(self), PyObject *args)
1986
{
1987
    NPY_SEARCHSIDE side;
1988 1
    if (!PyArg_ParseTuple(args, "O&", PyArray_SearchsideConverter, &side)) {
1989
        return NULL;
1990
    }
1991 1
    switch (side) {
1992 1
        case NPY_SEARCHLEFT: return PyUnicode_FromString("NPY_SEARCHLEFT");
1993 1
        case NPY_SEARCHRIGHT: return PyUnicode_FromString("NPY_SEARCHRIGHT");
1994
    }
1995 0
    return PyLong_FromLong(side);
1996
}
1997

1998
static PyObject *
1999 1
run_order_converter(PyObject* NPY_UNUSED(self), PyObject *args)
2000
{
2001
    NPY_ORDER order;
2002 1
    if (!PyArg_ParseTuple(args, "O&", PyArray_OrderConverter, &order)) {
2003
        return NULL;
2004
    }
2005 1
    switch (order) {
2006 1
        case NPY_ANYORDER: return PyUnicode_FromString("NPY_ANYORDER");
2007 1
        case NPY_CORDER: return PyUnicode_FromString("NPY_CORDER");
2008 1
        case NPY_FORTRANORDER: return PyUnicode_FromString("NPY_FORTRANORDER");
2009 1
        case NPY_KEEPORDER: return PyUnicode_FromString("NPY_KEEPORDER");
2010
    }
2011 0
    return PyLong_FromLong(order);
2012
}
2013

2014
static PyObject *
2015 1
run_clipmode_converter(PyObject* NPY_UNUSED(self), PyObject *args)
2016
{
2017
    NPY_CLIPMODE mode;
2018 1
    if (!PyArg_ParseTuple(args, "O&", PyArray_ClipmodeConverter, &mode)) {
2019
        return NULL;
2020
    }
2021 1
    switch (mode) {
2022 1
        case NPY_CLIP: return PyUnicode_FromString("NPY_CLIP");
2023 1
        case NPY_WRAP: return PyUnicode_FromString("NPY_WRAP");
2024 1
        case NPY_RAISE: return PyUnicode_FromString("NPY_RAISE");
2025
    }
2026 0
    return PyLong_FromLong(mode);
2027
}
2028

2029
static PyObject *
2030 1
run_casting_converter(PyObject* NPY_UNUSED(self), PyObject *args)
2031
{
2032
    NPY_CASTING casting;
2033 1
    if (!PyArg_ParseTuple(args, "O&", PyArray_CastingConverter, &casting)) {
2034
        return NULL;
2035
    }
2036 1
    switch (casting) {
2037 1
        case NPY_NO_CASTING: return PyUnicode_FromString("NPY_NO_CASTING");
2038 1
        case NPY_EQUIV_CASTING: return PyUnicode_FromString("NPY_EQUIV_CASTING");
2039 1
        case NPY_SAFE_CASTING: return PyUnicode_FromString("NPY_SAFE_CASTING");
2040 1
        case NPY_SAME_KIND_CASTING: return PyUnicode_FromString("NPY_SAME_KIND_CASTING");
2041 1
        case NPY_UNSAFE_CASTING: return PyUnicode_FromString("NPY_UNSAFE_CASTING");
2042
    }
2043 0
    return PyLong_FromLong(casting);
2044
}
2045

2046
static PyObject *
2047 1
run_intp_converter(PyObject* NPY_UNUSED(self), PyObject *args)
2048
{
2049 1
    PyArray_Dims dims = {NULL, -1};
2050 1
    if (!PyArg_ParseTuple(args, "O&", PyArray_IntpConverter, &dims)) {
2051
        return NULL;
2052
    }
2053 1
    if (dims.len == -1) {
2054 0
        Py_RETURN_NONE;
2055
    }
2056

2057 1
    PyObject *tup = PyArray_IntTupleFromIntp(dims.len, dims.ptr);
2058 1
    PyDimMem_FREE(dims.ptr);
2059 1
    return tup;
2060
}
2061

2062
static PyMethodDef Multiarray_TestsMethods[] = {
2063
    {"IsPythonScalar",
2064
        IsPythonScalar,
2065
        METH_VARARGS, NULL},
2066
    {"test_neighborhood_iterator",
2067
        test_neighborhood_iterator,
2068
        METH_VARARGS, NULL},
2069
    {"test_neighborhood_iterator_oob",
2070
        test_neighborhood_iterator_oob,
2071
        METH_VARARGS, NULL},
2072
    {"test_pydatamem_seteventhook_start",
2073
        test_pydatamem_seteventhook_start,
2074
        METH_NOARGS, NULL},
2075
    {"test_pydatamem_seteventhook_end",
2076
        test_pydatamem_seteventhook_end,
2077
        METH_NOARGS, NULL},
2078
    {"test_inplace_increment",
2079
        inplace_increment,
2080
        METH_VARARGS, NULL},
2081
    {"fromstring_null_term_c_api",
2082
        fromstring_null_term_c_api,
2083
        METH_O, NULL},
2084
    {"incref_elide",
2085
        incref_elide,
2086
        METH_VARARGS, NULL},
2087
    {"incref_elide_l",
2088
        incref_elide_l,
2089
        METH_VARARGS, NULL},
2090
    {"npy_char_deprecation",
2091
        npy_char_deprecation,
2092
        METH_NOARGS, NULL},
2093
    {"npy_updateifcopy_deprecation",
2094
        npy_updateifcopy_deprecation,
2095
        METH_O, NULL},
2096
    {"npy_pyarrayas1d_deprecation",
2097
        npy_pyarrayas1d_deprecation,
2098
        METH_NOARGS, NULL},
2099
    {"npy_pyarrayas2d_deprecation",
2100
        npy_pyarrayas2d_deprecation,
2101
        METH_NOARGS, NULL},
2102
    {"npy_create_writebackifcopy",
2103
        npy_create_writebackifcopy,
2104
        METH_O, NULL},
2105
    {"npy_abuse_writebackifcopy",
2106
        npy_abuse_writebackifcopy,
2107
        METH_O, NULL},
2108
    {"npy_resolve",
2109
        npy_resolve,
2110
        METH_O, NULL},
2111
    {"npy_discard",
2112
        npy_discard,
2113
        METH_O, NULL},
2114
    {"get_buffer_info",
2115
        get_buffer_info,
2116
        METH_VARARGS, NULL},
2117
    {"get_c_wrapping_array",
2118
        get_c_wrapping_array,
2119
        METH_O, NULL},
2120
    {"array_indexing",
2121
        array_indexing,
2122
        METH_VARARGS, NULL},
2123
    {"test_as_c_array",
2124
        test_as_c_array,
2125
        METH_VARARGS, NULL},
2126
    {"test_nditer_too_large",
2127
        test_nditer_too_large,
2128
        METH_VARARGS, NULL},
2129
    {"solve_diophantine",
2130
        (PyCFunction)array_solve_diophantine,
2131
        METH_VARARGS | METH_KEYWORDS, NULL},
2132
    {"internal_overlap",
2133
        (PyCFunction)array_internal_overlap,
2134
        METH_VARARGS | METH_KEYWORDS, NULL},
2135
    {"extint_safe_binop",
2136
        extint_safe_binop,
2137
        METH_VARARGS, NULL},
2138
    {"extint_to_128",
2139
        extint_to_128,
2140
        METH_VARARGS, NULL},
2141
    {"extint_to_64",
2142
        extint_to_64,
2143
        METH_VARARGS, NULL},
2144
    {"extint_mul_64_64",
2145
        extint_mul_64_64,
2146
        METH_VARARGS, NULL},
2147
    {"extint_add_128",
2148
        extint_add_128,
2149
        METH_VARARGS, NULL},
2150
    {"extint_sub_128",
2151
        extint_sub_128,
2152
        METH_VARARGS, NULL},
2153
    {"extint_neg_128",
2154
        extint_neg_128,
2155
        METH_VARARGS, NULL},
2156
    {"extint_shl_128",
2157
        extint_shl_128,
2158
        METH_VARARGS, NULL},
2159
    {"extint_shr_128",
2160
        extint_shr_128,
2161
        METH_VARARGS, NULL},
2162
    {"extint_gt_128",
2163
        extint_gt_128,
2164
        METH_VARARGS, NULL},
2165
    {"extint_divmod_128_64",
2166
        extint_divmod_128_64,
2167
        METH_VARARGS, NULL},
2168
    {"extint_floordiv_128_64",
2169
        extint_floordiv_128_64,
2170
        METH_VARARGS, NULL},
2171
    {"extint_ceildiv_128_64",
2172
        extint_ceildiv_128_64,
2173
        METH_VARARGS, NULL},
2174
    {"get_fpu_mode",
2175
        get_fpu_mode,
2176
        METH_VARARGS, get_fpu_mode_doc},
2177
    {"getset_numericops",
2178
        getset_numericops,
2179
        METH_NOARGS, NULL},
2180
/**begin repeat
2181
 * #name = cabs, carg#
2182
 */
2183

2184
/**begin repeat1
2185
 * #suffix = f, , l#
2186
 */
2187
    {"npy_@name@@suffix@",
2188
        call_npy_@name@@suffix@,
2189
        METH_VARARGS, NULL},
2190
/**end repeat1**/
2191

2192
/**end repeat**/
2193

2194
/**begin repeat
2195
 * #name = log10, cosh, sinh, tan, tanh#
2196
 */
2197

2198
/**begin repeat1
2199
 * #suffix= f, , l#
2200
 */
2201
    {"npy_@name@@suffix@",
2202
        call_npy_@name@@suffix@,
2203
        METH_VARARGS, NULL},
2204
/**end repeat1**/
2205

2206
/**end repeat**/
2207
    {"format_float_OSprintf_g",
2208
        (PyCFunction)printf_float_g,
2209
        METH_VARARGS , NULL},
2210
    {"get_struct_alignments",
2211
        get_struct_alignments,
2212
        METH_VARARGS, NULL},
2213
    {"run_byteorder_converter",
2214
        run_byteorder_converter,
2215
        METH_VARARGS, NULL},
2216
    {"run_sortkind_converter",
2217
        run_sortkind_converter,
2218
        METH_VARARGS, NULL},
2219
    {"run_selectkind_converter",
2220
        run_selectkind_converter,
2221
        METH_VARARGS, NULL},
2222
    {"run_searchside_converter",
2223
        run_searchside_converter,
2224
        METH_VARARGS, NULL},
2225
    {"run_order_converter",
2226
        run_order_converter,
2227
        METH_VARARGS, NULL},
2228
    {"run_clipmode_converter",
2229
        run_clipmode_converter,
2230
        METH_VARARGS, NULL},
2231
    {"run_casting_converter",
2232
        run_casting_converter,
2233
        METH_VARARGS, NULL},
2234
    {"run_intp_converter",
2235
        run_intp_converter,
2236
        METH_VARARGS, NULL},
2237
    {NULL, NULL, 0, NULL}        /* Sentinel */
2238
};
2239

2240

2241
static struct PyModuleDef moduledef = {
2242
        PyModuleDef_HEAD_INIT,
2243
        "_multiarray_tests",
2244
        NULL,
2245
        -1,
2246
        Multiarray_TestsMethods,
2247
        NULL,
2248
        NULL,
2249
        NULL,
2250
        NULL
2251
};
2252

2253 1
PyMODINIT_FUNC PyInit__multiarray_tests(void)
2254
{
2255
    PyObject *m;
2256

2257 1
    m = PyModule_Create(&moduledef);
2258 1
    if (m == NULL) {
2259
        return m;
2260
    }
2261 1
    import_array();
2262 1
    if (PyErr_Occurred()) {
2263 0
        PyErr_SetString(PyExc_RuntimeError,
2264
                        "cannot load _multiarray_tests module.");
2265
    }
2266
    return m;
2267
}
2268

2269
NPY_NO_EXPORT int
2270 0
test_not_exported(void)
2271
{
2272 0
    return 1;
2273
}

Read our documentation on viewing source code .

Loading