#line 1 "numpy/core/src/multiarray/scalartypes.c.src"

/*
 *****************************************************************************
 **       This file was autogenerated from a template  DO NOT EDIT!!!!      **
 **       Changes should be made to the original source (.src) file         **
 *****************************************************************************
 */

#line 1
/* -*- c -*- */
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>

#define NPY_NO_DEPRECATED_API NPY_API_VERSION
#ifndef _MULTIARRAYMODULE
#define _MULTIARRAYMODULE
#endif

#include "numpy/arrayobject.h"
#include "numpy/npy_math.h"
#include "numpy/halffloat.h"
#include "numpy/arrayscalars.h"

#include "npy_pycompat.h"

#include "arraytypes.h"
#include "npy_config.h"
#include "mapping.h"
#include "ctors.h"
#include "usertypes.h"
#include "numpyos.h"
#include "can_cast_table.h"
#include "common.h"
#include "scalartypes.h"
#include "_datetime.h"
#include "datetime_strings.h"
#include "alloc.h"
#include "npy_import.h"
#include "dragon4.h"
#include "npy_longdouble.h"
#include "npy_buffer.h"

#include <stdlib.h>

#include "binop_override.h"

/*
 * used for allocating a single scalar, so use the default numpy
 * memory allocators instead of the (maybe) user overrides
 */
NPY_NO_EXPORT void *
npy_alloc_cache_zero(size_t nmemb, size_t size);

NPY_NO_EXPORT void
npy_free_cache(void * p, npy_uintp sz);

NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[] = {
    {PyObject_HEAD_INIT(&PyBoolArrType_Type) 0},
    {PyObject_HEAD_INIT(&PyBoolArrType_Type) 1},
};

/* TimeInteger is deleted, but still here to fill the API slot */
NPY_NO_EXPORT PyTypeObject PyTimeIntegerArrType_Type;

/*
 * Inheritance is established later when tp_bases is set (or tp_base for
 * single inheritance)
 */

#line 68
NPY_NO_EXPORT PyTypeObject PyNumberArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy.number",
    .tp_basicsize = sizeof(PyObject),
};

#line 68
NPY_NO_EXPORT PyTypeObject PyIntegerArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy.integer",
    .tp_basicsize = sizeof(PyObject),
};

#line 68
NPY_NO_EXPORT PyTypeObject PySignedIntegerArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy.signedinteger",
    .tp_basicsize = sizeof(PyObject),
};

#line 68
NPY_NO_EXPORT PyTypeObject PyUnsignedIntegerArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy.unsignedinteger",
    .tp_basicsize = sizeof(PyObject),
};

#line 68
NPY_NO_EXPORT PyTypeObject PyInexactArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy.inexact",
    .tp_basicsize = sizeof(PyObject),
};

#line 68
NPY_NO_EXPORT PyTypeObject PyFloatingArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy.floating",
    .tp_basicsize = sizeof(PyObject),
};

#line 68
NPY_NO_EXPORT PyTypeObject PyComplexFloatingArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy.complexfloating",
    .tp_basicsize = sizeof(PyObject),
};

#line 68
NPY_NO_EXPORT PyTypeObject PyFlexibleArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy.flexible",
    .tp_basicsize = sizeof(PyObject),
};

#line 68
NPY_NO_EXPORT PyTypeObject PyCharacterArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy.character",
    .tp_basicsize = sizeof(PyObject),
};


static PyObject *
gentype_alloc(PyTypeObject *type, Py_ssize_t nitems)
{
    PyObject *obj;
    const size_t size = _PyObject_VAR_SIZE(type, nitems + 1);

    obj = (PyObject *)PyObject_Malloc(size);
    if (obj == NULL) {
        PyErr_NoMemory();
        return NULL;
    }
    /*
     * If we don't need to zero memory, we could use
     * PyObject_{New, NewVar} for this whole function.
     */
    memset(obj, 0, size);
    if (type->tp_itemsize == 0) {
        PyObject_Init(obj, type);
    }
    else {
        (void) PyObject_InitVar((PyVarObject *)obj, type, nitems);
    }
    return obj;
}

static void
gentype_dealloc(PyObject *v)
{
    Py_TYPE(v)->tp_free(v);
}

static void
gentype_free(PyObject *v)
{
    /*
     * have an explicit tp_free to enforce inheritance from it.
     * PyObject_Free is also the tp_free of PyBaseObject so python does not
     * COPYSLOT it, instead it takes the next parent PyInt which has a
     * different allocator
     */
    PyObject_Free(v);
}


static PyObject *
gentype_power(PyObject *m1, PyObject *m2, PyObject *modulo)
{
    if (modulo != Py_None) {
        /* modular exponentiation is not implemented (gh-8804) */
        Py_INCREF(Py_NotImplemented);
        return Py_NotImplemented;
    }

    BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_power, gentype_power);
    return PyArray_Type.tp_as_number->nb_power(m1, m2, Py_None);
}

static PyObject *
gentype_generic_method(PyObject *self, PyObject *args, PyObject *kwds,
        char *str)
{
    PyObject *arr, *meth, *ret;

    arr = PyArray_FromScalar(self, NULL);
    if (arr == NULL) {
        return NULL;
    }
    meth = PyObject_GetAttrString(arr, str);
    if (meth == NULL) {
        Py_DECREF(arr);
        return NULL;
    }
    if (kwds == NULL) {
        ret = PyObject_CallObject(meth, args);
    }
    else {
        ret = PyObject_Call(meth, args, kwds);
    }
    Py_DECREF(meth);
    Py_DECREF(arr);
    if (ret && PyArray_Check(ret)) {
        return PyArray_Return((PyArrayObject *)ret);
    }
    else {
        return ret;
    }
}

static PyObject *
gentype_add(PyObject *m1, PyObject* m2)
{
    /* special case str.__radd__, which should not call array_add */
    if (PyBytes_Check(m1) || PyUnicode_Check(m1)) {
        Py_INCREF(Py_NotImplemented);
        return Py_NotImplemented;
    }
    BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_add, gentype_add);
    return PyArray_Type.tp_as_number->nb_add(m1, m2);
}

#line 180
static PyObject *
gentype_subtract(PyObject *m1, PyObject *m2)
{
    BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_subtract, gentype_subtract);
    return PyArray_Type.tp_as_number->nb_subtract(m1, m2);
}


#line 180
static PyObject *
gentype_remainder(PyObject *m1, PyObject *m2)
{
    BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_remainder, gentype_remainder);
    return PyArray_Type.tp_as_number->nb_remainder(m1, m2);
}


#line 180
static PyObject *
gentype_divmod(PyObject *m1, PyObject *m2)
{
    BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_divmod, gentype_divmod);
    return PyArray_Type.tp_as_number->nb_divmod(m1, m2);
}


#line 180
static PyObject *
gentype_lshift(PyObject *m1, PyObject *m2)
{
    BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_lshift, gentype_lshift);
    return PyArray_Type.tp_as_number->nb_lshift(m1, m2);
}


#line 180
static PyObject *
gentype_rshift(PyObject *m1, PyObject *m2)
{
    BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_rshift, gentype_rshift);
    return PyArray_Type.tp_as_number->nb_rshift(m1, m2);
}


#line 180
static PyObject *
gentype_and(PyObject *m1, PyObject *m2)
{
    BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_and, gentype_and);
    return PyArray_Type.tp_as_number->nb_and(m1, m2);
}


#line 180
static PyObject *
gentype_xor(PyObject *m1, PyObject *m2)
{
    BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_xor, gentype_xor);
    return PyArray_Type.tp_as_number->nb_xor(m1, m2);
}


#line 180
static PyObject *
gentype_or(PyObject *m1, PyObject *m2)
{
    BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_or, gentype_or);
    return PyArray_Type.tp_as_number->nb_or(m1, m2);
}


#line 180
static PyObject *
gentype_floor_divide(PyObject *m1, PyObject *m2)
{
    BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_floor_divide, gentype_floor_divide);
    return PyArray_Type.tp_as_number->nb_floor_divide(m1, m2);
}


#line 180
static PyObject *
gentype_true_divide(PyObject *m1, PyObject *m2)
{
    BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_true_divide, gentype_true_divide);
    return PyArray_Type.tp_as_number->nb_true_divide(m1, m2);
}



/* Get a nested slot, or NULL if absent */
#define GET_NESTED_SLOT(type, group, slot) \
    ((type)->group == NULL ? NULL : (type)->group->slot)

static PyObject *
gentype_multiply(PyObject *m1, PyObject *m2)
{
    /*
     * If the other object supports sequence repeat and not number multiply
     * we fall back on the python builtin to invoke the sequence repeat, rather
     * than promoting both arguments to ndarray.
     * This covers a list repeat by numpy scalars.
     * A python defined class will always only have the nb_multiply slot and
     * some classes may have neither defined. For the latter we want need
     * to give the normal case a chance to convert the object to ndarray.
     * Probably no class has both defined, but if they do, prefer number.
     */
    if (!PyArray_IsScalar(m1, Generic) &&
            GET_NESTED_SLOT(Py_TYPE(m1), tp_as_sequence, sq_repeat) != NULL &&
            GET_NESTED_SLOT(Py_TYPE(m1), tp_as_number, nb_multiply) == NULL) {
        Py_INCREF(Py_NotImplemented);
        return Py_NotImplemented;
    }
    if (!PyArray_IsScalar(m2, Generic) &&
            GET_NESTED_SLOT(Py_TYPE(m2), tp_as_sequence, sq_repeat) != NULL &&
            GET_NESTED_SLOT(Py_TYPE(m2), tp_as_number, nb_multiply) == NULL) {
        Py_INCREF(Py_NotImplemented);
        return Py_NotImplemented;
    }
    /* All normal cases are handled by PyArray's multiply */
    BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_multiply, gentype_multiply);
    return PyArray_Type.tp_as_number->nb_multiply(m1, m2);
}

#line 233
static PyObject *
npy_byte_bit_count(PyObject *self, PyObject *NPY_UNUSED(args))
{
    npy_byte scalar = PyArrayScalar_VAL(self, Byte);
    uint8_t count = npy_popcounthh(scalar);
    PyObject *result = PyLong_FromLong(count);

    return result;
}

#line 233
static PyObject *
npy_ubyte_bit_count(PyObject *self, PyObject *NPY_UNUSED(args))
{
    npy_ubyte scalar = PyArrayScalar_VAL(self, UByte);
    uint8_t count = npy_popcountuhh(scalar);
    PyObject *result = PyLong_FromLong(count);

    return result;
}

#line 233
static PyObject *
npy_short_bit_count(PyObject *self, PyObject *NPY_UNUSED(args))
{
    npy_short scalar = PyArrayScalar_VAL(self, Short);
    uint8_t count = npy_popcounth(scalar);
    PyObject *result = PyLong_FromLong(count);

    return result;
}

#line 233
static PyObject *
npy_ushort_bit_count(PyObject *self, PyObject *NPY_UNUSED(args))
{
    npy_ushort scalar = PyArrayScalar_VAL(self, UShort);
    uint8_t count = npy_popcountuh(scalar);
    PyObject *result = PyLong_FromLong(count);

    return result;
}

#line 233
static PyObject *
npy_int_bit_count(PyObject *self, PyObject *NPY_UNUSED(args))
{
    npy_int scalar = PyArrayScalar_VAL(self, Int);
    uint8_t count = npy_popcount(scalar);
    PyObject *result = PyLong_FromLong(count);

    return result;
}

#line 233
static PyObject *
npy_uint_bit_count(PyObject *self, PyObject *NPY_UNUSED(args))
{
    npy_uint scalar = PyArrayScalar_VAL(self, UInt);
    uint8_t count = npy_popcountu(scalar);
    PyObject *result = PyLong_FromLong(count);

    return result;
}

#line 233
static PyObject *
npy_long_bit_count(PyObject *self, PyObject *NPY_UNUSED(args))
{
    npy_long scalar = PyArrayScalar_VAL(self, Long);
    uint8_t count = npy_popcountl(scalar);
    PyObject *result = PyLong_FromLong(count);

    return result;
}

#line 233
static PyObject *
npy_ulong_bit_count(PyObject *self, PyObject *NPY_UNUSED(args))
{
    npy_ulong scalar = PyArrayScalar_VAL(self, ULong);
    uint8_t count = npy_popcountul(scalar);
    PyObject *result = PyLong_FromLong(count);

    return result;
}

#line 233
static PyObject *
npy_longlong_bit_count(PyObject *self, PyObject *NPY_UNUSED(args))
{
    npy_longlong scalar = PyArrayScalar_VAL(self, LongLong);
    uint8_t count = npy_popcountll(scalar);
    PyObject *result = PyLong_FromLongLong(count);

    return result;
}

#line 233
static PyObject *
npy_ulonglong_bit_count(PyObject *self, PyObject *NPY_UNUSED(args))
{
    npy_ulonglong scalar = PyArrayScalar_VAL(self, ULongLong);
    uint8_t count = npy_popcountull(scalar);
    PyObject *result = PyLong_FromLongLong(count);

    return result;
}


#line 248
static PyObject *
gentype_positive(PyObject *m1)
{
    PyObject *arr, *ret;

    arr = PyArray_FromScalar(m1, NULL);
    if (arr == NULL) {
        return NULL;
    }
    ret = Py_TYPE(arr)->tp_as_number->nb_positive(arr);
    Py_DECREF(arr);
    return ret;
}

#line 248
static PyObject *
gentype_negative(PyObject *m1)
{
    PyObject *arr, *ret;

    arr = PyArray_FromScalar(m1, NULL);
    if (arr == NULL) {
        return NULL;
    }
    ret = Py_TYPE(arr)->tp_as_number->nb_negative(arr);
    Py_DECREF(arr);
    return ret;
}

#line 248
static PyObject *
gentype_absolute(PyObject *m1)
{
    PyObject *arr, *ret;

    arr = PyArray_FromScalar(m1, NULL);
    if (arr == NULL) {
        return NULL;
    }
    ret = Py_TYPE(arr)->tp_as_number->nb_absolute(arr);
    Py_DECREF(arr);
    return ret;
}

#line 248
static PyObject *
gentype_invert(PyObject *m1)
{
    PyObject *arr, *ret;

    arr = PyArray_FromScalar(m1, NULL);
    if (arr == NULL) {
        return NULL;
    }
    ret = Py_TYPE(arr)->tp_as_number->nb_invert(arr);
    Py_DECREF(arr);
    return ret;
}

#line 248
static PyObject *
gentype_int(PyObject *m1)
{
    PyObject *arr, *ret;

    arr = PyArray_FromScalar(m1, NULL);
    if (arr == NULL) {
        return NULL;
    }
    ret = Py_TYPE(arr)->tp_as_number->nb_int(arr);
    Py_DECREF(arr);
    return ret;
}

#line 248
static PyObject *
gentype_float(PyObject *m1)
{
    PyObject *arr, *ret;

    arr = PyArray_FromScalar(m1, NULL);
    if (arr == NULL) {
        return NULL;
    }
    ret = Py_TYPE(arr)->tp_as_number->nb_float(arr);
    Py_DECREF(arr);
    return ret;
}


static int
gentype_nonzero_number(PyObject *m1)
{
    PyObject *arr;
    int ret;

    arr = PyArray_FromScalar(m1, NULL);
    if (arr == NULL) {
        return -1;
    }
    ret = Py_TYPE(arr)->tp_as_number->nb_bool(arr);
    Py_DECREF(arr);
    return ret;
}

static PyObject *
genint_type_str(PyObject *self)
{
    PyObject  *item, *item_str;
    PyArray_Descr *descr = PyArray_DescrFromTypeObject((PyObject *)Py_TYPE(self));
    void *val = scalar_value(self, descr);
    switch (descr->type_num) {
        case NPY_BYTE:
            item = PyLong_FromLong(*(npy_byte *)val);
            break;
        case NPY_UBYTE:
            item = PyLong_FromUnsignedLong(*(npy_ubyte *)val);
            break;
        case NPY_SHORT:
            item = PyLong_FromLong(*(npy_short *)val);
            break;
        case NPY_USHORT:
            item = PyLong_FromUnsignedLong(*(npy_ushort *)val);
            break;
        case NPY_INT:
            item = PyLong_FromLong(*(npy_int *)val);
            break;
        case NPY_UINT:
            item = PyLong_FromUnsignedLong(*(npy_uint *)val);
            break;
        case NPY_LONG:
            item = PyLong_FromLong(*(npy_long *)val);
            break;
        case NPY_ULONG:
            item = PyLong_FromUnsignedLong(*(npy_ulong *)val);
            break;
        case NPY_LONGLONG:
            item = PyLong_FromLongLong(*(npy_longlong *)val);
            break;
        case NPY_ULONGLONG:
            item = PyLong_FromUnsignedLongLong(*(npy_ulonglong *)val);
            break;
        default:
            item = gentype_generic_method(self, NULL, NULL, "item");
            break;
    }
    Py_DECREF(descr);
    if (item == NULL) {
        return NULL;
    }

    item_str = PyObject_Str(item);
    Py_DECREF(item);
    return item_str;
}

/*
 * The __format__ method for PEP 3101.
 */
static PyObject *
gentype_format(PyObject *self, PyObject *args)
{
    PyObject *format_spec;
    PyObject *obj, *ret;

    if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) {
        return NULL;
    }

    /*
     * Convert to an appropriate Python type and call its format.
     * TODO: For some types, like long double, this isn't right,
     *       because it throws away precision.
     */
    if (Py_TYPE(self) == &PyBoolArrType_Type) {
        obj = PyBool_FromLong(PyArrayScalar_VAL(self, Bool));
    }
    else if (PyArray_IsScalar(self, Integer)
             && !PyArray_IsScalar(self, Timedelta)) {
        obj = Py_TYPE(self)->tp_as_number->nb_int(self);
    }
    else if (PyArray_IsScalar(self, Floating)) {
        obj = Py_TYPE(self)->tp_as_number->nb_float(self);
    }
    else if (PyArray_IsScalar(self, ComplexFloating)) {
        double val[2];
        PyArray_Descr *dtype = PyArray_DescrFromScalar(self);

        if (dtype == NULL) {
            return NULL;
        }
        if (PyArray_CastScalarDirect(self, dtype, &val[0], NPY_CDOUBLE) < 0) {
            Py_DECREF(dtype);
            return NULL;
        }
        obj = PyComplex_FromDoubles(val[0], val[1]);
        Py_DECREF(dtype);
    }
    else {
        obj = PyObject_Str(self);
    }

    if (obj == NULL) {
        return NULL;
    }

    ret = PyObject_Format(obj, format_spec);
    Py_DECREF(obj);
    return ret;
}

#ifdef FORCE_NO_LONG_DOUBLE_FORMATTING
#undef NPY_LONGDOUBLE_FMT
#define NPY_LONGDOUBLE_FMT NPY_DOUBLE_FMT
#endif

#line 396

NPY_NO_EXPORT PyObject *
format_half(npy_half val, npy_bool scientific,
              int precision, int sign, TrimMode trim,
              int pad_left, int pad_right, int exp_digits)
{
    if (scientific) {
        return Dragon4_Scientific_Half(&val,
                        DigitMode_Unique, precision, -1,
                        sign, trim, pad_left, exp_digits);
    }
    else {
        return Dragon4_Positional_Half(&val,
                        DigitMode_Unique, CutoffMode_TotalLength, precision,
                        -1, sign, trim, pad_left, pad_right);
    }
}



#line 396

NPY_NO_EXPORT PyObject *
format_float(npy_float val, npy_bool scientific,
              int precision, int sign, TrimMode trim,
              int pad_left, int pad_right, int exp_digits)
{
    if (scientific) {
        return Dragon4_Scientific_Float(&val,
                        DigitMode_Unique, precision, -1,
                        sign, trim, pad_left, exp_digits);
    }
    else {
        return Dragon4_Positional_Float(&val,
                        DigitMode_Unique, CutoffMode_TotalLength, precision,
                        -1, sign, trim, pad_left, pad_right);
    }
}



#line 396

NPY_NO_EXPORT PyObject *
format_double(npy_double val, npy_bool scientific,
              int precision, int sign, TrimMode trim,
              int pad_left, int pad_right, int exp_digits)
{
    if (scientific) {
        return Dragon4_Scientific_Double(&val,
                        DigitMode_Unique, precision, -1,
                        sign, trim, pad_left, exp_digits);
    }
    else {
        return Dragon4_Positional_Double(&val,
                        DigitMode_Unique, CutoffMode_TotalLength, precision,
                        -1, sign, trim, pad_left, pad_right);
    }
}



#line 396

NPY_NO_EXPORT PyObject *
format_longdouble(npy_longdouble val, npy_bool scientific,
              int precision, int sign, TrimMode trim,
              int pad_left, int pad_right, int exp_digits)
{
    if (scientific) {
        return Dragon4_Scientific_LongDouble(&val,
                        DigitMode_Unique, precision, -1,
                        sign, trim, pad_left, exp_digits);
    }
    else {
        return Dragon4_Positional_LongDouble(&val,
                        DigitMode_Unique, CutoffMode_TotalLength, precision,
                        -1, sign, trim, pad_left, pad_right);
    }
}




/*
 * Over-ride repr and str of array-scalar byte strings to remove NULL bytes and
 * then call the corresponding functions of PyBytes_Type to generate the string
 */

#line 425
static PyObject *
stringtype_repr(PyObject *self)
{
    const npy_char *dptr, *ip;
    Py_ssize_t len;
    PyObject *new;
    PyObject *ret;

    ip = PyBytes_AS_STRING(self);
    len = PyBytes_GET_SIZE(self);
    for(dptr = ip + len - 1; len > 0 && *dptr == 0; len--, dptr--);
    new = PyBytes_FromStringAndSize(ip, len);
    if (new == NULL) {
        return NULL;
    }
    ret = PyBytes_Type.tp_repr(new);
    Py_DECREF(new);
    return ret;
}

#line 425
static PyObject *
stringtype_str(PyObject *self)
{
    const npy_char *dptr, *ip;
    Py_ssize_t len;
    PyObject *new;
    PyObject *ret;

    ip = PyBytes_AS_STRING(self);
    len = PyBytes_GET_SIZE(self);
    for(dptr = ip + len - 1; len > 0 && *dptr == 0; len--, dptr--);
    new = PyBytes_FromStringAndSize(ip, len);
    if (new == NULL) {
        return NULL;
    }
    ret = PyBytes_Type.tp_str(new);
    Py_DECREF(new);
    return ret;
}


/*
 * Over-ride repr and str of array-scalar strings to remove NULL code points and
 * then call the corresponding functions of PyUnicode_Type to generate the string
 */

#line 454
static PyObject *
unicodetype_repr(PyObject *self)
{
    Py_UCS4 *dptr, *ip;
    Py_ssize_t len;
    PyObject *new;
    PyObject *ret;

    /* PyUnicode_READY is called by PyUnicode_GetLength */
    len = PyUnicode_GetLength(self);
    ip = PyUnicode_AsUCS4Copy(self);
    if (ip == NULL) {
        return NULL;
    }
    for(dptr = ip + len - 1; len > 0 && *dptr == 0; len--, dptr--);
    new = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, ip, len);
    if (new == NULL) {
        PyMem_Free(ip);
        return NULL;
    }
    ret = PyUnicode_Type.tp_repr(new);
    Py_DECREF(new);
    PyMem_Free(ip);
    return ret;
}

#line 454
static PyObject *
unicodetype_str(PyObject *self)
{
    Py_UCS4 *dptr, *ip;
    Py_ssize_t len;
    PyObject *new;
    PyObject *ret;

    /* PyUnicode_READY is called by PyUnicode_GetLength */
    len = PyUnicode_GetLength(self);
    ip = PyUnicode_AsUCS4Copy(self);
    if (ip == NULL) {
        return NULL;
    }
    for(dptr = ip + len - 1; len > 0 && *dptr == 0; len--, dptr--);
    new = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, ip, len);
    if (new == NULL) {
        PyMem_Free(ip);
        return NULL;
    }
    ret = PyUnicode_Type.tp_str(new);
    Py_DECREF(new);
    PyMem_Free(ip);
    return ret;
}


/*
 * Convert array of bytes to a string representation much like bytes.__repr__,
 * but convert all bytes (including ASCII) to the `\x00` notation with
 * uppercase hex codes (FF not ff).
 *
 * Largely copied from _Py_strhex_impl in CPython implementation
 */
static inline PyObject *
_void_to_hex(const char* argbuf, const Py_ssize_t arglen,
             const char *schars, const char *bprefix, const char *echars)
{
    PyObject *retval;
    int extrachars, slen;
    char *retbuf;
    Py_ssize_t i, j;
    char const *hexdigits = "0123456789ABCDEF";

    extrachars = strlen(schars) + strlen(echars);
    slen = extrachars + arglen*(2 + strlen(bprefix));

    if (arglen > (PY_SSIZE_T_MAX / 2) - extrachars) {
        return PyErr_NoMemory();
    }

    retbuf = (char *)PyMem_Malloc(slen);
    if (!retbuf) {
        return PyErr_NoMemory();
    }

    memcpy(retbuf, schars, strlen(schars));
    j = strlen(schars);

    for (i = 0; i < arglen; i++) {
        unsigned char c;
        memcpy(&retbuf[j], bprefix, strlen(bprefix));
        j += strlen(bprefix);
        c = (argbuf[i] >> 4) & 0xf;
        retbuf[j++] = hexdigits[c];
        c = argbuf[i] & 0xf;
        retbuf[j++] = hexdigits[c];
    }
    memcpy(&retbuf[j], echars, strlen(echars));

    retval = PyUnicode_FromStringAndSize(retbuf, slen);
    PyMem_Free(retbuf);

    return retval;
}

static PyObject *
_void_scalar_repr(PyObject *obj) {
    static PyObject *reprfunc = NULL;
    npy_cache_import("numpy.core.arrayprint",
                     "_void_scalar_repr", &reprfunc);
    if (reprfunc == NULL) {
        return NULL;
    }
    return PyObject_CallFunction(reprfunc, "O", obj);
}

static PyObject *
voidtype_repr(PyObject *self)
{
    PyVoidScalarObject *s = (PyVoidScalarObject*) self;
    if (PyDataType_HASFIELDS(s->descr)) {
        return _void_scalar_repr(self);
    }
    return _void_to_hex(s->obval, s->descr->elsize, "void(b'", "\\x", "')");
}

static PyObject *
voidtype_str(PyObject *self)
{
    PyVoidScalarObject *s = (PyVoidScalarObject*) self;
    if (PyDataType_HASFIELDS(s->descr)) {
        return _void_scalar_repr(self);
    }
    return _void_to_hex(s->obval, s->descr->elsize, "b'", "\\x", "'");
}

static PyObject *
datetimetype_repr(PyObject *self)
{
    PyDatetimeScalarObject *scal;
    npy_datetimestruct dts;
    PyObject *ret;
    char iso[NPY_DATETIME_MAX_ISO8601_STRLEN];
    NPY_DATETIMEUNIT unit;

    if (!PyArray_IsScalar(self, Datetime)) {
        PyErr_SetString(PyExc_RuntimeError,
                "Called NumPy datetime repr on a non-datetime type");
        return NULL;
    }

    scal = (PyDatetimeScalarObject *)self;

    if (convert_datetime_to_datetimestruct(&scal->obmeta,
                scal->obval, &dts) < 0) {
        return NULL;
    }

    unit = scal->obmeta.base;
    if (make_iso_8601_datetime(&dts, iso, sizeof(iso), 0, 0,
                            unit, -1, NPY_SAFE_CASTING) < 0) {
        return NULL;
    }

    /*
     * For straight units or generic units, the unit will be deduced
     * from the string, so it's not necessary to specify it.
     */
    if ((scal->obmeta.num == 1 && scal->obmeta.base != NPY_FR_h) ||
            scal->obmeta.base == NPY_FR_GENERIC) {
        ret = PyUnicode_FromFormat("numpy.datetime64('%s')", iso);
    }
    else {
        PyObject *meta = metastr_to_unicode(&scal->obmeta, 1);
        if (meta == NULL) {
            return NULL;
        }
        ret = PyUnicode_FromFormat("numpy.datetime64('%s','%S')", iso, meta);
        Py_DECREF(meta);
    }

    return ret;
}

static PyObject *
timedeltatype_repr(PyObject *self)
{
    PyTimedeltaScalarObject *scal;
    PyObject *val, *ret;

    if (!PyArray_IsScalar(self, Timedelta)) {
        PyErr_SetString(PyExc_RuntimeError,
                "Called NumPy timedelta repr on a non-datetime type");
        return NULL;
    }

    scal = (PyTimedeltaScalarObject *)self;

    /* The value */
    if (scal->obval == NPY_DATETIME_NAT) {
        val = PyUnicode_FromString("'NaT'");
    }
    else {
         /* Can't use "%lld" if HAVE_LONG_LONG is not defined */
#if defined(HAVE_LONG_LONG)
        val = PyUnicode_FromFormat("%lld", (long long)scal->obval);
#else
        val = PyUnicode_FromFormat("%ld", (long)scal->obval);
#endif
    }
    if (val == NULL) {
        return NULL;
    }

    /* The metadata unit */
    if (scal->obmeta.base == NPY_FR_GENERIC) {
        ret = PyUnicode_FromFormat("numpy.timedelta64(%S)", val);
    }
    else {
        PyObject *meta = metastr_to_unicode(&scal->obmeta, 1);
        if (meta == NULL) {
            Py_DECREF(val);
            return NULL;
        }
        ret = PyUnicode_FromFormat("numpy.timedelta64(%S,'%S')", val, meta);
        Py_DECREF(meta);
    }
    Py_DECREF(val);

    return ret;
}

static PyObject *
datetimetype_str(PyObject *self)
{
    PyDatetimeScalarObject *scal;
    npy_datetimestruct dts;
    char iso[NPY_DATETIME_MAX_ISO8601_STRLEN];
    NPY_DATETIMEUNIT unit;

    if (!PyArray_IsScalar(self, Datetime)) {
        PyErr_SetString(PyExc_RuntimeError,
                "Called NumPy datetime str on a non-datetime type");
        return NULL;
    }

    scal = (PyDatetimeScalarObject *)self;

    if (convert_datetime_to_datetimestruct(&scal->obmeta, scal->obval,
                                                            &dts) < 0) {
        return NULL;
    }

    unit = scal->obmeta.base;
    if (make_iso_8601_datetime(&dts, iso, sizeof(iso), 0, 0,
                            unit, -1, NPY_SAFE_CASTING) < 0) {
        return NULL;
    }

    return PyUnicode_FromString(iso);
}

static char *_datetime_verbose_strings[NPY_DATETIME_NUMUNITS] = {
    "years",
    "months",
    "weeks",
    "<invalid>",
    "days",
    "hours",
    "minutes",
    "seconds",
    "milliseconds",
    "microseconds",
    "nanoseconds",
    "picoseconds",
    "femtoseconds",
    "attoseconds",
    "generic time units"
};

static PyObject *
timedeltatype_str(PyObject *self)
{
    PyTimedeltaScalarObject *scal;
    PyObject *ret;
    char *basestr = "invalid";

    if (!PyArray_IsScalar(self, Timedelta)) {
        PyErr_SetString(PyExc_RuntimeError,
                "Called NumPy timedelta str on a non-datetime type");
        return NULL;
    }

    scal = (PyTimedeltaScalarObject *)self;

    if (scal->obmeta.base >= 0 && scal->obmeta.base < NPY_DATETIME_NUMUNITS) {
        basestr = _datetime_verbose_strings[scal->obmeta.base];
    }
    else {
        PyErr_SetString(PyExc_RuntimeError,
                "NumPy datetime metadata is corrupted");
        return NULL;
    }

    if (scal->obval == NPY_DATETIME_NAT) {
        ret = PyUnicode_FromString("NaT");
    }
    else {
        /*
         * Can't use "%lld" if HAVE_LONG_LONG is not defined
         */
#if defined(HAVE_LONG_LONG)
        ret = PyUnicode_FromFormat("%lld %s",
            (long long)(scal->obval * scal->obmeta.num), basestr);
#else
        ret = PyUnicode_FromFormat("%ld %s",
            (long)(scal->obval * scal->obmeta.num), basestr);
#endif
    }

    return ret;
}

/*
 * float type str and repr
 *
 * These functions will return NULL if PyString creation fails.
 */


/*
 *               *** BEGIN LEGACY PRINTING MODE CODE ***
 *
 * This code is legacy code needed to reproduce the printing behavior of
 * scalars in numpy 1.13. One day we hope to remove it.
 */

/* determines if legacy mode is enabled, global set in multiarraymodule.c */
extern int npy_legacy_print_mode;

#define HALFPREC_REPR 5
#define HALFPREC_STR 5
#define FLOATPREC_REPR 8
#define FLOATPREC_STR 6
#define DOUBLEPREC_REPR 17
#define DOUBLEPREC_STR 12
#if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE
#define LONGDOUBLEPREC_REPR DOUBLEPREC_REPR
#define LONGDOUBLEPREC_STR DOUBLEPREC_STR
#else /* More than probably needed on Intel FP */
#define LONGDOUBLEPREC_REPR 20
#define LONGDOUBLEPREC_STR 12
#endif

#line 783

#line 790

#define _FMT1 "%%.%i" NPY_FLOAT_FMT
#define _FMT2 "%%+.%i" NPY_FLOAT_FMT

static PyObject*
legacy_cfloat_formatstr(npy_cfloat val)
{
    /* XXX: Find a correct size here for format string */
    char format[64], buf[100], *res;

    /*
     * Ideally, we should handle this nan/inf stuff in NumpyOS_ascii_format*
     */
    if (val.real == 0.0 && npy_signbit(val.real) == 0) {
        PyOS_snprintf(format, sizeof(format), _FMT1, FLOATPREC_STR);
        res = NumPyOS_ascii_formatf(buf, sizeof(buf) - 1, format, val.imag, 0);
        if (res == NULL) {
            PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
            return NULL;
        }
        if (!npy_isfinite(val.imag)) {
            strncat(buf, "*", sizeof(buf) - strlen(buf) - 1);
        }
        strncat(buf, "j", sizeof(buf) - strlen(buf) - 1);
    }
    else {
        char re[64], im[64];

        if (npy_isfinite(val.real)) {
            PyOS_snprintf(format, sizeof(format), _FMT1, FLOATPREC_STR);
            res = NumPyOS_ascii_formatf(re, sizeof(re), format,
                                             val.real, 0);
            if (res == NULL) {
                PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
                return NULL;
            }
        }
        else {
            if (npy_isnan(val.real)) {
                strcpy(re, "nan");
            }
            else if (val.real > 0){
                strcpy(re, "inf");
            }
            else {
                strcpy(re, "-inf");
            }
        }


        if (npy_isfinite(val.imag)) {
            PyOS_snprintf(format, sizeof(format), _FMT2, FLOATPREC_STR);
            res = NumPyOS_ascii_formatf(im, sizeof(im), format,
                                             val.imag, 0);
            if (res == NULL) {
                PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
                return NULL;
            }
        }
        else {
            if (npy_isnan(val.imag)) {
                strcpy(im, "+nan");
            }
            else if (val.imag > 0){
                strcpy(im, "+inf");
            }
            else {
                strcpy(im, "-inf");
            }
            if (!npy_isfinite(val.imag)) {
                strncat(im, "*", sizeof(im) - strlen(im) - 1);
            }
        }
        PyOS_snprintf(buf, sizeof(buf), "(%s%sj)", re, im);
    }

    return PyUnicode_FromString(buf);
}

#undef _FMT1
#undef _FMT2


#line 790

#define _FMT1 "%%.%i" NPY_DOUBLE_FMT
#define _FMT2 "%%+.%i" NPY_DOUBLE_FMT

static PyObject*
legacy_cdouble_formatstr(npy_cdouble val)
{
    /* XXX: Find a correct size here for format string */
    char format[64], buf[100], *res;

    /*
     * Ideally, we should handle this nan/inf stuff in NumpyOS_ascii_format*
     */
    if (val.real == 0.0 && npy_signbit(val.real) == 0) {
        PyOS_snprintf(format, sizeof(format), _FMT1, DOUBLEPREC_STR);
        res = NumPyOS_ascii_formatd(buf, sizeof(buf) - 1, format, val.imag, 0);
        if (res == NULL) {
            PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
            return NULL;
        }
        if (!npy_isfinite(val.imag)) {
            strncat(buf, "*", sizeof(buf) - strlen(buf) - 1);
        }
        strncat(buf, "j", sizeof(buf) - strlen(buf) - 1);
    }
    else {
        char re[64], im[64];

        if (npy_isfinite(val.real)) {
            PyOS_snprintf(format, sizeof(format), _FMT1, DOUBLEPREC_STR);
            res = NumPyOS_ascii_formatd(re, sizeof(re), format,
                                             val.real, 0);
            if (res == NULL) {
                PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
                return NULL;
            }
        }
        else {
            if (npy_isnan(val.real)) {
                strcpy(re, "nan");
            }
            else if (val.real > 0){
                strcpy(re, "inf");
            }
            else {
                strcpy(re, "-inf");
            }
        }


        if (npy_isfinite(val.imag)) {
            PyOS_snprintf(format, sizeof(format), _FMT2, DOUBLEPREC_STR);
            res = NumPyOS_ascii_formatd(im, sizeof(im), format,
                                             val.imag, 0);
            if (res == NULL) {
                PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
                return NULL;
            }
        }
        else {
            if (npy_isnan(val.imag)) {
                strcpy(im, "+nan");
            }
            else if (val.imag > 0){
                strcpy(im, "+inf");
            }
            else {
                strcpy(im, "-inf");
            }
            if (!npy_isfinite(val.imag)) {
                strncat(im, "*", sizeof(im) - strlen(im) - 1);
            }
        }
        PyOS_snprintf(buf, sizeof(buf), "(%s%sj)", re, im);
    }

    return PyUnicode_FromString(buf);
}

#undef _FMT1
#undef _FMT2


#line 790

#define _FMT1 "%%.%i" NPY_LONGDOUBLE_FMT
#define _FMT2 "%%+.%i" NPY_LONGDOUBLE_FMT

static PyObject*
legacy_clongdouble_formatstr(npy_clongdouble val)
{
    /* XXX: Find a correct size here for format string */
    char format[64], buf[100], *res;

    /*
     * Ideally, we should handle this nan/inf stuff in NumpyOS_ascii_format*
     */
    if (val.real == 0.0 && npy_signbit(val.real) == 0) {
        PyOS_snprintf(format, sizeof(format), _FMT1, LONGDOUBLEPREC_STR);
        res = NumPyOS_ascii_formatl(buf, sizeof(buf) - 1, format, val.imag, 0);
        if (res == NULL) {
            PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
            return NULL;
        }
        if (!npy_isfinite(val.imag)) {
            strncat(buf, "*", sizeof(buf) - strlen(buf) - 1);
        }
        strncat(buf, "j", sizeof(buf) - strlen(buf) - 1);
    }
    else {
        char re[64], im[64];

        if (npy_isfinite(val.real)) {
            PyOS_snprintf(format, sizeof(format), _FMT1, LONGDOUBLEPREC_STR);
            res = NumPyOS_ascii_formatl(re, sizeof(re), format,
                                             val.real, 0);
            if (res == NULL) {
                PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
                return NULL;
            }
        }
        else {
            if (npy_isnan(val.real)) {
                strcpy(re, "nan");
            }
            else if (val.real > 0){
                strcpy(re, "inf");
            }
            else {
                strcpy(re, "-inf");
            }
        }


        if (npy_isfinite(val.imag)) {
            PyOS_snprintf(format, sizeof(format), _FMT2, LONGDOUBLEPREC_STR);
            res = NumPyOS_ascii_formatl(im, sizeof(im), format,
                                             val.imag, 0);
            if (res == NULL) {
                PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
                return NULL;
            }
        }
        else {
            if (npy_isnan(val.imag)) {
                strcpy(im, "+nan");
            }
            else if (val.imag > 0){
                strcpy(im, "+inf");
            }
            else {
                strcpy(im, "-inf");
            }
            if (!npy_isfinite(val.imag)) {
                strncat(im, "*", sizeof(im) - strlen(im) - 1);
            }
        }
        PyOS_snprintf(buf, sizeof(buf), "(%s%sj)", re, im);
    }

    return PyUnicode_FromString(buf);
}

#undef _FMT1
#undef _FMT2



#line 880

#define _FMT1 "%%.%i" NPY_FLOAT_FMT

static PyObject *
legacy_float_formatstr(npy_float val){
    /* XXX: Find a correct size here for format string */
    char format[64], buf[100], *res;
    size_t i, cnt;

    PyOS_snprintf(format, sizeof(format), _FMT1, FLOATPREC_STR);
    res = NumPyOS_ascii_formatf(buf, sizeof(buf), format, val, 0);
    if (res == NULL) {
        PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
        return NULL;
    }

    /* If nothing but digits after sign, append ".0" */
    cnt = strlen(buf);
    for (i = (buf[0] == '-') ? 1 : 0; i < cnt; ++i) {
        if (!isdigit(Py_CHARMASK(buf[i]))) {
            break;
        }
    }
    if (i == cnt && sizeof(buf) >= cnt + 3) {
        strcpy(&buf[cnt],".0");
    }

    return PyUnicode_FromString(buf);
}

#undef _FMT1


#line 880

#define _FMT1 "%%.%i" NPY_DOUBLE_FMT

static PyObject *
legacy_double_formatstr(npy_double val){
    /* XXX: Find a correct size here for format string */
    char format[64], buf[100], *res;
    size_t i, cnt;

    PyOS_snprintf(format, sizeof(format), _FMT1, DOUBLEPREC_STR);
    res = NumPyOS_ascii_formatd(buf, sizeof(buf), format, val, 0);
    if (res == NULL) {
        PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
        return NULL;
    }

    /* If nothing but digits after sign, append ".0" */
    cnt = strlen(buf);
    for (i = (buf[0] == '-') ? 1 : 0; i < cnt; ++i) {
        if (!isdigit(Py_CHARMASK(buf[i]))) {
            break;
        }
    }
    if (i == cnt && sizeof(buf) >= cnt + 3) {
        strcpy(&buf[cnt],".0");
    }

    return PyUnicode_FromString(buf);
}

#undef _FMT1


#line 880

#define _FMT1 "%%.%i" NPY_LONGDOUBLE_FMT

static PyObject *
legacy_longdouble_formatstr(npy_longdouble val){
    /* XXX: Find a correct size here for format string */
    char format[64], buf[100], *res;
    size_t i, cnt;

    PyOS_snprintf(format, sizeof(format), _FMT1, LONGDOUBLEPREC_STR);
    res = NumPyOS_ascii_formatl(buf, sizeof(buf), format, val, 0);
    if (res == NULL) {
        PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
        return NULL;
    }

    /* If nothing but digits after sign, append ".0" */
    cnt = strlen(buf);
    for (i = (buf[0] == '-') ? 1 : 0; i < cnt; ++i) {
        if (!isdigit(Py_CHARMASK(buf[i]))) {
            break;
        }
    }
    if (i == cnt && sizeof(buf) >= cnt + 3) {
        strcpy(&buf[cnt],".0");
    }

    return PyUnicode_FromString(buf);
}

#undef _FMT1




#line 783

#line 790

#define _FMT1 "%%.%i" NPY_FLOAT_FMT
#define _FMT2 "%%+.%i" NPY_FLOAT_FMT

static PyObject*
legacy_cfloat_formatrepr(npy_cfloat val)
{
    /* XXX: Find a correct size here for format string */
    char format[64], buf[100], *res;

    /*
     * Ideally, we should handle this nan/inf stuff in NumpyOS_ascii_format*
     */
    if (val.real == 0.0 && npy_signbit(val.real) == 0) {
        PyOS_snprintf(format, sizeof(format), _FMT1, FLOATPREC_REPR);
        res = NumPyOS_ascii_formatf(buf, sizeof(buf) - 1, format, val.imag, 0);
        if (res == NULL) {
            PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
            return NULL;
        }
        if (!npy_isfinite(val.imag)) {
            strncat(buf, "*", sizeof(buf) - strlen(buf) - 1);
        }
        strncat(buf, "j", sizeof(buf) - strlen(buf) - 1);
    }
    else {
        char re[64], im[64];

        if (npy_isfinite(val.real)) {
            PyOS_snprintf(format, sizeof(format), _FMT1, FLOATPREC_REPR);
            res = NumPyOS_ascii_formatf(re, sizeof(re), format,
                                             val.real, 0);
            if (res == NULL) {
                PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
                return NULL;
            }
        }
        else {
            if (npy_isnan(val.real)) {
                strcpy(re, "nan");
            }
            else if (val.real > 0){
                strcpy(re, "inf");
            }
            else {
                strcpy(re, "-inf");
            }
        }


        if (npy_isfinite(val.imag)) {
            PyOS_snprintf(format, sizeof(format), _FMT2, FLOATPREC_REPR);
            res = NumPyOS_ascii_formatf(im, sizeof(im), format,
                                             val.imag, 0);
            if (res == NULL) {
                PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
                return NULL;
            }
        }
        else {
            if (npy_isnan(val.imag)) {
                strcpy(im, "+nan");
            }
            else if (val.imag > 0){
                strcpy(im, "+inf");
            }
            else {
                strcpy(im, "-inf");
            }
            if (!npy_isfinite(val.imag)) {
                strncat(im, "*", sizeof(im) - strlen(im) - 1);
            }
        }
        PyOS_snprintf(buf, sizeof(buf), "(%s%sj)", re, im);
    }

    return PyUnicode_FromString(buf);
}

#undef _FMT1
#undef _FMT2


#line 790

#define _FMT1 "%%.%i" NPY_DOUBLE_FMT
#define _FMT2 "%%+.%i" NPY_DOUBLE_FMT

static PyObject*
legacy_cdouble_formatrepr(npy_cdouble val)
{
    /* XXX: Find a correct size here for format string */
    char format[64], buf[100], *res;

    /*
     * Ideally, we should handle this nan/inf stuff in NumpyOS_ascii_format*
     */
    if (val.real == 0.0 && npy_signbit(val.real) == 0) {
        PyOS_snprintf(format, sizeof(format), _FMT1, DOUBLEPREC_REPR);
        res = NumPyOS_ascii_formatd(buf, sizeof(buf) - 1, format, val.imag, 0);
        if (res == NULL) {
            PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
            return NULL;
        }
        if (!npy_isfinite(val.imag)) {
            strncat(buf, "*", sizeof(buf) - strlen(buf) - 1);
        }
        strncat(buf, "j", sizeof(buf) - strlen(buf) - 1);
    }
    else {
        char re[64], im[64];

        if (npy_isfinite(val.real)) {
            PyOS_snprintf(format, sizeof(format), _FMT1, DOUBLEPREC_REPR);
            res = NumPyOS_ascii_formatd(re, sizeof(re), format,
                                             val.real, 0);
            if (res == NULL) {
                PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
                return NULL;
            }
        }
        else {
            if (npy_isnan(val.real)) {
                strcpy(re, "nan");
            }
            else if (val.real > 0){
                strcpy(re, "inf");
            }
            else {
                strcpy(re, "-inf");
            }
        }


        if (npy_isfinite(val.imag)) {
            PyOS_snprintf(format, sizeof(format), _FMT2, DOUBLEPREC_REPR);
            res = NumPyOS_ascii_formatd(im, sizeof(im), format,
                                             val.imag, 0);
            if (res == NULL) {
                PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
                return NULL;
            }
        }
        else {
            if (npy_isnan(val.imag)) {
                strcpy(im, "+nan");
            }
            else if (val.imag > 0){
                strcpy(im, "+inf");
            }
            else {
                strcpy(im, "-inf");
            }
            if (!npy_isfinite(val.imag)) {
                strncat(im, "*", sizeof(im) - strlen(im) - 1);
            }
        }
        PyOS_snprintf(buf, sizeof(buf), "(%s%sj)", re, im);
    }

    return PyUnicode_FromString(buf);
}

#undef _FMT1
#undef _FMT2


#line 790

#define _FMT1 "%%.%i" NPY_LONGDOUBLE_FMT
#define _FMT2 "%%+.%i" NPY_LONGDOUBLE_FMT

static PyObject*
legacy_clongdouble_formatrepr(npy_clongdouble val)
{
    /* XXX: Find a correct size here for format string */
    char format[64], buf[100], *res;

    /*
     * Ideally, we should handle this nan/inf stuff in NumpyOS_ascii_format*
     */
    if (val.real == 0.0 && npy_signbit(val.real) == 0) {
        PyOS_snprintf(format, sizeof(format), _FMT1, LONGDOUBLEPREC_REPR);
        res = NumPyOS_ascii_formatl(buf, sizeof(buf) - 1, format, val.imag, 0);
        if (res == NULL) {
            PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
            return NULL;
        }
        if (!npy_isfinite(val.imag)) {
            strncat(buf, "*", sizeof(buf) - strlen(buf) - 1);
        }
        strncat(buf, "j", sizeof(buf) - strlen(buf) - 1);
    }
    else {
        char re[64], im[64];

        if (npy_isfinite(val.real)) {
            PyOS_snprintf(format, sizeof(format), _FMT1, LONGDOUBLEPREC_REPR);
            res = NumPyOS_ascii_formatl(re, sizeof(re), format,
                                             val.real, 0);
            if (res == NULL) {
                PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
                return NULL;
            }
        }
        else {
            if (npy_isnan(val.real)) {
                strcpy(re, "nan");
            }
            else if (val.real > 0){
                strcpy(re, "inf");
            }
            else {
                strcpy(re, "-inf");
            }
        }


        if (npy_isfinite(val.imag)) {
            PyOS_snprintf(format, sizeof(format), _FMT2, LONGDOUBLEPREC_REPR);
            res = NumPyOS_ascii_formatl(im, sizeof(im), format,
                                             val.imag, 0);
            if (res == NULL) {
                PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
                return NULL;
            }
        }
        else {
            if (npy_isnan(val.imag)) {
                strcpy(im, "+nan");
            }
            else if (val.imag > 0){
                strcpy(im, "+inf");
            }
            else {
                strcpy(im, "-inf");
            }
            if (!npy_isfinite(val.imag)) {
                strncat(im, "*", sizeof(im) - strlen(im) - 1);
            }
        }
        PyOS_snprintf(buf, sizeof(buf), "(%s%sj)", re, im);
    }

    return PyUnicode_FromString(buf);
}

#undef _FMT1
#undef _FMT2



#line 880

#define _FMT1 "%%.%i" NPY_FLOAT_FMT

static PyObject *
legacy_float_formatrepr(npy_float val){
    /* XXX: Find a correct size here for format string */
    char format[64], buf[100], *res;
    size_t i, cnt;

    PyOS_snprintf(format, sizeof(format), _FMT1, FLOATPREC_REPR);
    res = NumPyOS_ascii_formatf(buf, sizeof(buf), format, val, 0);
    if (res == NULL) {
        PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
        return NULL;
    }

    /* If nothing but digits after sign, append ".0" */
    cnt = strlen(buf);
    for (i = (buf[0] == '-') ? 1 : 0; i < cnt; ++i) {
        if (!isdigit(Py_CHARMASK(buf[i]))) {
            break;
        }
    }
    if (i == cnt && sizeof(buf) >= cnt + 3) {
        strcpy(&buf[cnt],".0");
    }

    return PyUnicode_FromString(buf);
}

#undef _FMT1


#line 880

#define _FMT1 "%%.%i" NPY_DOUBLE_FMT

static PyObject *
legacy_double_formatrepr(npy_double val){
    /* XXX: Find a correct size here for format string */
    char format[64], buf[100], *res;
    size_t i, cnt;

    PyOS_snprintf(format, sizeof(format), _FMT1, DOUBLEPREC_REPR);
    res = NumPyOS_ascii_formatd(buf, sizeof(buf), format, val, 0);
    if (res == NULL) {
        PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
        return NULL;
    }

    /* If nothing but digits after sign, append ".0" */
    cnt = strlen(buf);
    for (i = (buf[0] == '-') ? 1 : 0; i < cnt; ++i) {
        if (!isdigit(Py_CHARMASK(buf[i]))) {
            break;
        }
    }
    if (i == cnt && sizeof(buf) >= cnt + 3) {
        strcpy(&buf[cnt],".0");
    }

    return PyUnicode_FromString(buf);
}

#undef _FMT1


#line 880

#define _FMT1 "%%.%i" NPY_LONGDOUBLE_FMT

static PyObject *
legacy_longdouble_formatrepr(npy_longdouble val){
    /* XXX: Find a correct size here for format string */
    char format[64], buf[100], *res;
    size_t i, cnt;

    PyOS_snprintf(format, sizeof(format), _FMT1, LONGDOUBLEPREC_REPR);
    res = NumPyOS_ascii_formatl(buf, sizeof(buf), format, val, 0);
    if (res == NULL) {
        PyErr_SetString(PyExc_RuntimeError, "Error while formatting");
        return NULL;
    }

    /* If nothing but digits after sign, append ".0" */
    cnt = strlen(buf);
    for (i = (buf[0] == '-') ? 1 : 0; i < cnt; ++i) {
        if (!isdigit(Py_CHARMASK(buf[i]))) {
            break;
        }
    }
    if (i == cnt && sizeof(buf) >= cnt + 3) {
        strcpy(&buf[cnt],".0");
    }

    return PyUnicode_FromString(buf);
}

#undef _FMT1






/*
 *               *** END LEGACY PRINTING MODE CODE ***
 */


#line 925

#line 931

/* helper function choose scientific of fractional output, based on a cutoff */
static PyObject *
floattype_str_either(npy_float val, TrimMode trim_pos, TrimMode trim_sci,
                         npy_bool sign)
{

    if (npy_legacy_print_mode <= 113) {
        return legacy_float_formatstr(val);
    }

    int use_positional;
    if (npy_isnan(val) || val == 0) {
         use_positional = 1;
    }
    else {
        npy_float absval = val < 0 ? -val : val;
        use_positional = absval < 1.e16L && absval >= 1.e-4L;
    }

    if (use_positional) {
        return format_float(val, 0, -1, sign, trim_pos, -1, -1, -1);
    }
    return format_float(val, 1, -1, sign, trim_sci, -1, -1, -1);
}

static PyObject *
floattype_str(PyObject *self)
{
    return floattype_str_either(PyArrayScalar_VAL(self, Float),
                                  TrimMode_LeaveOneZero, TrimMode_DptZeros, 0);
}

static PyObject *
cfloattype_str(PyObject *self)
{
    PyObject *rstr, *istr;
    npy_cfloat val = PyArrayScalar_VAL(self, CFloat);
    TrimMode trim = TrimMode_DptZeros;

    if (npy_legacy_print_mode <= 113) {
        return legacy_cfloat_formatstr(val);
    }

    if (val.real == 0.0 && npy_signbit(val.real) == 0) {
        istr = floattype_str_either(val.imag, trim, trim, 0);
        if (istr == NULL) {
            return NULL;
        }
        PyObject *ret = PyUnicode_FromFormat("%Sj", istr);
        Py_DECREF(istr);
        return ret;
    }

    if (npy_isfinite(val.real)) {
        rstr = floattype_str_either(val.real, trim, trim, 0);
    }
    else if (npy_isnan(val.real)) {
        rstr = PyUnicode_FromString("nan");
    }
    else if (val.real > 0){
        rstr = PyUnicode_FromString("inf");
    }
    else {
        rstr = PyUnicode_FromString("-inf");
    }
    if (rstr == NULL) {
        return NULL;
    }

    if (npy_isfinite(val.imag)) {
        istr = floattype_str_either(val.imag, trim, trim, 1);
    }
    else if (npy_isnan(val.imag)) {
        istr = PyUnicode_FromString("+nan");
    }
    else if (val.imag > 0){
        istr = PyUnicode_FromString("+inf");
    }
    else {
        istr = PyUnicode_FromString("-inf");
    }
    if (istr == NULL) {
        Py_DECREF(rstr);
        return NULL;
    }

    PyObject *ret = PyUnicode_FromFormat("(%S%Sj)", rstr, istr);
    Py_DECREF(rstr);
    Py_DECREF(istr);
    return ret;
}

#undef PREC


#line 931

/* helper function choose scientific of fractional output, based on a cutoff */
static PyObject *
doubletype_str_either(npy_double val, TrimMode trim_pos, TrimMode trim_sci,
                         npy_bool sign)
{

    if (npy_legacy_print_mode <= 113) {
        return legacy_double_formatstr(val);
    }

    int use_positional;
    if (npy_isnan(val) || val == 0) {
         use_positional = 1;
    }
    else {
        npy_double absval = val < 0 ? -val : val;
        use_positional = absval < 1.e16L && absval >= 1.e-4L;
    }

    if (use_positional) {
        return format_double(val, 0, -1, sign, trim_pos, -1, -1, -1);
    }
    return format_double(val, 1, -1, sign, trim_sci, -1, -1, -1);
}

static PyObject *
doubletype_str(PyObject *self)
{
    return doubletype_str_either(PyArrayScalar_VAL(self, Double),
                                  TrimMode_LeaveOneZero, TrimMode_DptZeros, 0);
}

static PyObject *
cdoubletype_str(PyObject *self)
{
    PyObject *rstr, *istr;
    npy_cdouble val = PyArrayScalar_VAL(self, CDouble);
    TrimMode trim = TrimMode_DptZeros;

    if (npy_legacy_print_mode <= 113) {
        return legacy_cdouble_formatstr(val);
    }

    if (val.real == 0.0 && npy_signbit(val.real) == 0) {
        istr = doubletype_str_either(val.imag, trim, trim, 0);
        if (istr == NULL) {
            return NULL;
        }
        PyObject *ret = PyUnicode_FromFormat("%Sj", istr);
        Py_DECREF(istr);
        return ret;
    }

    if (npy_isfinite(val.real)) {
        rstr = doubletype_str_either(val.real, trim, trim, 0);
    }
    else if (npy_isnan(val.real)) {
        rstr = PyUnicode_FromString("nan");
    }
    else if (val.real > 0){
        rstr = PyUnicode_FromString("inf");
    }
    else {
        rstr = PyUnicode_FromString("-inf");
    }
    if (rstr == NULL) {
        return NULL;
    }

    if (npy_isfinite(val.imag)) {
        istr = doubletype_str_either(val.imag, trim, trim, 1);
    }
    else if (npy_isnan(val.imag)) {
        istr = PyUnicode_FromString("+nan");
    }
    else if (val.imag > 0){
        istr = PyUnicode_FromString("+inf");
    }
    else {
        istr = PyUnicode_FromString("-inf");
    }
    if (istr == NULL) {
        Py_DECREF(rstr);
        return NULL;
    }

    PyObject *ret = PyUnicode_FromFormat("(%S%Sj)", rstr, istr);
    Py_DECREF(rstr);
    Py_DECREF(istr);
    return ret;
}

#undef PREC


#line 931

/* helper function choose scientific of fractional output, based on a cutoff */
static PyObject *
longdoubletype_str_either(npy_longdouble val, TrimMode trim_pos, TrimMode trim_sci,
                         npy_bool sign)
{

    if (npy_legacy_print_mode <= 113) {
        return legacy_longdouble_formatstr(val);
    }

    int use_positional;
    if (npy_isnan(val) || val == 0) {
         use_positional = 1;
    }
    else {
        npy_longdouble absval = val < 0 ? -val : val;
        use_positional = absval < 1.e16L && absval >= 1.e-4L;
    }

    if (use_positional) {
        return format_longdouble(val, 0, -1, sign, trim_pos, -1, -1, -1);
    }
    return format_longdouble(val, 1, -1, sign, trim_sci, -1, -1, -1);
}

static PyObject *
longdoubletype_str(PyObject *self)
{
    return longdoubletype_str_either(PyArrayScalar_VAL(self, LongDouble),
                                  TrimMode_LeaveOneZero, TrimMode_DptZeros, 0);
}

static PyObject *
clongdoubletype_str(PyObject *self)
{
    PyObject *rstr, *istr;
    npy_clongdouble val = PyArrayScalar_VAL(self, CLongDouble);
    TrimMode trim = TrimMode_DptZeros;

    if (npy_legacy_print_mode <= 113) {
        return legacy_clongdouble_formatstr(val);
    }

    if (val.real == 0.0 && npy_signbit(val.real) == 0) {
        istr = longdoubletype_str_either(val.imag, trim, trim, 0);
        if (istr == NULL) {
            return NULL;
        }
        PyObject *ret = PyUnicode_FromFormat("%Sj", istr);
        Py_DECREF(istr);
        return ret;
    }

    if (npy_isfinite(val.real)) {
        rstr = longdoubletype_str_either(val.real, trim, trim, 0);
    }
    else if (npy_isnan(val.real)) {
        rstr = PyUnicode_FromString("nan");
    }
    else if (val.real > 0){
        rstr = PyUnicode_FromString("inf");
    }
    else {
        rstr = PyUnicode_FromString("-inf");
    }
    if (rstr == NULL) {
        return NULL;
    }

    if (npy_isfinite(val.imag)) {
        istr = longdoubletype_str_either(val.imag, trim, trim, 1);
    }
    else if (npy_isnan(val.imag)) {
        istr = PyUnicode_FromString("+nan");
    }
    else if (val.imag > 0){
        istr = PyUnicode_FromString("+inf");
    }
    else {
        istr = PyUnicode_FromString("-inf");
    }
    if (istr == NULL) {
        Py_DECREF(rstr);
        return NULL;
    }

    PyObject *ret = PyUnicode_FromFormat("(%S%Sj)", rstr, istr);
    Py_DECREF(rstr);
    Py_DECREF(istr);
    return ret;
}

#undef PREC




static PyObject *
halftype_str(PyObject *self)
{
    npy_half val = PyArrayScalar_VAL(self, Half);
    float floatval = npy_half_to_float(val);
    float absval;

    if (npy_legacy_print_mode <= 113) {
        return legacy_float_formatstr(floatval);
    }

    absval = floatval < 0 ? -floatval : floatval;

    if (absval == 0 || (absval < 1.e16 && absval >= 1.e-4) ) {
        return format_half(val, 0, -1, 0, TrimMode_LeaveOneZero, -1, -1, -1);
    }
    return format_half(val, 1, -1, 0, TrimMode_DptZeros, -1, -1, -1);
}



#line 925

#line 931

/* helper function choose scientific of fractional output, based on a cutoff */
static PyObject *
floattype_repr_either(npy_float val, TrimMode trim_pos, TrimMode trim_sci,
                         npy_bool sign)
{

    if (npy_legacy_print_mode <= 113) {
        return legacy_float_formatrepr(val);
    }

    int use_positional;
    if (npy_isnan(val) || val == 0) {
         use_positional = 1;
    }
    else {
        npy_float absval = val < 0 ? -val : val;
        use_positional = absval < 1.e16L && absval >= 1.e-4L;
    }

    if (use_positional) {
        return format_float(val, 0, -1, sign, trim_pos, -1, -1, -1);
    }
    return format_float(val, 1, -1, sign, trim_sci, -1, -1, -1);
}

static PyObject *
floattype_repr(PyObject *self)
{
    return floattype_repr_either(PyArrayScalar_VAL(self, Float),
                                  TrimMode_LeaveOneZero, TrimMode_DptZeros, 0);
}

static PyObject *
cfloattype_repr(PyObject *self)
{
    PyObject *rstr, *istr;
    npy_cfloat val = PyArrayScalar_VAL(self, CFloat);
    TrimMode trim = TrimMode_DptZeros;

    if (npy_legacy_print_mode <= 113) {
        return legacy_cfloat_formatrepr(val);
    }

    if (val.real == 0.0 && npy_signbit(val.real) == 0) {
        istr = floattype_repr_either(val.imag, trim, trim, 0);
        if (istr == NULL) {
            return NULL;
        }
        PyObject *ret = PyUnicode_FromFormat("%Sj", istr);
        Py_DECREF(istr);
        return ret;
    }

    if (npy_isfinite(val.real)) {
        rstr = floattype_repr_either(val.real, trim, trim, 0);
    }
    else if (npy_isnan(val.real)) {
        rstr = PyUnicode_FromString("nan");
    }
    else if (val.real > 0){
        rstr = PyUnicode_FromString("inf");
    }
    else {
        rstr = PyUnicode_FromString("-inf");
    }
    if (rstr == NULL) {
        return NULL;
    }

    if (npy_isfinite(val.imag)) {
        istr = floattype_repr_either(val.imag, trim, trim, 1);
    }
    else if (npy_isnan(val.imag)) {
        istr = PyUnicode_FromString("+nan");
    }
    else if (val.imag > 0){
        istr = PyUnicode_FromString("+inf");
    }
    else {
        istr = PyUnicode_FromString("-inf");
    }
    if (istr == NULL) {
        Py_DECREF(rstr);
        return NULL;
    }

    PyObject *ret = PyUnicode_FromFormat("(%S%Sj)", rstr, istr);
    Py_DECREF(rstr);
    Py_DECREF(istr);
    return ret;
}

#undef PREC


#line 931

/* helper function choose scientific of fractional output, based on a cutoff */
static PyObject *
doubletype_repr_either(npy_double val, TrimMode trim_pos, TrimMode trim_sci,
                         npy_bool sign)
{

    if (npy_legacy_print_mode <= 113) {
        return legacy_double_formatrepr(val);
    }

    int use_positional;
    if (npy_isnan(val) || val == 0) {
         use_positional = 1;
    }
    else {
        npy_double absval = val < 0 ? -val : val;
        use_positional = absval < 1.e16L && absval >= 1.e-4L;
    }

    if (use_positional) {
        return format_double(val, 0, -1, sign, trim_pos, -1, -1, -1);
    }
    return format_double(val, 1, -1, sign, trim_sci, -1, -1, -1);
}

static PyObject *
doubletype_repr(PyObject *self)
{
    return doubletype_repr_either(PyArrayScalar_VAL(self, Double),
                                  TrimMode_LeaveOneZero, TrimMode_DptZeros, 0);
}

static PyObject *
cdoubletype_repr(PyObject *self)
{
    PyObject *rstr, *istr;
    npy_cdouble val = PyArrayScalar_VAL(self, CDouble);
    TrimMode trim = TrimMode_DptZeros;

    if (npy_legacy_print_mode <= 113) {
        return legacy_cdouble_formatrepr(val);
    }

    if (val.real == 0.0 && npy_signbit(val.real) == 0) {
        istr = doubletype_repr_either(val.imag, trim, trim, 0);
        if (istr == NULL) {
            return NULL;
        }
        PyObject *ret = PyUnicode_FromFormat("%Sj", istr);
        Py_DECREF(istr);
        return ret;
    }

    if (npy_isfinite(val.real)) {
        rstr = doubletype_repr_either(val.real, trim, trim, 0);
    }
    else if (npy_isnan(val.real)) {
        rstr = PyUnicode_FromString("nan");
    }
    else if (val.real > 0){
        rstr = PyUnicode_FromString("inf");
    }
    else {
        rstr = PyUnicode_FromString("-inf");
    }
    if (rstr == NULL) {
        return NULL;
    }

    if (npy_isfinite(val.imag)) {
        istr = doubletype_repr_either(val.imag, trim, trim, 1);
    }
    else if (npy_isnan(val.imag)) {
        istr = PyUnicode_FromString("+nan");
    }
    else if (val.imag > 0){
        istr = PyUnicode_FromString("+inf");
    }
    else {
        istr = PyUnicode_FromString("-inf");
    }
    if (istr == NULL) {
        Py_DECREF(rstr);
        return NULL;
    }

    PyObject *ret = PyUnicode_FromFormat("(%S%Sj)", rstr, istr);
    Py_DECREF(rstr);
    Py_DECREF(istr);
    return ret;
}

#undef PREC


#line 931

/* helper function choose scientific of fractional output, based on a cutoff */
static PyObject *
longdoubletype_repr_either(npy_longdouble val, TrimMode trim_pos, TrimMode trim_sci,
                         npy_bool sign)
{

    if (npy_legacy_print_mode <= 113) {
        return legacy_longdouble_formatrepr(val);
    }

    int use_positional;
    if (npy_isnan(val) || val == 0) {
         use_positional = 1;
    }
    else {
        npy_longdouble absval = val < 0 ? -val : val;
        use_positional = absval < 1.e16L && absval >= 1.e-4L;
    }

    if (use_positional) {
        return format_longdouble(val, 0, -1, sign, trim_pos, -1, -1, -1);
    }
    return format_longdouble(val, 1, -1, sign, trim_sci, -1, -1, -1);
}

static PyObject *
longdoubletype_repr(PyObject *self)
{
    return longdoubletype_repr_either(PyArrayScalar_VAL(self, LongDouble),
                                  TrimMode_LeaveOneZero, TrimMode_DptZeros, 0);
}

static PyObject *
clongdoubletype_repr(PyObject *self)
{
    PyObject *rstr, *istr;
    npy_clongdouble val = PyArrayScalar_VAL(self, CLongDouble);
    TrimMode trim = TrimMode_DptZeros;

    if (npy_legacy_print_mode <= 113) {
        return legacy_clongdouble_formatrepr(val);
    }

    if (val.real == 0.0 && npy_signbit(val.real) == 0) {
        istr = longdoubletype_repr_either(val.imag, trim, trim, 0);
        if (istr == NULL) {
            return NULL;
        }
        PyObject *ret = PyUnicode_FromFormat("%Sj", istr);
        Py_DECREF(istr);
        return ret;
    }

    if (npy_isfinite(val.real)) {
        rstr = longdoubletype_repr_either(val.real, trim, trim, 0);
    }
    else if (npy_isnan(val.real)) {
        rstr = PyUnicode_FromString("nan");
    }
    else if (val.real > 0){
        rstr = PyUnicode_FromString("inf");
    }
    else {
        rstr = PyUnicode_FromString("-inf");
    }
    if (rstr == NULL) {
        return NULL;
    }

    if (npy_isfinite(val.imag)) {
        istr = longdoubletype_repr_either(val.imag, trim, trim, 1);
    }
    else if (npy_isnan(val.imag)) {
        istr = PyUnicode_FromString("+nan");
    }
    else if (val.imag > 0){
        istr = PyUnicode_FromString("+inf");
    }
    else {
        istr = PyUnicode_FromString("-inf");
    }
    if (istr == NULL) {
        Py_DECREF(rstr);
        return NULL;
    }

    PyObject *ret = PyUnicode_FromFormat("(%S%Sj)", rstr, istr);
    Py_DECREF(rstr);
    Py_DECREF(istr);
    return ret;
}

#undef PREC




static PyObject *
halftype_repr(PyObject *self)
{
    npy_half val = PyArrayScalar_VAL(self, Half);
    float floatval = npy_half_to_float(val);
    float absval;

    if (npy_legacy_print_mode <= 113) {
        return legacy_float_formatrepr(floatval);
    }

    absval = floatval < 0 ? -floatval : floatval;

    if (absval == 0 || (absval < 1.e16 && absval >= 1.e-4) ) {
        return format_half(val, 0, -1, 0, TrimMode_LeaveOneZero, -1, -1, -1);
    }
    return format_half(val, 1, -1, 0, TrimMode_DptZeros, -1, -1, -1);
}




#line 1056
static PyObject *
longdoubletype_float(PyObject *self)
{
    npy_longdouble val = PyArrayScalar_VAL(self, LongDouble);
    return PyFloat_FromDouble((double) val);
}

static PyObject *
longdoubletype_long(PyObject *self)
{
    npy_longdouble val = PyArrayScalar_VAL(self, LongDouble);
    return npy_longdouble_to_PyLong(val);
}


#line 1056
static PyObject *
clongdoubletype_float(PyObject *self)
{
    npy_longdouble val = PyArrayScalar_VAL(self, CLongDouble).real;
    return PyFloat_FromDouble((double) val);
}

static PyObject *
clongdoubletype_long(PyObject *self)
{
    npy_longdouble val = PyArrayScalar_VAL(self, CLongDouble).real;
    return npy_longdouble_to_PyLong(val);
}



static PyNumberMethods gentype_as_number = {
    .nb_add = (binaryfunc)gentype_add,
    .nb_subtract = (binaryfunc)gentype_subtract,
    .nb_multiply = (binaryfunc)gentype_multiply,
    .nb_remainder = (binaryfunc)gentype_remainder,
    .nb_divmod = (binaryfunc)gentype_divmod,
    .nb_power = (ternaryfunc)gentype_power,
    .nb_negative = (unaryfunc)gentype_negative,
    .nb_positive = (unaryfunc)gentype_positive,
    .nb_absolute = (unaryfunc)gentype_absolute,
    .nb_bool = (inquiry)gentype_nonzero_number,
    .nb_invert = (unaryfunc)gentype_invert,
    .nb_lshift = (binaryfunc)gentype_lshift,
    .nb_rshift = (binaryfunc)gentype_rshift,
    .nb_and = (binaryfunc)gentype_and,
    .nb_xor = (binaryfunc)gentype_xor,
    .nb_or = (binaryfunc)gentype_or,
    .nb_int = (unaryfunc)gentype_int,
    .nb_float = (unaryfunc)gentype_float,
    .nb_floor_divide = (binaryfunc)gentype_floor_divide,
    .nb_true_divide = (binaryfunc)gentype_true_divide,
};


static PyObject *
gentype_richcompare(PyObject *self, PyObject *other, int cmp_op)
{
    PyObject *arr, *ret;

    /*
     * If the other object is None, False is always right. This avoids
     * the array None comparison, at least until deprecation it is fixed.
     * After that, this may be removed and numpy false would be returned.
     *
     * NOTE: np.equal(NaT, None) evaluates to TRUE! This is an
     *       an inconsistency, which may has to be considered
     *       when the deprecation is finished.
     */
    if (other == Py_None) {
        if (cmp_op == Py_EQ) {
            Py_RETURN_FALSE;
        }
        if (cmp_op == Py_NE) {
            Py_RETURN_TRUE;
        }
    }

   RICHCMP_GIVE_UP_IF_NEEDED(self, other);

    arr = PyArray_FromScalar(self, NULL);
    if (arr == NULL) {
        return NULL;
    }
    /*
     * Call via PyObject_RichCompare to ensure that other.__eq__
     * has a chance to run when necessary
     */
    ret = PyObject_RichCompare(arr, other, cmp_op);
    Py_DECREF(arr);
    return ret;
}

static PyObject *
gentype_ndim_get(PyObject *NPY_UNUSED(self), void *NPY_UNUSED(ignored))
{
    return PyLong_FromLong(0);
}

static PyObject *
gentype_flags_get(PyObject *NPY_UNUSED(self), void *NPY_UNUSED(ignored))
{
    return PyArray_NewFlagsObject(NULL);
}

static PyObject *
voidtype_flags_get(PyVoidScalarObject *self, void *NPY_UNUSED(ignored))
{
    PyObject *flagobj;
    flagobj = PyArrayFlags_Type.tp_alloc(&PyArrayFlags_Type, 0);
    if (flagobj == NULL) {
        return NULL;
    }
    ((PyArrayFlagsObject *)flagobj)->arr = NULL;
    ((PyArrayFlagsObject *)flagobj)->flags = self->flags;
    return flagobj;
}

static PyObject *
voidtype_dtypedescr_get(PyVoidScalarObject *self, void *NPY_UNUSED(ignored))
{
    Py_INCREF(self->descr);
    return (PyObject *)self->descr;
}


static PyObject *
inttype_numerator_get(PyObject *self, void *NPY_UNUSED(ignored))
{
    Py_INCREF(self);
    return self;
}


static PyObject *
inttype_denominator_get(PyObject *self, void *NPY_UNUSED(ignored))
{
    return PyLong_FromLong(1);
}


static PyObject *
gentype_data_get(PyObject *self, void *NPY_UNUSED(ignored))
{
    return PyMemoryView_FromObject(self);
}


static PyObject *
gentype_itemsize_get(PyObject *self, void *NPY_UNUSED(ignored))
{
    PyArray_Descr *typecode;
    PyObject *ret;
    int elsize;

    typecode = PyArray_DescrFromScalar(self);
    elsize = typecode->elsize;
    ret = PyLong_FromLong((long) elsize);
    Py_DECREF(typecode);
    return ret;
}

static PyObject *
gentype_size_get(PyObject *NPY_UNUSED(self), void *NPY_UNUSED(ignored))
{
    return PyLong_FromLong(1);
}

static PyObject *
gentype_sizeof(PyObject *self, PyObject *NPY_UNUSED(args))
{
    Py_ssize_t nbytes;
    PyObject * isz = gentype_itemsize_get(self, NULL);
    if (isz == NULL) {
        return NULL;
    }
    nbytes = PyLong_AsLong(isz) + Py_TYPE(self)->tp_basicsize +
        Py_SIZE(self) * Py_TYPE(self)->tp_itemsize;
    Py_DECREF(isz);
    return PyLong_FromSsize_t(nbytes);
}

NPY_NO_EXPORT void
gentype_struct_free(PyObject *ptr)
{
    PyArrayInterface *arrif = (PyArrayInterface*)PyCapsule_GetPointer(ptr, NULL);
    if (arrif == NULL) {
        PyErr_WriteUnraisable(ptr);
        return;
    }
    PyObject *context = (PyObject *)PyCapsule_GetContext(ptr);
    if (context == NULL && PyErr_Occurred()) {
        PyErr_WriteUnraisable(ptr);
    }
    Py_XDECREF(context);
    Py_XDECREF(arrif->descr);
    PyArray_free(arrif->shape);
    PyArray_free(arrif);
}

static PyObject *
gentype_struct_get(PyObject *self, void *NPY_UNUSED(ignored))
{
    PyArrayObject *arr;
    PyArrayInterface *inter;
    PyObject *ret;

    arr = (PyArrayObject *)PyArray_FromScalar(self, NULL);
    inter = (PyArrayInterface *)PyArray_malloc(sizeof(PyArrayInterface));
    inter->two = 2;
    inter->nd = 0;
    inter->flags = PyArray_FLAGS(arr);
    inter->flags &= ~(NPY_ARRAY_WRITEBACKIFCOPY | NPY_ARRAY_OWNDATA);
    inter->flags |= NPY_ARRAY_NOTSWAPPED;
    inter->typekind = PyArray_DESCR(arr)->kind;
    inter->itemsize = PyArray_DESCR(arr)->elsize;
    inter->strides = NULL;
    inter->shape = NULL;
    inter->data = PyArray_DATA(arr);
    inter->descr = NULL;

    ret = NpyCapsule_FromVoidPtrAndDesc(inter, arr, gentype_struct_free);
    return ret;
}

static PyObject *
gentype_priority_get(PyObject *NPY_UNUSED(self), void *NPY_UNUSED(ignored))
{
    return PyFloat_FromDouble(NPY_SCALAR_PRIORITY);
}

static PyObject *
gentype_shape_get(PyObject *NPY_UNUSED(self), void *NPY_UNUSED(ignored))
{
    return PyTuple_New(0);
}


static PyObject *
gentype_interface_get(PyObject *self, void *NPY_UNUSED(ignored))
{
    PyArrayObject *arr;
    PyObject *inter;

    arr = (PyArrayObject *)PyArray_FromScalar(self, NULL);
    if (arr == NULL) {
        return NULL;
    }
    inter = PyObject_GetAttrString((PyObject *)arr, "__array_interface__");
    if (inter != NULL) {
        PyDict_SetItemString(inter, "__ref", (PyObject *)arr);
    }
    Py_DECREF(arr);
    return inter;
}



static PyObject *
gentype_typedescr_get(PyObject *self, void *NPY_UNUSED(ignored))
{
    return (PyObject *)PyArray_DescrFromScalar(self);
}


static PyObject *
gentype_base_get(PyObject *NPY_UNUSED(self), void *NPY_UNUSED(ignored))
{
    Py_RETURN_NONE;
}

static PyObject *
voidtype_base_get(PyVoidScalarObject *self, void *NPY_UNUSED(ignored))
{
    if (self->base == NULL) {
        Py_RETURN_NONE;
    }
    else {
        Py_INCREF(self->base);
        return self->base;
    }
}


static PyArray_Descr *
_realdescr_fromcomplexscalar(PyObject *self, int *typenum)
{
    if (PyArray_IsScalar(self, CDouble)) {
        *typenum = NPY_CDOUBLE;
        return PyArray_DescrFromType(NPY_DOUBLE);
    }
    if (PyArray_IsScalar(self, CFloat)) {
        *typenum = NPY_CFLOAT;
        return PyArray_DescrFromType(NPY_FLOAT);
    }
    if (PyArray_IsScalar(self, CLongDouble)) {
        *typenum = NPY_CLONGDOUBLE;
        return PyArray_DescrFromType(NPY_LONGDOUBLE);
    }
    return NULL;
}

static PyObject *
gentype_real_get(PyObject *self, void *NPY_UNUSED(ignored))
{
    PyArray_Descr *typecode;
    PyObject *ret;
    int typenum;

    if (PyArray_IsScalar(self, ComplexFloating)) {
        void *ptr;
        typecode = _realdescr_fromcomplexscalar(self, &typenum);
        ptr = scalar_value(self, NULL);
        ret = PyArray_Scalar(ptr, typecode, NULL);
        Py_DECREF(typecode);
        return ret;
    }
    else if (PyArray_IsScalar(self, Object)) {
        PyObject *obj = PyArrayScalar_VAL(self, Object);
        ret = PyObject_GetAttrString(obj, "real");
        if (ret != NULL) {
            return ret;
        }
        PyErr_Clear();
    }
    Py_INCREF(self);
    return (PyObject *)self;
}

static PyObject *
gentype_imag_get(PyObject *self, void *NPY_UNUSED(ignored))
{
    PyArray_Descr *typecode=NULL;
    PyObject *ret;
    int typenum;

    if (PyArray_IsScalar(self, ComplexFloating)) {
        char *ptr;
        typecode = _realdescr_fromcomplexscalar(self, &typenum);
        ptr = (char *)scalar_value(self, NULL);
        ret = PyArray_Scalar(ptr + typecode->elsize, typecode, NULL);
    }
    else if (PyArray_IsScalar(self, Object)) {
        PyObject *obj = PyArrayScalar_VAL(self, Object);
        PyArray_Descr *newtype;
        ret = PyObject_GetAttrString(obj, "imag");
        if (ret == NULL) {
            PyErr_Clear();
            obj = PyLong_FromLong(0);
            newtype = PyArray_DescrFromType(NPY_OBJECT);
            ret = PyArray_Scalar((char *)&obj, newtype, NULL);
            Py_DECREF(newtype);
            Py_DECREF(obj);
        }
    }
    else {
        char *temp;
        int elsize;
        typecode = PyArray_DescrFromScalar(self);
        elsize = typecode->elsize;
        temp = npy_alloc_cache_zero(1, elsize);
        ret = PyArray_Scalar(temp, typecode, NULL);
        npy_free_cache(temp, elsize);
    }

    Py_XDECREF(typecode);
    return ret;
}

static PyObject *
gentype_flat_get(PyObject *self, void *NPY_UNUSED(ignored))
{
    PyObject *ret, *arr;

    arr = PyArray_FromScalar(self, NULL);
    if (arr == NULL) {
        return NULL;
    }
    ret = PyArray_IterNew(arr);
    Py_DECREF(arr);
    return ret;
}


static PyObject *
gentype_transpose_get(PyObject *self, void *NPY_UNUSED(ignored))
{
    Py_INCREF(self);
    return self;
}


static PyGetSetDef gentype_getsets[] = {
    {"ndim",
        (getter)gentype_ndim_get,
        (setter) 0, NULL, NULL},
    {"flags",
        (getter)gentype_flags_get,
        (setter)0, NULL, NULL},
    {"shape",
        (getter)gentype_shape_get,
        (setter)0, NULL, NULL},
    {"strides",
        (getter)gentype_shape_get,
        (setter) 0, NULL, NULL},
    {"data",
        (getter)gentype_data_get,
        (setter) 0, NULL, NULL},
    {"itemsize",
        (getter)gentype_itemsize_get,
        (setter)0, NULL, NULL},
    {"size",
        (getter)gentype_size_get,
        (setter)0, NULL, NULL},
    {"nbytes",
        (getter)gentype_itemsize_get,
        (setter)0, NULL, NULL},
    {"base",
        (getter)gentype_base_get,
        (setter)0, NULL, NULL},
    {"dtype",
        (getter)gentype_typedescr_get,
        NULL, NULL, NULL},
    {"real",
        (getter)gentype_real_get,
        (setter)0, NULL, NULL},
    {"imag",
        (getter)gentype_imag_get,
        (setter)0, NULL, NULL},
    {"flat",
        (getter)gentype_flat_get,
        (setter)0, NULL, NULL},
    {"T",
        (getter)gentype_transpose_get,
        (setter)0, NULL, NULL},
    {"__array_interface__",
        (getter)gentype_interface_get,
        NULL,
        "Array protocol: Python side",
        NULL},
    {"__array_struct__",
        (getter)gentype_struct_get,
        NULL,
        "Array protocol: struct",
        NULL},
    {"__array_priority__",
        (getter)gentype_priority_get,
        NULL,
        "Array priority.",
        NULL},
    {NULL, NULL, NULL, NULL, NULL}  /* Sentinel */
};


/* 0-dim array from scalar object */

static char doc_getarray[] = "sc.__array__(dtype) return 0-dim array from "
                             "scalar with specified dtype";

static PyObject *
gentype_getarray(PyObject *scalar, PyObject *args)
{
    PyArray_Descr *outcode=NULL;
    PyObject *ret;

    if (!PyArg_ParseTuple(args, "|O&:__array__", &PyArray_DescrConverter,
                &outcode)) {
        Py_XDECREF(outcode);
        return NULL;
    }
    ret = PyArray_FromScalar(scalar, outcode);
    return ret;
}

static char doc_sc_wraparray[] = "sc.__array_wrap__(obj) return scalar from array";

static PyObject *
gentype_wraparray(PyObject *NPY_UNUSED(scalar), PyObject *args)
{
    PyObject *obj;
    PyArrayObject *arr;

    if (PyTuple_Size(args) < 1) {
        PyErr_SetString(PyExc_TypeError,
                "only accepts 1 argument.");
        return NULL;
    }
    obj = PyTuple_GET_ITEM(args, 0);
    if (!PyArray_Check(obj)) {
        PyErr_SetString(PyExc_TypeError,
                "can only be called with ndarray object");
        return NULL;
    }
    arr = (PyArrayObject *)obj;

    return PyArray_Scalar(PyArray_DATA(arr),
                    PyArray_DESCR(arr), (PyObject *)arr);
}

/*
 * These gentype_* functions do not take keyword arguments.
 * The proper flag is METH_VARARGS.
 */
#line 1550
static PyObject *
gentype_tolist(PyObject *self, PyObject *args)
{
    return gentype_generic_method(self, args, NULL, "tolist");
}

#line 1550
static PyObject *
gentype_item(PyObject *self, PyObject *args)
{
    return gentype_generic_method(self, args, NULL, "item");
}

#line 1550
static PyObject *
gentype___deepcopy__(PyObject *self, PyObject *args)
{
    return gentype_generic_method(self, args, NULL, "__deepcopy__");
}

#line 1550
static PyObject *
gentype___copy__(PyObject *self, PyObject *args)
{
    return gentype_generic_method(self, args, NULL, "__copy__");
}

#line 1550
static PyObject *
gentype_swapaxes(PyObject *self, PyObject *args)
{
    return gentype_generic_method(self, args, NULL, "swapaxes");
}

#line 1550
static PyObject *
gentype_conj(PyObject *self, PyObject *args)
{
    return gentype_generic_method(self, args, NULL, "conj");
}

#line 1550
static PyObject *
gentype_conjugate(PyObject *self, PyObject *args)
{
    return gentype_generic_method(self, args, NULL, "conjugate");
}

#line 1550
static PyObject *
gentype_nonzero(PyObject *self, PyObject *args)
{
    return gentype_generic_method(self, args, NULL, "nonzero");
}

#line 1550
static PyObject *
gentype_fill(PyObject *self, PyObject *args)
{
    return gentype_generic_method(self, args, NULL, "fill");
}

#line 1550
static PyObject *
gentype_transpose(PyObject *self, PyObject *args)
{
    return gentype_generic_method(self, args, NULL, "transpose");
}

#line 1550
static PyObject *
gentype_newbyteorder(PyObject *self, PyObject *args)
{
    return gentype_generic_method(self, args, NULL, "newbyteorder");
}


static PyObject *
gentype_itemset(PyObject *NPY_UNUSED(self), PyObject *NPY_UNUSED(args))
{
    PyErr_SetString(PyExc_ValueError, "array-scalars are immutable");
    return NULL;
}

static PyObject *
gentype_byteswap(PyObject *self, PyObject *args, PyObject *kwds)
{
    npy_bool inplace = NPY_FALSE;
    static char *kwlist[] = {"inplace", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&:byteswap", kwlist,
                                     PyArray_BoolConverter, &inplace)) {
        return NULL;
    }
    if (inplace) {
        PyErr_SetString(PyExc_ValueError,
                "cannot byteswap a scalar in-place");
        return NULL;
    }
    else {
        /* get the data, copyswap it and pass it to a new Array scalar */
        char *data;
        PyArray_Descr *descr;
        PyObject *new;
        char *newmem;

        descr = PyArray_DescrFromScalar(self);
        data = (void *)scalar_value(self, descr);

        newmem = PyObject_Malloc(descr->elsize);
        if (newmem == NULL) {
            Py_DECREF(descr);
            return PyErr_NoMemory();
        }
        else {
            descr->f->copyswap(newmem, data, 1, NULL);
        }
        new = PyArray_Scalar(newmem, descr, NULL);
        PyObject_Free(newmem);
        Py_DECREF(descr);
        return new;
    }
}


/*
 * These gentype_* functions take keyword arguments.
 * The proper flag is METH_VARARGS | METH_KEYWORDS.
 */
#line 1617
static PyObject *
gentype_take(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "take");
}

#line 1617
static PyObject *
gentype_getfield(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "getfield");
}

#line 1617
static PyObject *
gentype_put(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "put");
}

#line 1617
static PyObject *
gentype_repeat(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "repeat");
}

#line 1617
static PyObject *
gentype_tofile(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "tofile");
}

#line 1617
static PyObject *
gentype_mean(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "mean");
}

#line 1617
static PyObject *
gentype_trace(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "trace");
}

#line 1617
static PyObject *
gentype_diagonal(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "diagonal");
}

#line 1617
static PyObject *
gentype_clip(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "clip");
}

#line 1617
static PyObject *
gentype_std(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "std");
}

#line 1617
static PyObject *
gentype_var(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "var");
}

#line 1617
static PyObject *
gentype_sum(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "sum");
}

#line 1617
static PyObject *
gentype_cumsum(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "cumsum");
}

#line 1617
static PyObject *
gentype_prod(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "prod");
}

#line 1617
static PyObject *
gentype_cumprod(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "cumprod");
}

#line 1617
static PyObject *
gentype_compress(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "compress");
}

#line 1617
static PyObject *
gentype_sort(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "sort");
}

#line 1617
static PyObject *
gentype_argsort(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "argsort");
}

#line 1617
static PyObject *
gentype_round(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "round");
}

#line 1617
static PyObject *
gentype_argmax(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "argmax");
}

#line 1617
static PyObject *
gentype_argmin(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "argmin");
}

#line 1617
static PyObject *
gentype_max(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "max");
}

#line 1617
static PyObject *
gentype_min(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "min");
}

#line 1617
static PyObject *
gentype_ptp(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "ptp");
}

#line 1617
static PyObject *
gentype_any(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "any");
}

#line 1617
static PyObject *
gentype_all(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "all");
}

#line 1617
static PyObject *
gentype_astype(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "astype");
}

#line 1617
static PyObject *
gentype_resize(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "resize");
}

#line 1617
static PyObject *
gentype_reshape(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "reshape");
}

#line 1617
static PyObject *
gentype_choose(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "choose");
}

#line 1617
static PyObject *
gentype_tostring(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "tostring");
}

#line 1617
static PyObject *
gentype_tobytes(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "tobytes");
}

#line 1617
static PyObject *
gentype_copy(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "copy");
}

#line 1617
static PyObject *
gentype_searchsorted(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "searchsorted");
}

#line 1617
static PyObject *
gentype_view(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "view");
}

#line 1617
static PyObject *
gentype_flatten(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "flatten");
}

#line 1617
static PyObject *
gentype_ravel(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "ravel");
}

#line 1617
static PyObject *
gentype_squeeze(PyObject *self, PyObject *args, PyObject *kwds)
{
    return gentype_generic_method(self, args, kwds, "squeeze");
}



#line 1629
static PyObject *
integertype_dunder_round(PyObject *self, PyObject *args, PyObject *kwds)
{
    static char *kwlist[] = {"ndigits", NULL};
    PyObject *ndigits = Py_None;
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:__round__", kwlist, &ndigits)) {
        return NULL;
    }

#if 0
    if (DEPRECATE("The Python built-in `round` is deprecated for complex "
                  "scalars, and will raise a `TypeError` in a future release. "
                  "Use `np.round` or `scalar.round` instead.") < 0) {
        return NULL;
    }
#endif

    PyObject *tup;
    if (ndigits == Py_None) {
        tup = PyTuple_Pack(0);
    }
    else {
        tup = PyTuple_Pack(1, ndigits);
    }

    if (tup == NULL) {
        return NULL;
    }

    PyObject *obj = gentype_round(self, tup, NULL);
    Py_DECREF(tup);
    if (obj == NULL) {
        return NULL;
    }

#if !0
    if (ndigits == Py_None) {
        PyObject *ret = PyNumber_Long(obj);
        Py_DECREF(obj);
        return ret;
    }
#endif

    return obj;
}

#line 1629
static PyObject *
floatingtype_dunder_round(PyObject *self, PyObject *args, PyObject *kwds)
{
    static char *kwlist[] = {"ndigits", NULL};
    PyObject *ndigits = Py_None;
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:__round__", kwlist, &ndigits)) {
        return NULL;
    }

#if 0
    if (DEPRECATE("The Python built-in `round` is deprecated for complex "
                  "scalars, and will raise a `TypeError` in a future release. "
                  "Use `np.round` or `scalar.round` instead.") < 0) {
        return NULL;
    }
#endif

    PyObject *tup;
    if (ndigits == Py_None) {
        tup = PyTuple_Pack(0);
    }
    else {
        tup = PyTuple_Pack(1, ndigits);
    }

    if (tup == NULL) {
        return NULL;
    }

    PyObject *obj = gentype_round(self, tup, NULL);
    Py_DECREF(tup);
    if (obj == NULL) {
        return NULL;
    }

#if !0
    if (ndigits == Py_None) {
        PyObject *ret = PyNumber_Long(obj);
        Py_DECREF(obj);
        return ret;
    }
#endif

    return obj;
}

#line 1629
static PyObject *
complexfloatingtype_dunder_round(PyObject *self, PyObject *args, PyObject *kwds)
{
    static char *kwlist[] = {"ndigits", NULL};
    PyObject *ndigits = Py_None;
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:__round__", kwlist, &ndigits)) {
        return NULL;
    }

#if 1
    if (DEPRECATE("The Python built-in `round` is deprecated for complex "
                  "scalars, and will raise a `TypeError` in a future release. "
                  "Use `np.round` or `scalar.round` instead.") < 0) {
        return NULL;
    }
#endif

    PyObject *tup;
    if (ndigits == Py_None) {
        tup = PyTuple_Pack(0);
    }
    else {
        tup = PyTuple_Pack(1, ndigits);
    }

    if (tup == NULL) {
        return NULL;
    }

    PyObject *obj = gentype_round(self, tup, NULL);
    Py_DECREF(tup);
    if (obj == NULL) {
        return NULL;
    }

#if !1
    if (ndigits == Py_None) {
        PyObject *ret = PyNumber_Long(obj);
        Py_DECREF(obj);
        return ret;
    }
#endif

    return obj;
}


static PyObject *
voidtype_getfield(PyVoidScalarObject *self, PyObject *args, PyObject *kwds)
{
    /* Use ndarray's getfield to obtain the field safely */
    return gentype_generic_method((PyObject *)self, args, kwds, "getfield");
}

static PyObject *
gentype_setfield(PyObject *NPY_UNUSED(self), PyObject *NPY_UNUSED(args),
                 PyObject *NPY_UNUSED(kwds))
{
    PyErr_SetString(PyExc_TypeError,
            "Can't set fields in a non-void array scalar.");
    return NULL;
}

static PyObject *
voidtype_setfield(PyVoidScalarObject *self, PyObject *args, PyObject *kwds)
{
    /*
     * We would like to use ndarray's setfield because it performs safety
     * checks on the field datatypes and because it broadcasts properly.
     * However, as a special case, void-scalar assignment broadcasts
     * differently from ndarrays when assigning to an object field: Assignment
     * to an ndarray object field broadcasts, but assignment to a void-scalar
     * object-field should not, in order to allow nested ndarrays.
     * These lines should then behave identically:
     *
     *     b = np.zeros(1, dtype=[('x', 'O')])
     *     b[0]['x'] = arange(3)  # uses voidtype_setfield
     *     b['x'][0] = arange(3)  # uses ndarray setitem
     *
     * Ndarray's setfield would try to broadcast the lhs. Instead we use
     * ndarray getfield to get the field safely, then setitem with an empty
     * tuple to set the value without broadcast. Note we also want subarrays to
     * be set properly, ie
     *
     *     a = np.zeros(1, dtype=[('x', 'i', 5)])
     *     a[0]['x'] = 1
     *
     * sets all values to 1. "getfield + setitem with empty tuple" takes
     * care of both object arrays and subarrays.
     */
    PyObject *getfield_args, *value, *arr, *meth, *arr_field, *emptytuple;

    value = PyTuple_GetItem(args, 0);
    if (value == NULL) {
        return NULL;
    }
    getfield_args = PyTuple_GetSlice(args, 1, 3);
    if (getfield_args == NULL) {
        return NULL;
    }

    /* 1. Convert to 0-d array and use getfield */
    arr = PyArray_FromScalar((PyObject*)self, NULL);
    if (arr == NULL) {
        Py_DECREF(getfield_args);
        return NULL;
    }
    meth = PyObject_GetAttrString(arr, "getfield");
    if (meth == NULL) {
        Py_DECREF(getfield_args);
        Py_DECREF(arr);
        return NULL;
    }
    if (kwds == NULL) {
        arr_field = PyObject_CallObject(meth, getfield_args);
    }
    else {
        arr_field = PyObject_Call(meth, getfield_args, kwds);
    }
    Py_DECREF(getfield_args);
    Py_DECREF(meth);
    Py_DECREF(arr);

    if(arr_field == NULL){
        return NULL;
    }

    /* 2. Assign the value using setitem with empty tuple. */
    emptytuple = PyTuple_New(0);
    if (PyObject_SetItem(arr_field, emptytuple, value) < 0) {
        Py_DECREF(arr_field);
        Py_DECREF(emptytuple);
        return NULL;
    }
    Py_DECREF(emptytuple);
    Py_DECREF(arr_field);

    Py_RETURN_NONE;
}


static PyObject *
gentype_reduce(PyObject *self, PyObject *NPY_UNUSED(args))
{
    PyObject *ret = NULL, *obj = NULL, *mod = NULL;
    Py_buffer view;
    const char *buffer;
    Py_ssize_t buflen;

    /* Return a tuple of (callable object, arguments) */
    ret = PyTuple_New(2);
    if (ret == NULL) {
        return NULL;
    }

    if (PyObject_GetBuffer(self, &view, PyBUF_SIMPLE) >= 0) {
        buffer = view.buf;
        buflen = view.len;
        /*
         * In Python 3 both of the deprecated functions PyObject_AsWriteBuffer and
         * PyObject_AsReadBuffer that this code replaces release the buffer. It is
         * up to the object that supplies the buffer to guarantee that the buffer
         * sticks around after the release.
         */
        PyBuffer_Release(&view);
    }
    else {
        Py_DECREF(ret);
        return NULL;
    }

    mod = PyImport_ImportModule("numpy.core._multiarray_umath");
    if (mod == NULL) {
        Py_DECREF(ret);
        return NULL;
    }
    obj = PyObject_GetAttrString(mod, "scalar");
    Py_DECREF(mod);
    if (obj == NULL) {
        Py_DECREF(ret);
        return NULL;
    }
    PyTuple_SET_ITEM(ret, 0, obj);
    obj = PyObject_GetAttrString((PyObject *)self, "dtype");
    if (PyArray_IsScalar(self, Object)) {
        PyObject *val = PyArrayScalar_VAL(self, Object);
        PyObject *tup = Py_BuildValue("NO", obj, val);
        if (tup == NULL) {
            Py_DECREF(ret);
            return NULL;
        }
        PyTuple_SET_ITEM(ret, 1, tup);
    }
    else if (obj && PyDataType_FLAGCHK((PyArray_Descr *)obj, NPY_LIST_PICKLE)) {
        /* a structured dtype with an object in a field */
        PyArrayObject *arr = (PyArrayObject *)PyArray_FromScalar(self, NULL);
        if (arr == NULL) {
            Py_DECREF(ret);
            return NULL;
        }
        /* Use the whole array which handles sturctured void correctly */
        PyObject *tup = Py_BuildValue("NN", obj, arr);
        if (tup == NULL) {
            Py_DECREF(ret);
            return NULL;
        }
        PyTuple_SET_ITEM(ret, 1, tup);
    }
    else {
        mod = PyBytes_FromStringAndSize(buffer, buflen);
        if (mod == NULL) {
            Py_DECREF(ret);
            return NULL;
        }
        PyTuple_SET_ITEM(ret, 1,
                Py_BuildValue("NN", obj, mod));
    }
    return ret;
}

/* ignores everything */
static PyObject *
gentype_setstate(PyObject *NPY_UNUSED(self), PyObject *NPY_UNUSED(args))
{
    Py_RETURN_NONE;
}

static PyObject *
gentype_dump(PyObject *self, PyObject *args)
{
    PyObject *file = NULL;
    int ret;

    if (!PyArg_ParseTuple(args, "O:dump", &file)) {
        return NULL;
    }
    ret = PyArray_Dump(self, file, 2);
    if (ret < 0) {
        return NULL;
    }
    Py_RETURN_NONE;
}

static PyObject *
gentype_dumps(PyObject *self, PyObject *args)
{
    if (!PyArg_ParseTuple(args, "")) {
        return NULL;
    }
    return PyArray_Dumps(self, 2);
}


/* setting flags cannot be done for scalars */
static PyObject *
gentype_setflags(PyObject *NPY_UNUSED(self), PyObject *NPY_UNUSED(args),
        PyObject *NPY_UNUSED(kwds))
{
    Py_RETURN_NONE;
}

static PyObject *
numbertype_class_getitem_abc(PyObject *cls, PyObject *args)
{
    const Py_ssize_t args_len = PyTuple_Check(args) ? PyTuple_Size(args) : 1;
    int args_len_expected;

    /* complexfloating should take 2 parameters, all others take 1 */
    if (PyType_IsSubtype((PyTypeObject *)cls,
                         &PyComplexFloatingArrType_Type)) {
        args_len_expected = 2;
    }
    else {
        args_len_expected = 1;
    }

    if ((args_len > args_len_expected) || (args_len == 0)) {
        return PyErr_Format(PyExc_TypeError,
                            "Too %s arguments for %s",
                            args_len > args_len_expected ? "many" : "few",
                            ((PyTypeObject *)cls)->tp_name);
    }
    return Py_GenericAlias(cls, args);
}

/*
 * Use for concrete np.number subclasses, making them act as if they
 * were subtyped from e.g. np.signedinteger[object], thus lacking any
 * free subscription parameters. Requires python >= 3.9.
 */
static PyObject *
numbertype_class_getitem(PyObject *cls, PyObject *args)
{
    PyErr_Format(PyExc_TypeError,
                 "There are no type variables left in %s",
                 ((PyTypeObject *)cls)->tp_name);
    return NULL;
}

/*
 * casting complex numbers (that don't inherit from Python complex)
 * to Python complex
 */

#line 1937
static PyObject *
cfloat_complex(PyObject *self, PyObject *NPY_UNUSED(args),
               PyObject *NPY_UNUSED(kwds))
{
    return PyComplex_FromDoubles(PyArrayScalar_VAL(self, CFloat).real,
                                 PyArrayScalar_VAL(self, CFloat).imag);
}

#line 1937
static PyObject *
clongdouble_complex(PyObject *self, PyObject *NPY_UNUSED(args),
               PyObject *NPY_UNUSED(kwds))
{
    return PyComplex_FromDoubles(PyArrayScalar_VAL(self, CLongDouble).real,
                                 PyArrayScalar_VAL(self, CLongDouble).imag);
}


#line 1955
/* Heavily copied from the builtin float.as_integer_ratio */
static PyObject *
half_as_integer_ratio(PyObject *self, PyObject *NPY_UNUSED(args))
{
#if 1
    npy_double val = npy_half_to_double(PyArrayScalar_VAL(self, Half));
    npy_double frac;
#else
    npy_half val = PyArrayScalar_VAL(self, Half);
    npy_half frac;
#endif
    int exponent;
    int i;

    PyObject *py_exponent = NULL;
    PyObject *numerator = NULL;
    PyObject *denominator = NULL;
    PyObject *result_pair = NULL;
    PyNumberMethods *long_methods = PyLong_Type.tp_as_number;

    if (npy_isnan(val)) {
        PyErr_SetString(PyExc_ValueError,
                        "cannot convert NaN to integer ratio");
        return NULL;
    }
    if (!npy_isfinite(val)) {
        PyErr_SetString(PyExc_OverflowError,
                        "cannot convert Infinity to integer ratio");
        return NULL;
    }

    frac = npy_frexpf(val, &exponent); /* val == frac * 2**exponent exactly */

    /* This relies on the floating point type being base 2 to converge */
    for (i = 0; frac != npy_floorf(frac); i++) {
        frac *= 2.0;
        exponent--;
    }

    /* self == frac * 2**exponent exactly and frac is integral. */
    numerator = PyLong_FromDouble(frac);
    if (numerator == NULL)
        goto error;
    denominator = PyLong_FromLong(1);
    if (denominator == NULL)
        goto error;
    py_exponent = PyLong_FromLong(exponent < 0 ? -exponent : exponent);
    if (py_exponent == NULL)
        goto error;

    /* fold in 2**exponent */
    if (exponent > 0) {
        PyObject *temp = long_methods->nb_lshift(numerator, py_exponent);
        if (temp == NULL)
            goto error;
        Py_DECREF(numerator);
        numerator = temp;
    }
    else {
        PyObject *temp = long_methods->nb_lshift(denominator, py_exponent);
        if (temp == NULL)
            goto error;
        Py_DECREF(denominator);
        denominator = temp;
    }

    result_pair = PyTuple_Pack(2, numerator, denominator);

error:
    Py_XDECREF(py_exponent);
    Py_XDECREF(denominator);
    Py_XDECREF(numerator);
    return result_pair;
}

#line 1955
/* Heavily copied from the builtin float.as_integer_ratio */
static PyObject *
float_as_integer_ratio(PyObject *self, PyObject *NPY_UNUSED(args))
{
#if 0
    npy_double val = npy_half_to_double(PyArrayScalar_VAL(self, Float));
    npy_double frac;
#else
    npy_float val = PyArrayScalar_VAL(self, Float);
    npy_float frac;
#endif
    int exponent;
    int i;

    PyObject *py_exponent = NULL;
    PyObject *numerator = NULL;
    PyObject *denominator = NULL;
    PyObject *result_pair = NULL;
    PyNumberMethods *long_methods = PyLong_Type.tp_as_number;

    if (npy_isnan(val)) {
        PyErr_SetString(PyExc_ValueError,
                        "cannot convert NaN to integer ratio");
        return NULL;
    }
    if (!npy_isfinite(val)) {
        PyErr_SetString(PyExc_OverflowError,
                        "cannot convert Infinity to integer ratio");
        return NULL;
    }

    frac = npy_frexpf(val, &exponent); /* val == frac * 2**exponent exactly */

    /* This relies on the floating point type being base 2 to converge */
    for (i = 0; frac != npy_floorf(frac); i++) {
        frac *= 2.0;
        exponent--;
    }

    /* self == frac * 2**exponent exactly and frac is integral. */
    numerator = PyLong_FromDouble(frac);
    if (numerator == NULL)
        goto error;
    denominator = PyLong_FromLong(1);
    if (denominator == NULL)
        goto error;
    py_exponent = PyLong_FromLong(exponent < 0 ? -exponent : exponent);
    if (py_exponent == NULL)
        goto error;

    /* fold in 2**exponent */
    if (exponent > 0) {
        PyObject *temp = long_methods->nb_lshift(numerator, py_exponent);
        if (temp == NULL)
            goto error;
        Py_DECREF(numerator);
        numerator = temp;
    }
    else {
        PyObject *temp = long_methods->nb_lshift(denominator, py_exponent);
        if (temp == NULL)
            goto error;
        Py_DECREF(denominator);
        denominator = temp;
    }

    result_pair = PyTuple_Pack(2, numerator, denominator);

error:
    Py_XDECREF(py_exponent);
    Py_XDECREF(denominator);
    Py_XDECREF(numerator);
    return result_pair;
}

#line 1955
/* Heavily copied from the builtin float.as_integer_ratio */
static PyObject *
double_as_integer_ratio(PyObject *self, PyObject *NPY_UNUSED(args))
{
#if 0
    npy_double val = npy_half_to_double(PyArrayScalar_VAL(self, Double));
    npy_double frac;
#else
    npy_double val = PyArrayScalar_VAL(self, Double);
    npy_double frac;
#endif
    int exponent;
    int i;

    PyObject *py_exponent = NULL;
    PyObject *numerator = NULL;
    PyObject *denominator = NULL;
    PyObject *result_pair = NULL;
    PyNumberMethods *long_methods = PyLong_Type.tp_as_number;

    if (npy_isnan(val)) {
        PyErr_SetString(PyExc_ValueError,
                        "cannot convert NaN to integer ratio");
        return NULL;
    }
    if (!npy_isfinite(val)) {
        PyErr_SetString(PyExc_OverflowError,
                        "cannot convert Infinity to integer ratio");
        return NULL;
    }

    frac = npy_frexp(val, &exponent); /* val == frac * 2**exponent exactly */

    /* This relies on the floating point type being base 2 to converge */
    for (i = 0; frac != npy_floor(frac); i++) {
        frac *= 2.0;
        exponent--;
    }

    /* self == frac * 2**exponent exactly and frac is integral. */
    numerator = PyLong_FromDouble(frac);
    if (numerator == NULL)
        goto error;
    denominator = PyLong_FromLong(1);
    if (denominator == NULL)
        goto error;
    py_exponent = PyLong_FromLong(exponent < 0 ? -exponent : exponent);
    if (py_exponent == NULL)
        goto error;

    /* fold in 2**exponent */
    if (exponent > 0) {
        PyObject *temp = long_methods->nb_lshift(numerator, py_exponent);
        if (temp == NULL)
            goto error;
        Py_DECREF(numerator);
        numerator = temp;
    }
    else {
        PyObject *temp = long_methods->nb_lshift(denominator, py_exponent);
        if (temp == NULL)
            goto error;
        Py_DECREF(denominator);
        denominator = temp;
    }

    result_pair = PyTuple_Pack(2, numerator, denominator);

error:
    Py_XDECREF(py_exponent);
    Py_XDECREF(denominator);
    Py_XDECREF(numerator);
    return result_pair;
}

#line 1955
/* Heavily copied from the builtin float.as_integer_ratio */
static PyObject *
longdouble_as_integer_ratio(PyObject *self, PyObject *NPY_UNUSED(args))
{
#if 0
    npy_double val = npy_half_to_double(PyArrayScalar_VAL(self, LongDouble));
    npy_double frac;
#else
    npy_longdouble val = PyArrayScalar_VAL(self, LongDouble);
    npy_longdouble frac;
#endif
    int exponent;
    int i;

    PyObject *py_exponent = NULL;
    PyObject *numerator = NULL;
    PyObject *denominator = NULL;
    PyObject *result_pair = NULL;
    PyNumberMethods *long_methods = PyLong_Type.tp_as_number;

    if (npy_isnan(val)) {
        PyErr_SetString(PyExc_ValueError,
                        "cannot convert NaN to integer ratio");
        return NULL;
    }
    if (!npy_isfinite(val)) {
        PyErr_SetString(PyExc_OverflowError,
                        "cannot convert Infinity to integer ratio");
        return NULL;
    }

    frac = npy_frexpl(val, &exponent); /* val == frac * 2**exponent exactly */

    /* This relies on the floating point type being base 2 to converge */
    for (i = 0; frac != npy_floorl(frac); i++) {
        frac *= 2.0;
        exponent--;
    }

    /* self == frac * 2**exponent exactly and frac is integral. */
    numerator = npy_longdouble_to_PyLong(frac);
    if (numerator == NULL)
        goto error;
    denominator = PyLong_FromLong(1);
    if (denominator == NULL)
        goto error;
    py_exponent = PyLong_FromLong(exponent < 0 ? -exponent : exponent);
    if (py_exponent == NULL)
        goto error;

    /* fold in 2**exponent */
    if (exponent > 0) {
        PyObject *temp = long_methods->nb_lshift(numerator, py_exponent);
        if (temp == NULL)
            goto error;
        Py_DECREF(numerator);
        numerator = temp;
    }
    else {
        PyObject *temp = long_methods->nb_lshift(denominator, py_exponent);
        if (temp == NULL)
            goto error;
        Py_DECREF(denominator);
        denominator = temp;
    }

    result_pair = PyTuple_Pack(2, numerator, denominator);

error:
    Py_XDECREF(py_exponent);
    Py_XDECREF(denominator);
    Py_XDECREF(numerator);
    return result_pair;
}


#line 2037
static PyObject *
half_is_integer(PyObject *self, PyObject *NPY_UNUSED(args))
{
#if 1
    npy_double val = npy_half_to_double(PyArrayScalar_VAL(self, Half));
#else
    npy_half val = PyArrayScalar_VAL(self, Half);
#endif
    PyObject *ret;

    if (npy_isnan(val)) {
        Py_RETURN_FALSE;
    }
    if (!npy_isfinite(val)) {
        Py_RETURN_FALSE;
    }

    ret = (npy_floorf(val) == val) ? Py_True : Py_False;
    Py_INCREF(ret);
    return ret;
}

#line 2037
static PyObject *
float_is_integer(PyObject *self, PyObject *NPY_UNUSED(args))
{
#if 0
    npy_double val = npy_half_to_double(PyArrayScalar_VAL(self, Float));
#else
    npy_float val = PyArrayScalar_VAL(self, Float);
#endif
    PyObject *ret;

    if (npy_isnan(val)) {
        Py_RETURN_FALSE;
    }
    if (!npy_isfinite(val)) {
        Py_RETURN_FALSE;
    }

    ret = (npy_floorf(val) == val) ? Py_True : Py_False;
    Py_INCREF(ret);
    return ret;
}

#line 2037
static PyObject *
double_is_integer(PyObject *self, PyObject *NPY_UNUSED(args))
{
#if 0
    npy_double val = npy_half_to_double(PyArrayScalar_VAL(self, Double));
#else
    npy_double val = PyArrayScalar_VAL(self, Double);
#endif
    PyObject *ret;

    if (npy_isnan(val)) {
        Py_RETURN_FALSE;
    }
    if (!npy_isfinite(val)) {
        Py_RETURN_FALSE;
    }

    ret = (npy_floor(val) == val) ? Py_True : Py_False;
    Py_INCREF(ret);
    return ret;
}

#line 2037
static PyObject *
longdouble_is_integer(PyObject *self, PyObject *NPY_UNUSED(args))
{
#if 0
    npy_double val = npy_half_to_double(PyArrayScalar_VAL(self, LongDouble));
#else
    npy_longdouble val = PyArrayScalar_VAL(self, LongDouble);
#endif
    PyObject *ret;

    if (npy_isnan(val)) {
        Py_RETURN_FALSE;
    }
    if (!npy_isfinite(val)) {
        Py_RETURN_FALSE;
    }

    ret = (npy_floorl(val) == val) ? Py_True : Py_False;
    Py_INCREF(ret);
    return ret;
}


static PyObject *
integer_is_integer(PyObject *self, PyObject *NPY_UNUSED(args)) {
    Py_RETURN_TRUE;
}

/*
 * need to fill in doc-strings for these methods on import -- copy from
 * array docstrings
 */
static PyMethodDef gentype_methods[] = {
    {"tolist",
        (PyCFunction)gentype_tolist,
        METH_VARARGS, NULL},
    {"item",
        (PyCFunction)gentype_item,
        METH_VARARGS, NULL},
    {"itemset",
        (PyCFunction)gentype_itemset,
        METH_VARARGS, NULL},
    {"tobytes",
        (PyCFunction)gentype_tobytes,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"tofile",
        (PyCFunction)gentype_tofile,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"tostring",
        (PyCFunction)gentype_tostring,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"byteswap",
        (PyCFunction)gentype_byteswap,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"astype",
        (PyCFunction)gentype_astype,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"getfield",
        (PyCFunction)gentype_getfield,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"setfield",
        (PyCFunction)gentype_setfield,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"copy",
        (PyCFunction)gentype_copy,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"resize",
        (PyCFunction)gentype_resize,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"__array__",
        (PyCFunction)gentype_getarray,
        METH_VARARGS, doc_getarray},
    {"__array_wrap__",
        (PyCFunction)gentype_wraparray,
        METH_VARARGS, doc_sc_wraparray},

    /* for the sys module */
    {"__sizeof__",
        (PyCFunction)gentype_sizeof,
        METH_NOARGS, NULL},

    /* for the copy module */
    {"__copy__",
        (PyCFunction)gentype___copy__,
        METH_VARARGS, NULL},
    {"__deepcopy__",
        (PyCFunction)gentype___deepcopy__,
        METH_VARARGS, NULL},

    {"__reduce__",
        (PyCFunction) gentype_reduce,
        METH_VARARGS, NULL},
    /* For consistency does nothing */
    {"__setstate__",
        (PyCFunction) gentype_setstate,
        METH_VARARGS, NULL},

    {"dumps",
        (PyCFunction) gentype_dumps,
        METH_VARARGS, NULL},
    {"dump",
        (PyCFunction) gentype_dump,
        METH_VARARGS, NULL},

    /* Methods for array */
    {"fill",
        (PyCFunction)gentype_fill,
        METH_VARARGS, NULL},
    {"transpose",
        (PyCFunction)gentype_transpose,
        METH_VARARGS, NULL},
    {"take",
        (PyCFunction)gentype_take,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"put",
        (PyCFunction)gentype_put,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"repeat",
        (PyCFunction)gentype_repeat,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"choose",
        (PyCFunction)gentype_choose,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"sort",
        (PyCFunction)gentype_sort,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"argsort",
        (PyCFunction)gentype_argsort,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"searchsorted",
        (PyCFunction)gentype_searchsorted,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"argmax",
        (PyCFunction)gentype_argmax,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"argmin",
        (PyCFunction)gentype_argmin,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"reshape",
        (PyCFunction)gentype_reshape,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"squeeze",
        (PyCFunction)gentype_squeeze,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"view",
        (PyCFunction)gentype_view,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"swapaxes",
        (PyCFunction)gentype_swapaxes,
        METH_VARARGS, NULL},
    {"max",
        (PyCFunction)gentype_max,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"min",
        (PyCFunction)gentype_min,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"ptp",
        (PyCFunction)gentype_ptp,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"mean",
        (PyCFunction)gentype_mean,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"trace",
        (PyCFunction)gentype_trace,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"diagonal",
        (PyCFunction)gentype_diagonal,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"clip",
        (PyCFunction)gentype_clip,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"conj",
        (PyCFunction)gentype_conj,
        METH_VARARGS, NULL},
    {"conjugate",
        (PyCFunction)gentype_conjugate,
        METH_VARARGS, NULL},
    {"nonzero",
        (PyCFunction)gentype_nonzero,
        METH_VARARGS, NULL},
    {"std",
        (PyCFunction)gentype_std,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"var",
        (PyCFunction)gentype_var,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"sum",
        (PyCFunction)gentype_sum,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"cumsum",
        (PyCFunction)gentype_cumsum,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"prod",
        (PyCFunction)gentype_prod,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"cumprod",
        (PyCFunction)gentype_cumprod,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"all",
        (PyCFunction)gentype_all,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"any",
        (PyCFunction)gentype_any,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"compress",
        (PyCFunction)gentype_compress,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"flatten",
        (PyCFunction)gentype_flatten,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"ravel",
        (PyCFunction)gentype_ravel,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"round",
        (PyCFunction)gentype_round,
        METH_VARARGS | METH_KEYWORDS, NULL},
    /* For the format function */
    {"__format__",
        gentype_format,
        METH_VARARGS,
        "NumPy array scalar formatter"},
    {"setflags",
        (PyCFunction)gentype_setflags,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"newbyteorder",
        (PyCFunction)gentype_newbyteorder,
        METH_VARARGS, NULL},
    {NULL, NULL, 0, NULL} /* sentinel */
};


static PyGetSetDef voidtype_getsets[] = {
    {"flags",
        (getter)voidtype_flags_get,
        (setter)0,
        "integer value of flags",
        NULL},
    {"dtype",
        (getter)voidtype_dtypedescr_get,
        (setter)0,
        "dtype object",
        NULL},
    {"base",
        (getter)voidtype_base_get,
        (setter)0,
        "base object",
        NULL},
    {NULL, NULL, NULL, NULL, NULL}
};

static PyMethodDef voidtype_methods[] = {
    {"getfield",
        (PyCFunction)voidtype_getfield,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"setfield",
        (PyCFunction)voidtype_setfield,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {NULL, NULL, 0, NULL}
};

static PyGetSetDef inttype_getsets[] = {
    {"numerator",
        (getter)inttype_numerator_get,
        (setter)0,
        "numerator of value (the value itself)",
        NULL},
    {"denominator",
        (getter)inttype_denominator_get,
        (setter)0,
        "denominator of value (1)",
        NULL},
    {NULL, NULL, NULL, NULL, NULL}
};

static PyMethodDef numbertype_methods[] = {
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem_abc,
        METH_CLASS | METH_O, NULL},
    {NULL, NULL, 0, NULL}  /* sentinel */
};

#line 2322
static PyMethodDef cfloattype_methods[] = {
    {"__complex__",
        (PyCFunction)cfloat_complex,
        METH_VARARGS | METH_KEYWORDS, NULL},
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {NULL, NULL, 0, NULL}
};

#line 2322
static PyMethodDef clongdoubletype_methods[] = {
    {"__complex__",
        (PyCFunction)clongdouble_complex,
        METH_VARARGS | METH_KEYWORDS, NULL},
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {NULL, NULL, 0, NULL}
};


#line 2337
static PyMethodDef floatingtype_methods[] = {
    /* Hook for the round() builtin */
    {"__round__",
        (PyCFunction)floatingtype_dunder_round,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {NULL, NULL, 0, NULL} /* sentinel */
};

#line 2337
static PyMethodDef complexfloatingtype_methods[] = {
    /* Hook for the round() builtin */
    {"__round__",
        (PyCFunction)complexfloatingtype_dunder_round,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {NULL, NULL, 0, NULL} /* sentinel */
};


static PyMethodDef integertype_methods[] = {
    /* Hook for the round() builtin */
    {"__round__",
        (PyCFunction)integertype_dunder_round,
        METH_VARARGS | METH_KEYWORDS, NULL},
    {"is_integer",
        (PyCFunction)integer_is_integer,
        METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL} /* sentinel */
};

#line 2360
static PyMethodDef halftype_methods[] = {
    {"as_integer_ratio",
        (PyCFunction)half_as_integer_ratio,
        METH_NOARGS, NULL},
    {"is_integer",
        (PyCFunction)half_is_integer,
        METH_NOARGS, NULL},
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {NULL, NULL, 0, NULL}
};

#line 2360
static PyMethodDef floattype_methods[] = {
    {"as_integer_ratio",
        (PyCFunction)float_as_integer_ratio,
        METH_NOARGS, NULL},
    {"is_integer",
        (PyCFunction)float_is_integer,
        METH_NOARGS, NULL},
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {NULL, NULL, 0, NULL}
};

#line 2360
static PyMethodDef doubletype_methods[] = {
    {"as_integer_ratio",
        (PyCFunction)double_as_integer_ratio,
        METH_NOARGS, NULL},
    {"is_integer",
        (PyCFunction)double_is_integer,
        METH_NOARGS, NULL},
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {NULL, NULL, 0, NULL}
};

#line 2360
static PyMethodDef longdoubletype_methods[] = {
    {"as_integer_ratio",
        (PyCFunction)longdouble_as_integer_ratio,
        METH_NOARGS, NULL},
    {"is_integer",
        (PyCFunction)longdouble_is_integer,
        METH_NOARGS, NULL},
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {NULL, NULL, 0, NULL}
};


#line 2378
static PyMethodDef timedeltatype_methods[] = {
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {NULL, NULL, 0, NULL}
};

#line 2378
static PyMethodDef cdoubletype_methods[] = {
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {NULL, NULL, 0, NULL}
};


#line 2391
static PyMethodDef bytetype_methods[] = {
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {"bit_count",
        (PyCFunction)npy_byte_bit_count,
        METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL} /* sentinel */
};

#line 2391
static PyMethodDef ubytetype_methods[] = {
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {"bit_count",
        (PyCFunction)npy_ubyte_bit_count,
        METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL} /* sentinel */
};

#line 2391
static PyMethodDef shorttype_methods[] = {
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {"bit_count",
        (PyCFunction)npy_short_bit_count,
        METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL} /* sentinel */
};

#line 2391
static PyMethodDef ushorttype_methods[] = {
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {"bit_count",
        (PyCFunction)npy_ushort_bit_count,
        METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL} /* sentinel */
};

#line 2391
static PyMethodDef inttype_methods[] = {
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {"bit_count",
        (PyCFunction)npy_int_bit_count,
        METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL} /* sentinel */
};

#line 2391
static PyMethodDef uinttype_methods[] = {
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {"bit_count",
        (PyCFunction)npy_uint_bit_count,
        METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL} /* sentinel */
};

#line 2391
static PyMethodDef longtype_methods[] = {
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {"bit_count",
        (PyCFunction)npy_long_bit_count,
        METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL} /* sentinel */
};

#line 2391
static PyMethodDef ulongtype_methods[] = {
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {"bit_count",
        (PyCFunction)npy_ulong_bit_count,
        METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL} /* sentinel */
};

#line 2391
static PyMethodDef longlongtype_methods[] = {
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {"bit_count",
        (PyCFunction)npy_longlong_bit_count,
        METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL} /* sentinel */
};

#line 2391
static PyMethodDef ulonglongtype_methods[] = {
    /* for typing */
    {"__class_getitem__",
        (PyCFunction)numbertype_class_getitem,
        METH_CLASS | METH_O, NULL},
    {"bit_count",
        (PyCFunction)npy_ulonglong_bit_count,
        METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL} /* sentinel */
};



/************* As_mapping functions for void array scalar ************/

static Py_ssize_t
voidtype_length(PyVoidScalarObject *self)
{
    if (!PyDataType_HASFIELDS(self->descr)) {
        return 0;
    }
    else {
        /* return the number of fields */
        return (Py_ssize_t) PyTuple_GET_SIZE(self->descr->names);
    }
}

static PyObject *
voidtype_subscript(PyVoidScalarObject *self, PyObject *ind);

static PyObject *
voidtype_item(PyVoidScalarObject *self, Py_ssize_t n)
{
    npy_intp m;
    PyObject *flist=NULL;

    if (!(PyDataType_HASFIELDS(self->descr))) {
        PyErr_SetString(PyExc_IndexError,
                "can't index void scalar without fields");
        return NULL;
    }
    flist = self->descr->names;
    m = PyTuple_GET_SIZE(flist);
    if (n < 0) {
        n += m;
    }
    if (n < 0 || n >= m) {
        PyErr_Format(PyExc_IndexError, "invalid index (%d)", (int) n);
        return NULL;
    }

    return voidtype_subscript(self, PyTuple_GetItem(flist, n));
}

/* get field by name or number */
static PyObject *
voidtype_subscript(PyVoidScalarObject *self, PyObject *ind)
{
    npy_intp n;
    PyObject *ret, *res;

    /* structured voids will accept an integer index */
    if (PyDataType_HASFIELDS(self->descr)) {
        n = PyArray_PyIntAsIntp(ind);
        if (!error_converting(n)) {
            return voidtype_item(self, (Py_ssize_t)n);
        }
        PyErr_Clear();
    }

    res = PyArray_FromScalar((PyObject*)self, NULL);

    /* ellipsis should return 0d array */
    if(ind == Py_Ellipsis){
        return res;
    }

    /*
     * other cases (field names, empty tuple) will return either
     * scalar or non-0d array. Compute this using ndarray subscript.
     */
    ret = array_subscript((PyArrayObject *)res, ind);
    Py_DECREF(res);
    return PyArray_Return((PyArrayObject*)ret);
}

static int
voidtype_ass_subscript(PyVoidScalarObject *self, PyObject *ind, PyObject *val);

static int
voidtype_ass_item(PyVoidScalarObject *self, Py_ssize_t n, PyObject *val)
{
    npy_intp m;
    PyObject *flist=NULL;

    if (!(PyDataType_HASFIELDS(self->descr))) {
        PyErr_SetString(PyExc_IndexError,
                "can't index void scalar without fields");
        return -1;
    }

    flist = self->descr->names;
    m = PyTuple_GET_SIZE(flist);
    if (n < 0) {
        n += m;
    }
    if (n < 0 || n >= m) {
        PyErr_Format(PyExc_IndexError, "invalid index (%d)", (int) n);
        return -1;
    }

    return voidtype_ass_subscript(self, PyTuple_GetItem(flist, n), val);
}

static int
voidtype_ass_subscript(PyVoidScalarObject *self, PyObject *ind, PyObject *val)
{
    npy_intp n;
    char *msg = "invalid index";
    PyObject *args;

    if (!PyDataType_HASFIELDS(self->descr)) {
        PyErr_SetString(PyExc_IndexError,
                "can't index void scalar without fields");
        return -1;
    }

    if (!val) {
        PyErr_SetString(PyExc_ValueError,
                "cannot delete scalar field");
        return -1;
    }

    if (PyUnicode_Check(ind)) {
        /*
         * Much like in voidtype_setfield, we cannot simply use ndarray's
         * __setitem__ since assignment to void scalars should not broadcast
         * the lhs. Instead we get a view through __getitem__ and then assign
         * the value using setitem with an empty tuple (which treats both
         * object arrays and subarrays properly).
         *
         * Also we do not want to use voidtype_setfield here, since we do
         * not need to do the (slow) view safety checks, since we already
         * know the dtype/offset are safe.
         */

        PyObject *arr, *arr_field, *meth, *emptytuple;

        /* 1. Convert to 0-d array and use getitem */
        arr = PyArray_FromScalar((PyObject*)self, NULL);
        if (arr == NULL) {
            return -1;
        }
        meth = PyObject_GetAttrString(arr, "__getitem__");
        if (meth == NULL) {
            Py_DECREF(arr);
            return -1;
        }
        args = Py_BuildValue("(O)", ind);
        arr_field = PyObject_CallObject(meth, args);
        Py_DECREF(meth);
        Py_DECREF(arr);
        Py_DECREF(args);

        if(arr_field == NULL){
            return -1;
        }

        /* 2. Assign the value using setitem with empty tuple. */
        emptytuple = PyTuple_New(0);
        if (PyObject_SetItem(arr_field, emptytuple, val) < 0) {
            Py_DECREF(arr_field);
            Py_DECREF(emptytuple);
            return -1;
        }
        Py_DECREF(emptytuple);
        Py_DECREF(arr_field);
        return 0;
    }

    /* try to convert it to a number */
    n = PyArray_PyIntAsIntp(ind);
    if (error_converting(n)) {
        goto fail;
    }
    return voidtype_ass_item(self, (Py_ssize_t)n, val);

fail:
    PyErr_SetString(PyExc_IndexError, msg);
    return -1;
}

static PyMappingMethods voidtype_as_mapping = {
    .mp_length = (lenfunc)voidtype_length,
    .mp_subscript = (binaryfunc)voidtype_subscript,
    .mp_ass_subscript = (objobjargproc)voidtype_ass_subscript,
};


static PySequenceMethods voidtype_as_sequence = {
    .sq_length = (lenfunc)voidtype_length,
    .sq_item = (ssizeargfunc)voidtype_item,
    .sq_ass_item = (ssizeobjargproc)voidtype_ass_item,
};


/*
 * This function implements simple buffer export for user defined subclasses
 * of `np.generic`. All other scalar types override the buffer export.
 */
static int
gentype_arrtype_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
        PyErr_Format(PyExc_TypeError,
                "NumPy scalar %R can only exported as a buffer without format.",
                self);
        return -1;
    }
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyArray_Descr *descr = PyArray_DescrFromScalar(self);
    if (descr == NULL) {
        return -1;
    }
    if (!PyDataType_ISUSERDEF(descr)) {
        /* This path would also reject the (hopefully) impossible "object" */
        PyErr_Format(PyExc_TypeError,
                "user-defined scalar %R registered for built-in dtype %S? "
                "This should be impossible.",
                self, descr);
        Py_DECREF(descr);
        return -1;
    }
    view->ndim = 0;
    view->len = descr->elsize;
    view->itemsize = descr->elsize;
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;  /* assume general (user) scalars are readonly. */
    Py_INCREF(self);
    view->obj = self;
    view->buf = scalar_value(self, descr);
    Py_DECREF(descr);
    view->format = NULL;
    return 0;
}


static PyBufferProcs gentype_arrtype_as_buffer = {
    .bf_getbuffer = (getbufferproc)gentype_arrtype_getbuffer,
};


#line 2660

static int
bool_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyBoolScalarObject *scalar = (PyBoolScalarObject *)self;

    static char fmt[3] = "?";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs bool_arrtype_as_buffer = {
    .bf_getbuffer = bool_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
byte_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyByteScalarObject *scalar = (PyByteScalarObject *)self;

    static char fmt[3] = "b";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs byte_arrtype_as_buffer = {
    .bf_getbuffer = byte_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
short_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyShortScalarObject *scalar = (PyShortScalarObject *)self;

    static char fmt[3] = "h";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs short_arrtype_as_buffer = {
    .bf_getbuffer = short_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
int_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyIntScalarObject *scalar = (PyIntScalarObject *)self;

    static char fmt[3] = "i";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs int_arrtype_as_buffer = {
    .bf_getbuffer = int_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
long_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyLongScalarObject *scalar = (PyLongScalarObject *)self;

    static char fmt[3] = "l";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs long_arrtype_as_buffer = {
    .bf_getbuffer = long_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
longlong_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyLongLongScalarObject *scalar = (PyLongLongScalarObject *)self;

    static char fmt[3] = "q";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs longlong_arrtype_as_buffer = {
    .bf_getbuffer = longlong_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
ubyte_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyUByteScalarObject *scalar = (PyUByteScalarObject *)self;

    static char fmt[3] = "B";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs ubyte_arrtype_as_buffer = {
    .bf_getbuffer = ubyte_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
ushort_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyUShortScalarObject *scalar = (PyUShortScalarObject *)self;

    static char fmt[3] = "H";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs ushort_arrtype_as_buffer = {
    .bf_getbuffer = ushort_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
uint_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyUIntScalarObject *scalar = (PyUIntScalarObject *)self;

    static char fmt[3] = "I";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs uint_arrtype_as_buffer = {
    .bf_getbuffer = uint_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
ulong_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyULongScalarObject *scalar = (PyULongScalarObject *)self;

    static char fmt[3] = "L";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs ulong_arrtype_as_buffer = {
    .bf_getbuffer = ulong_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
ulonglong_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyULongLongScalarObject *scalar = (PyULongLongScalarObject *)self;

    static char fmt[3] = "Q";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs ulonglong_arrtype_as_buffer = {
    .bf_getbuffer = ulonglong_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
half_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyHalfScalarObject *scalar = (PyHalfScalarObject *)self;

    static char fmt[3] = "e";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs half_arrtype_as_buffer = {
    .bf_getbuffer = half_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
float_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyFloatScalarObject *scalar = (PyFloatScalarObject *)self;

    static char fmt[3] = "f";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs float_arrtype_as_buffer = {
    .bf_getbuffer = float_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
double_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyDoubleScalarObject *scalar = (PyDoubleScalarObject *)self;

    static char fmt[3] = "d";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs double_arrtype_as_buffer = {
    .bf_getbuffer = double_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
longdouble_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyLongDoubleScalarObject *scalar = (PyLongDoubleScalarObject *)self;

    static char fmt[3] = "g";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs longdouble_arrtype_as_buffer = {
    .bf_getbuffer = longdouble_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
cfloat_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyCFloatScalarObject *scalar = (PyCFloatScalarObject *)self;

    static char fmt[3] = "Zf";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs cfloat_arrtype_as_buffer = {
    .bf_getbuffer = cfloat_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
cdouble_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyCDoubleScalarObject *scalar = (PyCDoubleScalarObject *)self;

    static char fmt[3] = "Zd";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs cdouble_arrtype_as_buffer = {
    .bf_getbuffer = cdouble_getbuffer,
    /* No need to release the buffer */
};


#line 2660

static int
clongdouble_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyCLongDoubleScalarObject *scalar = (PyCLongDoubleScalarObject *)self;

    static char fmt[3] = "Zg";

    view->ndim = 0;
    view->len = sizeof(scalar->obval);
    view->itemsize = sizeof(scalar->obval);
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;
    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    view->format = fmt;

    return 0;
}

static PyBufferProcs clongdouble_arrtype_as_buffer = {
    .bf_getbuffer = clongdouble_getbuffer,
    /* No need to release the buffer */
};



static int
unicode_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyUnicodeScalarObject *scalar = (PyUnicodeScalarObject *)self;
    Py_ssize_t length = PyUnicode_GetLength(self);

    view->ndim = 0;
    view->len = length * 4;
    view->itemsize = length * 4;
    view->shape = NULL;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;

    if (scalar->obval == NULL) {
        /*
         * Unicode may not have the representation available, `scalar_value`
         * ensures materialization.
         */
        PyArray_Descr *descr = PyArray_DescrFromType(NPY_UNICODE);
        scalar_value(self, descr);
        Py_DECREF(descr);
        if (scalar->obval == NULL) {
            /* allocating memory failed */
            Py_SETREF(view->obj, NULL);
            return -1;
        }
    }
    view->buf = scalar->obval;

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    if (scalar->buffer_fmt != NULL) {
        view->format = scalar->buffer_fmt;
    }
    else {
        scalar->buffer_fmt = PyMem_Malloc(22);
        if (scalar->buffer_fmt == NULL) {
            Py_SETREF(view->obj, NULL);
            return -1;
        }
        PyOS_snprintf(scalar->buffer_fmt, 22, "%" NPY_INTP_FMT "w", length);
        view->format = scalar->buffer_fmt;
    }

    return 0;
}

static PyBufferProcs unicode_arrtype_as_buffer = {
    .bf_getbuffer = unicode_getbuffer,
    /* No need to release the buffer */
};


#line 2769

static int
datetime_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyDatetimeScalarObject *scalar = (PyDatetimeScalarObject *)self;

    view->ndim = 1;
    view->len = 8;
    view->itemsize = 1;
    static Py_ssize_t length = 8;
    view->shape = &length;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;

    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    /* export datetime scalars as bytes (although arrays are not exported) */
    view->format = "B";

    return 0;
}

static PyBufferProcs datetime_arrtype_as_buffer = {
        .bf_getbuffer = datetime_getbuffer,
        /* No need to release the buffer */
};


#line 2769

static int
timedelta_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        PyErr_SetString(PyExc_BufferError, "scalar buffer is readonly");
        return -1;
    }
    PyTimedeltaScalarObject *scalar = (PyTimedeltaScalarObject *)self;

    view->ndim = 1;
    view->len = 8;
    view->itemsize = 1;
    static Py_ssize_t length = 8;
    view->shape = &length;
    view->strides = NULL;
    view->suboffsets = NULL;
    view->readonly = 1;
    Py_INCREF(self);
    view->obj = self;

    view->buf = &(scalar->obval);

    if ((flags & PyBUF_FORMAT) != PyBUF_FORMAT) {
        /* It is unnecessary to find the correct format */
        view->format = NULL;
        return 0;
    }

    /* export datetime scalars as bytes (although arrays are not exported) */
    view->format = "B";

    return 0;
}

static PyBufferProcs timedelta_arrtype_as_buffer = {
        .bf_getbuffer = timedelta_getbuffer,
        /* No need to release the buffer */
};



static PyBufferProcs void_arrtype_as_buffer = {
        .bf_getbuffer = void_getbuffer,  /* defined in buffer.c */
        /* No need to release the buffer */
};


#define BASEFLAGS Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
#define LEAFFLAGS  Py_TPFLAGS_DEFAULT

NPY_NO_EXPORT PyTypeObject PyGenericArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy.generic",
    .tp_basicsize = sizeof(PyObject),
};


static void
void_dealloc(PyVoidScalarObject *v)
{
    if (v->flags & NPY_ARRAY_OWNDATA) {
        npy_free_cache(v->obval, Py_SIZE(v));
    }
    Py_XDECREF(v->descr);
    Py_XDECREF(v->base);
    if (_buffer_info_free(v->_buffer_info, (PyObject *)v) < 0) {
        PyErr_WriteUnraisable(NULL);
    }
    Py_TYPE(v)->tp_free(v);
}


static PyObject *
object_arrtype_alloc(PyTypeObject *type, Py_ssize_t items)
{
    /*
     * Object scalars should not actually exist, if they exist we should
     * consider it to be a bug.
     */
    static PyObject *visibleDeprecationWarning = NULL;
    npy_cache_import("numpy", "VisibleDeprecationWarning",
                     &visibleDeprecationWarning);
    if (visibleDeprecationWarning == NULL) {
        return NULL;
    }
    if (PyErr_WarnEx(visibleDeprecationWarning,
            "Creating a NumPy object scalar.  NumPy object scalars should "
            "never be created.  If you see this message please inform the "
            "NumPy developers.  Since this message should never be shown "
            "this will raise a TypeError in the future.", 1) < 0) {
        return NULL;
    }
    return gentype_alloc(type, items);
}


static void
object_arrtype_dealloc(PyObject *v)
{
    Py_XDECREF(PyArrayScalar_VAL(v, Object));
    Py_TYPE(v)->tp_free(v);
}

static void
unicode_arrtype_dealloc(PyObject *v)
{
    /* note: may be null if it was never requested */
    PyMem_Free(PyArrayScalar_VAL(v, Unicode));
    PyMem_Free(((PyUnicodeScalarObject *)v)->buffer_fmt);
    /* delegate to the base class */
    PyUnicode_Type.tp_dealloc(v);
}

#line 2894

/* used as a pattern for testing token equality */
#define _BYTE_IS_BYTE

static PyObject *
byte_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_BYTE_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_BYTE_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_BYTE_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_BYTE_IS_UNICODE) || defined(_BYTE_IS_STRING) || defined(_BYTE_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_BYTE_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not byte */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_BYTE);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_BYTE_IS_STRING) && !defined(_BYTE_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, Byte), 0, sizeof(npy_byte));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_BYTE_IS_STRING) || defined(_BYTE_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_byte *)dest) = *((npy_byte *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _BYTE_IS_BYTE


#line 2894

/* used as a pattern for testing token equality */
#define _SHORT_IS_SHORT

static PyObject *
short_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_SHORT_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_SHORT_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_SHORT_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_SHORT_IS_UNICODE) || defined(_SHORT_IS_STRING) || defined(_SHORT_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_SHORT_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not short */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_SHORT);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_SHORT_IS_STRING) && !defined(_SHORT_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, Short), 0, sizeof(npy_short));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_SHORT_IS_STRING) || defined(_SHORT_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_short *)dest) = *((npy_short *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _SHORT_IS_SHORT


#line 2894

/* used as a pattern for testing token equality */
#define _INT_IS_INT

static PyObject *
int_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_INT_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_INT_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_INT_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_INT_IS_UNICODE) || defined(_INT_IS_STRING) || defined(_INT_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_INT_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not int */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_INT);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_INT_IS_STRING) && !defined(_INT_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, Int), 0, sizeof(npy_int));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_INT_IS_STRING) || defined(_INT_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_int *)dest) = *((npy_int *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _INT_IS_INT


#line 2894

/* used as a pattern for testing token equality */
#define _LONG_IS_LONG

static PyObject *
long_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_LONG_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_LONG_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_LONG_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_LONG_IS_UNICODE) || defined(_LONG_IS_STRING) || defined(_LONG_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_LONG_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not long */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_LONG);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_LONG_IS_STRING) && !defined(_LONG_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, Long), 0, sizeof(npy_long));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_LONG_IS_STRING) || defined(_LONG_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_long *)dest) = *((npy_long *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _LONG_IS_LONG


#line 2894

/* used as a pattern for testing token equality */
#define _LONGLONG_IS_LONGLONG

static PyObject *
longlong_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_LONGLONG_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_LONGLONG_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_LONGLONG_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_LONGLONG_IS_UNICODE) || defined(_LONGLONG_IS_STRING) || defined(_LONGLONG_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_LONGLONG_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not longlong */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_LONGLONG);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_LONGLONG_IS_STRING) && !defined(_LONGLONG_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, LongLong), 0, sizeof(npy_longlong));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_LONGLONG_IS_STRING) || defined(_LONGLONG_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_longlong *)dest) = *((npy_longlong *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _LONGLONG_IS_LONGLONG


#line 2894

/* used as a pattern for testing token equality */
#define _UBYTE_IS_UBYTE

static PyObject *
ubyte_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_UBYTE_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_UBYTE_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_UBYTE_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_UBYTE_IS_UNICODE) || defined(_UBYTE_IS_STRING) || defined(_UBYTE_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_UBYTE_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not ubyte */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_UBYTE);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_UBYTE_IS_STRING) && !defined(_UBYTE_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, UByte), 0, sizeof(npy_ubyte));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_UBYTE_IS_STRING) || defined(_UBYTE_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_ubyte *)dest) = *((npy_ubyte *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _UBYTE_IS_UBYTE


#line 2894

/* used as a pattern for testing token equality */
#define _USHORT_IS_USHORT

static PyObject *
ushort_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_USHORT_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_USHORT_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_USHORT_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_USHORT_IS_UNICODE) || defined(_USHORT_IS_STRING) || defined(_USHORT_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_USHORT_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not ushort */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_USHORT);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_USHORT_IS_STRING) && !defined(_USHORT_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, UShort), 0, sizeof(npy_ushort));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_USHORT_IS_STRING) || defined(_USHORT_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_ushort *)dest) = *((npy_ushort *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _USHORT_IS_USHORT


#line 2894

/* used as a pattern for testing token equality */
#define _UINT_IS_UINT

static PyObject *
uint_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_UINT_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_UINT_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_UINT_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_UINT_IS_UNICODE) || defined(_UINT_IS_STRING) || defined(_UINT_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_UINT_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not uint */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_UINT);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_UINT_IS_STRING) && !defined(_UINT_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, UInt), 0, sizeof(npy_uint));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_UINT_IS_STRING) || defined(_UINT_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_uint *)dest) = *((npy_uint *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _UINT_IS_UINT


#line 2894

/* used as a pattern for testing token equality */
#define _ULONG_IS_ULONG

static PyObject *
ulong_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_ULONG_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_ULONG_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_ULONG_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_ULONG_IS_UNICODE) || defined(_ULONG_IS_STRING) || defined(_ULONG_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_ULONG_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not ulong */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_ULONG);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_ULONG_IS_STRING) && !defined(_ULONG_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, ULong), 0, sizeof(npy_ulong));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_ULONG_IS_STRING) || defined(_ULONG_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_ulong *)dest) = *((npy_ulong *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _ULONG_IS_ULONG


#line 2894

/* used as a pattern for testing token equality */
#define _ULONGLONG_IS_ULONGLONG

static PyObject *
ulonglong_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_ULONGLONG_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_ULONGLONG_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_ULONGLONG_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_ULONGLONG_IS_UNICODE) || defined(_ULONGLONG_IS_STRING) || defined(_ULONGLONG_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_ULONGLONG_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not ulonglong */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_ULONGLONG);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_ULONGLONG_IS_STRING) && !defined(_ULONGLONG_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, ULongLong), 0, sizeof(npy_ulonglong));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_ULONGLONG_IS_STRING) || defined(_ULONGLONG_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_ulonglong *)dest) = *((npy_ulonglong *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _ULONGLONG_IS_ULONGLONG


#line 2894

/* used as a pattern for testing token equality */
#define _HALF_IS_HALF

static PyObject *
half_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_HALF_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_HALF_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_HALF_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_HALF_IS_UNICODE) || defined(_HALF_IS_STRING) || defined(_HALF_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_HALF_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not half */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_HALF);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_HALF_IS_STRING) && !defined(_HALF_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, Half), 0, sizeof(npy_half));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_HALF_IS_STRING) || defined(_HALF_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_half *)dest) = *((npy_half *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _HALF_IS_HALF


#line 2894

/* used as a pattern for testing token equality */
#define _FLOAT_IS_FLOAT

static PyObject *
float_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_FLOAT_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_FLOAT_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_FLOAT_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_FLOAT_IS_UNICODE) || defined(_FLOAT_IS_STRING) || defined(_FLOAT_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_FLOAT_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not float */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_FLOAT);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_FLOAT_IS_STRING) && !defined(_FLOAT_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, Float), 0, sizeof(npy_float));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_FLOAT_IS_STRING) || defined(_FLOAT_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_float *)dest) = *((npy_float *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _FLOAT_IS_FLOAT


#line 2894

/* used as a pattern for testing token equality */
#define _DOUBLE_IS_DOUBLE

static PyObject *
double_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_DOUBLE_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_DOUBLE_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_DOUBLE_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_DOUBLE_IS_UNICODE) || defined(_DOUBLE_IS_STRING) || defined(_DOUBLE_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_DOUBLE_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not double */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_DOUBLE);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_DOUBLE_IS_STRING) && !defined(_DOUBLE_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, Double), 0, sizeof(npy_double));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_DOUBLE_IS_STRING) || defined(_DOUBLE_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_double *)dest) = *((npy_double *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _DOUBLE_IS_DOUBLE


#line 2894

/* used as a pattern for testing token equality */
#define _LONGDOUBLE_IS_LONGDOUBLE

static PyObject *
longdouble_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_LONGDOUBLE_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_LONGDOUBLE_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_LONGDOUBLE_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_LONGDOUBLE_IS_UNICODE) || defined(_LONGDOUBLE_IS_STRING) || defined(_LONGDOUBLE_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_LONGDOUBLE_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not longdouble */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_LONGDOUBLE);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_LONGDOUBLE_IS_STRING) && !defined(_LONGDOUBLE_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, LongDouble), 0, sizeof(npy_longdouble));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_LONGDOUBLE_IS_STRING) || defined(_LONGDOUBLE_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_longdouble *)dest) = *((npy_longdouble *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _LONGDOUBLE_IS_LONGDOUBLE


#line 2894

/* used as a pattern for testing token equality */
#define _CFLOAT_IS_CFLOAT

static PyObject *
cfloat_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_CFLOAT_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_CFLOAT_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_CFLOAT_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_CFLOAT_IS_UNICODE) || defined(_CFLOAT_IS_STRING) || defined(_CFLOAT_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_CFLOAT_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not cfloat */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_CFLOAT);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_CFLOAT_IS_STRING) && !defined(_CFLOAT_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, CFloat), 0, sizeof(npy_cfloat));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_CFLOAT_IS_STRING) || defined(_CFLOAT_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_cfloat *)dest) = *((npy_cfloat *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _CFLOAT_IS_CFLOAT


#line 2894

/* used as a pattern for testing token equality */
#define _CDOUBLE_IS_CDOUBLE

static PyObject *
cdouble_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_CDOUBLE_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_CDOUBLE_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_CDOUBLE_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_CDOUBLE_IS_UNICODE) || defined(_CDOUBLE_IS_STRING) || defined(_CDOUBLE_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_CDOUBLE_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not cdouble */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_CDOUBLE);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_CDOUBLE_IS_STRING) && !defined(_CDOUBLE_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, CDouble), 0, sizeof(npy_cdouble));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_CDOUBLE_IS_STRING) || defined(_CDOUBLE_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_cdouble *)dest) = *((npy_cdouble *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _CDOUBLE_IS_CDOUBLE


#line 2894

/* used as a pattern for testing token equality */
#define _CLONGDOUBLE_IS_CLONGDOUBLE

static PyObject *
clongdouble_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_CLONGDOUBLE_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_CLONGDOUBLE_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_CLONGDOUBLE_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_CLONGDOUBLE_IS_UNICODE) || defined(_CLONGDOUBLE_IS_STRING) || defined(_CLONGDOUBLE_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_CLONGDOUBLE_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not clongdouble */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_CLONGDOUBLE);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_CLONGDOUBLE_IS_STRING) && !defined(_CLONGDOUBLE_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, CLongDouble), 0, sizeof(npy_clongdouble));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_CLONGDOUBLE_IS_STRING) || defined(_CLONGDOUBLE_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_clongdouble *)dest) = *((npy_clongdouble *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _CLONGDOUBLE_IS_CLONGDOUBLE


#line 2894

/* used as a pattern for testing token equality */
#define _STRING_IS_STRING

static PyObject *
string_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_STRING_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_STRING_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_STRING_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_STRING_IS_UNICODE) || defined(_STRING_IS_STRING) || defined(_STRING_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_STRING_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not string */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_STRING);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_STRING_IS_STRING) && !defined(_STRING_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, String), 0, sizeof(npy_string));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_STRING_IS_STRING) || defined(_STRING_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_string *)dest) = *((npy_string *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _STRING_IS_STRING


#line 2894

/* used as a pattern for testing token equality */
#define _UNICODE_IS_UNICODE

static PyObject *
unicode_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    /* allow base-class (if any) to do conversion */
#if defined(_UNICODE_IS_UNICODE)
    PyObject *from_superclass = PyUnicode_Type.tp_new(type, args, kwds);
#elif defined(_UNICODE_IS_STRING)
    PyObject *from_superclass = PyBytes_Type.tp_new(type, args, kwds);
#elif defined(_UNICODE_IS_DOUBLE)
    PyObject *from_superclass = PyFloat_Type.tp_new(type, args, kwds);
#endif
#if defined(_UNICODE_IS_UNICODE) || defined(_UNICODE_IS_STRING) || defined(_UNICODE_IS_DOUBLE)
    if (from_superclass == NULL) {
        /* don't clear the exception unless numpy can handle the arguments */
        if (PyTuple_GET_SIZE(args) != 1 || (kwds && PyDict_Size(kwds) != 0)) {
            return NULL;
        }
        PyErr_Clear();
    }
    else {
#if defined(_UNICODE_IS_UNICODE)
        PyArrayScalar_VAL(from_superclass, Unicode) = NULL;
#endif
        return from_superclass;
    }
#endif

    /* TODO: include type name in error message, which is not unicode */
    PyObject *obj = NULL;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_UNICODE);
    if (typecode == NULL) {
        return NULL;
    }
    if (obj == NULL) {
        PyObject *robj = PyArray_Scalar(NULL, typecode, NULL);
        Py_DECREF(typecode);
        if (robj == NULL) {
            return NULL;
        }
#if !defined(_UNICODE_IS_STRING) && !defined(_UNICODE_IS_UNICODE)
        memset(&PyArrayScalar_VAL(robj, Unicode), 0, sizeof(npy_unicode));
#endif
        return robj;
    }

    /* PyArray_FromAny steals a reference, reclaim it before it's gone */
    Py_INCREF(typecode);
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(
            obj, typecode, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    if (arr == NULL) {
        Py_DECREF(typecode);
        return NULL;
    }
    if (PyArray_NDIM(arr) > 0) {
        Py_DECREF(typecode);
        return (PyObject *)arr;
    }

    /* Convert the 0-d array to a scalar*/
    PyObject *robj = PyArray_ToScalar(PyArray_DATA(arr), arr);
    Py_DECREF(arr);

    if (robj == NULL || Py_TYPE(robj) == type) {
        Py_DECREF(typecode);
        return robj;
    }

    /*
     * `typecode` does not contain any subclass information, as it was thrown
     * out by the call to `PyArray_DescrFromType` - we need to add this back.
     *
     * FIXME[gh-15467]: This branch is also hit for the "shadowed" builtin
     * types like `longdouble` (which on platforms where they are the same size
     * is shadowed by `double`), because `PyArray_FromAny` returns the
     * shadowing type rather than the requested one.
     */

    /* Need to allocate new type and copy data-area over */
    int itemsize;
    if (type->tp_itemsize) {
        itemsize = PyBytes_GET_SIZE(robj);
    }
    else {
        itemsize = 0;
    }
    PyObject *new_obj = type->tp_alloc(type, itemsize);
    if (new_obj == NULL) {
        Py_DECREF(robj);
        Py_DECREF(typecode);
        return NULL;
    }
    void *dest = scalar_value(new_obj, typecode);
    void *src = scalar_value(robj, typecode);
    Py_DECREF(typecode);
#if defined(_UNICODE_IS_STRING) || defined(_UNICODE_IS_UNICODE)
    if (itemsize == 0) { /* unicode */
        itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj);
    }
    memcpy(dest, src, itemsize);
#else
    *((npy_unicode *)dest) = *((npy_unicode *)src);
#endif
    Py_DECREF(robj);
    return new_obj;
}
#undef _UNICODE_IS_UNICODE



static PyObject *
object_arrtype_new(PyTypeObject *NPY_UNUSED(type), PyObject *args, PyObject *kwds)
{
    PyObject *obj = Py_None;
    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:object_", kwnames, &obj)) {
        return NULL;
    }
    PyArray_Descr *typecode = PyArray_DescrFromType(NPY_OBJECT);
    if (typecode == NULL) {
        return NULL;
    }
    PyArrayObject *arr = (PyArrayObject *)PyArray_FromAny(obj, typecode,
                                    0, 0, NPY_ARRAY_FORCECAST, NULL);
    return PyArray_Return(arr);
}

#line 3034

static PyObject *
datetime_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyObject *obj = NULL, *meta_obj = NULL;
    PyDatetimeScalarObject *ret;

    static char *kwnames[] = {"", "", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwnames, &obj, &meta_obj)) {
        return NULL;
    }

    /* Allocate the return scalar */
    ret = (PyDatetimeScalarObject *)PyDatetimeArrType_Type.tp_alloc(
                                            &PyDatetimeArrType_Type, 0);
    if (ret == NULL) {
        return NULL;
    }

    /* Incorporate the metadata if its provided */
    if (meta_obj != NULL) {
        /* Parse the provided metadata input */
        if (convert_pyobject_to_datetime_metadata(meta_obj, &ret->obmeta)
                                                                    < 0) {
            Py_DECREF(ret);
            return NULL;
        }
    }
    else {
        /*
         * A unit of -1 signals that convert_pyobject_to_datetime
         * should populate.
         */
        ret->obmeta.base = -1;
    }

    if (obj == NULL) {
        if (ret->obmeta.base == -1) {
            ret->obmeta.base = NPY_DATETIME_DEFAULTUNIT;
            ret->obmeta.num = 1;
        }

        /* Make datetime default to NaT, timedelta default to zero */
#if 1
        ret->obval = NPY_DATETIME_NAT;
#else
        ret->obval = 0;
#endif
    }
    else if (convert_pyobject_to_datetime(&ret->obmeta, obj,
                            NPY_SAME_KIND_CASTING, &ret->obval) < 0) {
        Py_DECREF(ret);
        return NULL;
    }

    return (PyObject *)ret;
}

#line 3034

static PyObject *
timedelta_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyObject *obj = NULL, *meta_obj = NULL;
    PyTimedeltaScalarObject *ret;

    static char *kwnames[] = {"", "", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwnames, &obj, &meta_obj)) {
        return NULL;
    }

    /* Allocate the return scalar */
    ret = (PyTimedeltaScalarObject *)PyTimedeltaArrType_Type.tp_alloc(
                                            &PyTimedeltaArrType_Type, 0);
    if (ret == NULL) {
        return NULL;
    }

    /* Incorporate the metadata if its provided */
    if (meta_obj != NULL) {
        /* Parse the provided metadata input */
        if (convert_pyobject_to_datetime_metadata(meta_obj, &ret->obmeta)
                                                                    < 0) {
            Py_DECREF(ret);
            return NULL;
        }
    }
    else {
        /*
         * A unit of -1 signals that convert_pyobject_to_datetime
         * should populate.
         */
        ret->obmeta.base = -1;
    }

    if (obj == NULL) {
        if (ret->obmeta.base == -1) {
            ret->obmeta.base = NPY_DATETIME_DEFAULTUNIT;
            ret->obmeta.num = 1;
        }

        /* Make datetime default to NaT, timedelta default to zero */
#if 0
        ret->obval = NPY_DATETIME_NAT;
#else
        ret->obval = 0;
#endif
    }
    else if (convert_pyobject_to_timedelta(&ret->obmeta, obj,
                            NPY_SAME_KIND_CASTING, &ret->obval) < 0) {
        Py_DECREF(ret);
        return NULL;
    }

    return (PyObject *)ret;
}


/* bool->tp_new only returns Py_True or Py_False */
static PyObject *
bool_arrtype_new(PyTypeObject *NPY_UNUSED(type), PyObject *args, PyObject *kwds)
{
    PyObject *obj = NULL;
    PyArrayObject *arr;

    static char *kwnames[] = {"", NULL};  /* positional-only */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:bool_", kwnames, &obj)) {
        return NULL;
    }
    if (obj == NULL) {
        PyArrayScalar_RETURN_FALSE;
    }
    if (obj == Py_False) {
        PyArrayScalar_RETURN_FALSE;
    }
    if (obj == Py_True) {
        PyArrayScalar_RETURN_TRUE;
    }
    arr = (PyArrayObject *)PyArray_FROM_OTF(obj,
                                NPY_BOOL, NPY_ARRAY_FORCECAST);
    if (arr && 0 == PyArray_NDIM(arr)) {
        npy_bool val = *((npy_bool *)PyArray_DATA(arr));
        Py_DECREF(arr);
        PyArrayScalar_RETURN_BOOL_FROM_LONG(val);
    }
    return PyArray_Return((PyArrayObject *)arr);
}

static PyObject *
bool_arrtype_and(PyObject *a, PyObject *b)
{
    if (PyArray_IsScalar(a, Bool) && PyArray_IsScalar(b, Bool)) {
        PyArrayScalar_RETURN_BOOL_FROM_LONG
            ((a == PyArrayScalar_True) & (b == PyArrayScalar_True));
    }
    return PyGenericArrType_Type.tp_as_number->nb_and(a, b);
}

static PyObject *
bool_arrtype_or(PyObject *a, PyObject *b)
{
    if (PyArray_IsScalar(a, Bool) && PyArray_IsScalar(b, Bool)) {
        PyArrayScalar_RETURN_BOOL_FROM_LONG
            ((a == PyArrayScalar_True)|(b == PyArrayScalar_True));
    }
    return PyGenericArrType_Type.tp_as_number->nb_or(a, b);
}

static PyObject *
bool_arrtype_xor(PyObject *a, PyObject *b)
{
    if (PyArray_IsScalar(a, Bool) && PyArray_IsScalar(b, Bool)) {
        PyArrayScalar_RETURN_BOOL_FROM_LONG
            ((a == PyArrayScalar_True)^(b == PyArrayScalar_True));
    }
    return PyGenericArrType_Type.tp_as_number->nb_xor(a, b);
}

static int
bool_arrtype_nonzero(PyObject *a)
{
    return a == PyArrayScalar_True;
}

#line 3167
static PyNumberMethods byte_arrtype_as_number;
static PyObject *
byte_index(PyObject *self)
{
    return PyLong_FromLong(PyArrayScalar_VAL(self, Byte));
}

#line 3167
static PyNumberMethods short_arrtype_as_number;
static PyObject *
short_index(PyObject *self)
{
    return PyLong_FromLong(PyArrayScalar_VAL(self, Short));
}

#line 3167
static PyNumberMethods int_arrtype_as_number;
static PyObject *
int_index(PyObject *self)
{
    return PyLong_FromLong(PyArrayScalar_VAL(self, Int));
}

#line 3167
static PyNumberMethods long_arrtype_as_number;
static PyObject *
long_index(PyObject *self)
{
    return PyLong_FromLong(PyArrayScalar_VAL(self, Long));
}

#line 3167
static PyNumberMethods ubyte_arrtype_as_number;
static PyObject *
ubyte_index(PyObject *self)
{
    return PyLong_FromLong(PyArrayScalar_VAL(self, UByte));
}

#line 3167
static PyNumberMethods ushort_arrtype_as_number;
static PyObject *
ushort_index(PyObject *self)
{
    return PyLong_FromLong(PyArrayScalar_VAL(self, UShort));
}

#line 3167
static PyNumberMethods longlong_arrtype_as_number;
static PyObject *
longlong_index(PyObject *self)
{
    return PyLong_FromLongLong(PyArrayScalar_VAL(self, LongLong));
}

#line 3167
static PyNumberMethods uint_arrtype_as_number;
static PyObject *
uint_index(PyObject *self)
{
    return PyLong_FromUnsignedLong(PyArrayScalar_VAL(self, UInt));
}

#line 3167
static PyNumberMethods ulong_arrtype_as_number;
static PyObject *
ulong_index(PyObject *self)
{
    return PyLong_FromUnsignedLong(PyArrayScalar_VAL(self, ULong));
}

#line 3167
static PyNumberMethods ulonglong_arrtype_as_number;
static PyObject *
ulonglong_index(PyObject *self)
{
    return PyLong_FromUnsignedLongLong(PyArrayScalar_VAL(self, ULongLong));
}


#line 3181
static PyNumberMethods half_arrtype_as_number;

#line 3181
static PyNumberMethods float_arrtype_as_number;

#line 3181
static PyNumberMethods double_arrtype_as_number;

#line 3181
static PyNumberMethods longdouble_arrtype_as_number;

#line 3181
static PyNumberMethods cfloat_arrtype_as_number;

#line 3181
static PyNumberMethods cdouble_arrtype_as_number;

#line 3181
static PyNumberMethods clongdouble_arrtype_as_number;


static PyObject *
bool_index(PyObject *a)
{
    if (DEPRECATE(
            "In future, it will be an error for 'np.bool_' scalars to be "
            "interpreted as an index") < 0) {
        return NULL;
    }
    else {
        return PyLong_FromLong(PyArrayScalar_VAL(a, Bool));
    }
}

/* Arithmetic methods -- only so we can override &, |, ^. */
NPY_NO_EXPORT PyNumberMethods bool_arrtype_as_number = {
    .nb_bool = (inquiry)bool_arrtype_nonzero,
    .nb_and = (binaryfunc)bool_arrtype_and,
    .nb_xor = (binaryfunc)bool_arrtype_xor,
    .nb_or = (binaryfunc)bool_arrtype_or,
};

static PyObject *
void_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyObject *obj, *arr;
    PyArray_Descr *descr = NULL;

    static char *kwnames[] = {"", "dtype", NULL};
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O&:void", kwnames,
            &obj, &PyArray_DescrConverter2, &descr)) {
        return NULL;
    }
    /*
     * For a VOID scalar first see if obj is an integer or long
     * and create new memory of that size (filled with 0) for the scalar
     */
    if (descr == NULL && (
            PyLong_Check(obj) ||
            PyArray_IsScalar(obj, Integer) ||
            (PyArray_Check(obj) &&
                     PyArray_NDIM((PyArrayObject *)obj)==0 &&
                     PyArray_ISINTEGER((PyArrayObject *)obj)))) {

        PyObject *length = Py_TYPE(obj)->tp_as_number->nb_int(obj);
        if (length == NULL) {
            return NULL;
        }

        PyObject *ret;
        char *destptr;
        npy_ulonglong memu = PyLong_AsUnsignedLongLong(length);
        Py_DECREF(length);
        if (PyErr_Occurred() || (memu > NPY_MAX_INT)) {
            PyErr_Clear();
            PyErr_Format(PyExc_OverflowError,
                    "size must be non-negative and not greater than %d",
                    (int) NPY_MAX_INT);
            return NULL;
        }
        if (memu == 0) {
            memu = 1;
        }
        destptr = npy_alloc_cache_zero(memu, 1);
        if (destptr == NULL) {
            return PyErr_NoMemory();
        }
        ret = type->tp_alloc(type, 0);
        if (ret == NULL) {
            npy_free_cache(destptr, memu);
            return PyErr_NoMemory();
        }
        ((PyVoidScalarObject *)ret)->obval = destptr;
        Py_SET_SIZE((PyVoidScalarObject *)ret, (int) memu);
        ((PyVoidScalarObject *)ret)->flags = NPY_ARRAY_BEHAVED |
                                             NPY_ARRAY_OWNDATA;
        ((PyVoidScalarObject *)ret)->base = NULL;
        ((PyVoidScalarObject *)ret)->descr =
            PyArray_DescrNewFromType(NPY_VOID);
        if (((PyVoidScalarObject *)ret)->descr == NULL) {
            Py_DECREF(ret);
            return NULL;
        }
        ((PyVoidScalarObject *)ret)->descr->elsize = (int) memu;
        return ret;
    }

    if (descr == NULL) {
        /* Use the "size-less" void dtype to discover the size. */
        descr = PyArray_DescrNewFromType(NPY_VOID);
        if (descr == NULL) {
            return NULL;
        }
    }
    else if (descr->type_num != NPY_VOID || PyDataType_HASSUBARRAY(descr)) {
        /* we reject subarrays, since subarray scalars do not exist. */
        PyErr_Format(PyExc_TypeError,
                "void: descr must be a `void` dtype that is not "
                "a subarray dtype (structured or unstructured). "
                "Got '%.100R'.", descr);
        Py_DECREF(descr);
        return NULL;
    }

    arr = PyArray_FromAny(obj, descr, 0, 0, NPY_ARRAY_FORCECAST, NULL);
    return PyArray_Return((PyArrayObject *)arr);
}


/****************  Define Hash functions ********************/

#line 3298
static npy_hash_t
bool_arrtype_hash(PyObject *obj)
{
    return (npy_hash_t)(PyArrayScalar_VAL(obj, Bool));
}

#line 3298
static npy_hash_t
ubyte_arrtype_hash(PyObject *obj)
{
    return (npy_hash_t)(PyArrayScalar_VAL(obj, UByte));
}

#line 3298
static npy_hash_t
ushort_arrtype_hash(PyObject *obj)
{
    return (npy_hash_t)(PyArrayScalar_VAL(obj, UShort));
}


#line 3309
static npy_hash_t
byte_arrtype_hash(PyObject *obj)
{
    npy_hash_t x = (npy_hash_t)(PyArrayScalar_VAL(obj, Byte));
    if (x == -1) {
        x = -2;
    }
    return x;
}

#line 3309
static npy_hash_t
short_arrtype_hash(PyObject *obj)
{
    npy_hash_t x = (npy_hash_t)(PyArrayScalar_VAL(obj, Short));
    if (x == -1) {
        x = -2;
    }
    return x;
}

#line 3309
static npy_hash_t
uint_arrtype_hash(PyObject *obj)
{
    npy_hash_t x = (npy_hash_t)(PyArrayScalar_VAL(obj, UInt));
    if (x == -1) {
        x = -2;
    }
    return x;
}


static npy_hash_t
ulong_arrtype_hash(PyObject *obj)
{
    PyObject * l = PyLong_FromUnsignedLong(PyArrayScalar_VAL(obj, ULong));
    npy_hash_t x = PyObject_Hash(l);
    Py_DECREF(l);
    return x;
}

static npy_hash_t
int_arrtype_hash(PyObject *obj)
{
    npy_hash_t x = (npy_hash_t)(PyArrayScalar_VAL(obj, Int));
    if (x == -1) {
        x = -2;
    }
    return x;
}

static npy_hash_t
long_arrtype_hash(PyObject *obj)
{
    PyObject * l = PyLong_FromLong(PyArrayScalar_VAL(obj, Long));
    npy_hash_t x = PyObject_Hash(l);
    Py_DECREF(l);
    return x;
}

#line 3353
static inline npy_hash_t
longlong_arrtype_hash(PyObject *obj)
{
    PyObject * l = PyLong_FromLongLong(
                                 PyArrayScalar_VAL(obj, LongLong));
    npy_hash_t x = PyObject_Hash(l);
    Py_DECREF(l);
    return x;
}

#line 3353
static inline npy_hash_t
ulonglong_arrtype_hash(PyObject *obj)
{
    PyObject * l = PyLong_FromUnsignedLongLong(
                                 PyArrayScalar_VAL(obj, ULongLong));
    npy_hash_t x = PyObject_Hash(l);
    Py_DECREF(l);
    return x;
}



#line 3369
#if NPY_SIZEOF_HASH_T==NPY_SIZEOF_DATETIME
static npy_hash_t
datetime_arrtype_hash(PyObject *obj)
{
    npy_hash_t x = (npy_hash_t)(PyArrayScalar_VAL(obj, Datetime));
    if (x == -1) {
        x = -2;
    }
    return x;
}
#elif NPY_SIZEOF_LONGLONG==NPY_SIZEOF_DATETIME
static npy_hash_t
datetime_arrtype_hash(PyObject *obj)
{
    npy_hash_t y;
    npy_longlong x = (PyArrayScalar_VAL(obj, Datetime));

    if ((x <= LONG_MAX)) {
        y = (npy_hash_t) x;
    }
    else {
        union Mask {
            long hashvals[2];
            npy_longlong v;
        } both;

        both.v = x;
        y = both.hashvals[0] + (1000003)*both.hashvals[1];
    }
    if (y == -1) {
        y = -2;
    }
    return y;
}
#endif

#line 3369
#if NPY_SIZEOF_HASH_T==NPY_SIZEOF_DATETIME
static npy_hash_t
timedelta_arrtype_hash(PyObject *obj)
{
    npy_hash_t x = (npy_hash_t)(PyArrayScalar_VAL(obj, Timedelta));
    if (x == -1) {
        x = -2;
    }
    return x;
}
#elif NPY_SIZEOF_LONGLONG==NPY_SIZEOF_DATETIME
static npy_hash_t
timedelta_arrtype_hash(PyObject *obj)
{
    npy_hash_t y;
    npy_longlong x = (PyArrayScalar_VAL(obj, Timedelta));

    if ((x <= LONG_MAX)) {
        y = (npy_hash_t) x;
    }
    else {
        union Mask {
            long hashvals[2];
            npy_longlong v;
        } both;

        both.v = x;
        y = both.hashvals[0] + (1000003)*both.hashvals[1];
    }
    if (y == -1) {
        y = -2;
    }
    return y;
}
#endif




/* Wrong thing to do for longdouble, but....*/

#line 3414
static npy_hash_t
float_arrtype_hash(PyObject *obj)
{
    return Npy_HashDouble(obj, (double)PyArrayScalar_VAL(obj, Float));
}

/* borrowed from complex_hash */
static npy_hash_t
cfloat_arrtype_hash(PyObject *obj)
{
    npy_hash_t hashreal, hashimag, combined;
    hashreal = Npy_HashDouble(
            obj, (double)PyArrayScalar_VAL(obj, CFloat).real);

    if (hashreal == -1) {
        return -1;
    }
    hashimag = Npy_HashDouble(
            obj, (double)PyArrayScalar_VAL(obj, CFloat).imag);
    if (hashimag == -1) {
        return -1;
    }
    combined = hashreal + 1000003 * hashimag;
    if (combined == -1) {
        combined = -2;
    }
    return combined;
}

#line 3414
static npy_hash_t
longdouble_arrtype_hash(PyObject *obj)
{
    return Npy_HashDouble(obj, (double)PyArrayScalar_VAL(obj, LongDouble));
}

/* borrowed from complex_hash */
static npy_hash_t
clongdouble_arrtype_hash(PyObject *obj)
{
    npy_hash_t hashreal, hashimag, combined;
    hashreal = Npy_HashDouble(
            obj, (double)PyArrayScalar_VAL(obj, CLongDouble).real);

    if (hashreal == -1) {
        return -1;
    }
    hashimag = Npy_HashDouble(
            obj, (double)PyArrayScalar_VAL(obj, CLongDouble).imag);
    if (hashimag == -1) {
        return -1;
    }
    combined = hashreal + 1000003 * hashimag;
    if (combined == -1) {
        combined = -2;
    }
    return combined;
}


static npy_hash_t
half_arrtype_hash(PyObject *obj)
{
    return Npy_HashDouble(
            obj, npy_half_to_double(PyArrayScalar_VAL(obj, Half)));
}

static npy_hash_t
object_arrtype_hash(PyObject *obj)
{
    return PyObject_Hash(PyArrayScalar_VAL(obj, Object));
}

/* we used to just hash the pointer */
/* now use tuplehash algorithm using voidtype_item to get the object
*/
static npy_hash_t
void_arrtype_hash(PyObject *obj)
{
    npy_hash_t x, y;
    Py_ssize_t len, n;
    PyVoidScalarObject *p;
    PyObject *element;
    npy_hash_t mult = 1000003L;
    x = 0x345678L;
    p = (PyVoidScalarObject *)obj;
    /* Cannot hash mutable void scalars */
    if (p->flags & NPY_ARRAY_WRITEABLE) {
       PyErr_SetString(PyExc_TypeError, "unhashable type: 'writeable void-scalar'");
       return -1;
    }
    len = voidtype_length(p);
    for (n=0; n < len; n++) {
        element = voidtype_item(p, n);
        y = PyObject_Hash(element);
        Py_DECREF(element);
        if (y == -1)
           return -1;
        x = (x ^ y) * mult;
        mult += (npy_hash_t)(82520L + len + len);
    }
    x += 97531L;
    if (x == -1)
        x = -2;
    return x;
}

/*object arrtype getattro and setattro */
static PyObject *
object_arrtype_getattro(PyObjectScalarObject *obj, PyObject *attr) {
    PyObject *res;

    /* first look in object and then hand off to generic type */

    res = PyObject_GenericGetAttr(obj->obval, attr);
    if (res) {
        return res;
    }
    PyErr_Clear();
    return  PyObject_GenericGetAttr((PyObject *)obj, attr);
}

static int
object_arrtype_setattro(PyObjectScalarObject *obj, PyObject *attr, PyObject *val) {
    int res;
    /* first look in object and then hand off to generic type */

    res = PyObject_GenericSetAttr(obj->obval, attr, val);
    if (res >= 0) {
        return res;
    }
    PyErr_Clear();
    return PyObject_GenericSetAttr((PyObject *)obj, attr, val);
}

static PyObject *
object_arrtype_concat(PyObjectScalarObject *self, PyObject *other)
{
    return PySequence_Concat(self->obval, other);
}

static Py_ssize_t
object_arrtype_length(PyObjectScalarObject *self)
{
    return PyObject_Length(self->obval);
}

static PyObject *
object_arrtype_repeat(PyObjectScalarObject *self, Py_ssize_t count)
{
    return PySequence_Repeat(self->obval, count);
}

static PyObject *
object_arrtype_subscript(PyObjectScalarObject *self, PyObject *key)
{
    return PyObject_GetItem(self->obval, key);
}

static int
object_arrtype_ass_subscript(PyObjectScalarObject *self, PyObject *key,
                             PyObject *value)
{
    return PyObject_SetItem(self->obval, key, value);
}

static int
object_arrtype_contains(PyObjectScalarObject *self, PyObject *ob)
{
    return PySequence_Contains(self->obval, ob);
}

static PyObject *
object_arrtype_inplace_concat(PyObjectScalarObject *self, PyObject *o)
{
    return PySequence_InPlaceConcat(self->obval, o);
}

static PyObject *
object_arrtype_inplace_repeat(PyObjectScalarObject *self, Py_ssize_t count)
{
    return PySequence_InPlaceRepeat(self->obval, count);
}

static PySequenceMethods object_arrtype_as_sequence = {
    .sq_length = (lenfunc)object_arrtype_length,
    .sq_concat = (binaryfunc)object_arrtype_concat,
    .sq_repeat = (ssizeargfunc)object_arrtype_repeat,
    .sq_contains = (objobjproc)object_arrtype_contains,
    .sq_inplace_concat = (binaryfunc)object_arrtype_inplace_concat,
    .sq_inplace_repeat = (ssizeargfunc)object_arrtype_inplace_repeat,
};

static PyMappingMethods object_arrtype_as_mapping = {
    .mp_length = (lenfunc)object_arrtype_length,
    .mp_subscript = (binaryfunc)object_arrtype_subscript,
    .mp_ass_subscript = (objobjargproc)object_arrtype_ass_subscript,
};

static int
object_arrtype_getbuffer(PyObjectScalarObject *self, Py_buffer *view, int flags)
{
    PyBufferProcs *pb = Py_TYPE(self->obval)->tp_as_buffer;
    if (pb == NULL || pb->bf_getbuffer == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "expected a readable buffer object");
        return -1;
    }
    return (*pb->bf_getbuffer)(self->obval, view, flags);
}

static void
object_arrtype_releasebuffer(PyObjectScalarObject *self, Py_buffer *view)
{
    PyBufferProcs *pb = Py_TYPE(self->obval)->tp_as_buffer;
    if (pb == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "expected a readable buffer object");
        return;
    }
    if (pb->bf_releasebuffer != NULL) {
        (*pb->bf_releasebuffer)(self->obval, view);
    }
}

static PyBufferProcs object_arrtype_as_buffer = {
    .bf_getbuffer = (getbufferproc)object_arrtype_getbuffer,
    .bf_releasebuffer = (releasebufferproc)object_arrtype_releasebuffer,
};

static PyObject *
object_arrtype_call(PyObjectScalarObject *obj, PyObject *args, PyObject *kwds)
{
    return PyObject_Call(obj->obval, args, kwds);
}

NPY_NO_EXPORT PyTypeObject PyObjectArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_OBJECT_name,
    .tp_basicsize = sizeof(PyObjectScalarObject),
    .tp_dealloc = (destructor)object_arrtype_dealloc,
    .tp_as_sequence = &object_arrtype_as_sequence,
    .tp_as_mapping = &object_arrtype_as_mapping,
    .tp_call = (ternaryfunc)object_arrtype_call,
    .tp_getattro = (getattrofunc)object_arrtype_getattro,
    .tp_setattro = (setattrofunc)object_arrtype_setattro,
    .tp_as_buffer = &object_arrtype_as_buffer,
    .tp_alloc = object_arrtype_alloc,
};

static PyObject *
gen_arrtype_subscript(PyObject *self, PyObject *key)
{
    /*
     * Only [...], [...,<???>], [<???>, ...],
     * is allowed for indexing a scalar
     *
     * These return a new N-d array with a copy of
     * the data where N is the number of None's in <???>.
     */
    PyObject *res, *ret;

    res = PyArray_FromScalar(self, NULL);

    ret = array_subscript((PyArrayObject *)res, key);
    Py_DECREF(res);
    if (ret == NULL) {
        PyErr_SetString(PyExc_IndexError,
                        "invalid index to scalar variable.");
    }
    return ret;
}


#line 3674

NPY_NO_EXPORT PyTypeObject PyBoolArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_BOOL_name,
    .tp_basicsize = sizeof(PyBoolScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyByteArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_BYTE_name,
    .tp_basicsize = sizeof(PyByteScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyShortArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_SHORT_name,
    .tp_basicsize = sizeof(PyShortScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyIntArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_INT_name,
    .tp_basicsize = sizeof(PyIntScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyLongArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_LONG_name,
    .tp_basicsize = sizeof(PyLongScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyLongLongArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_LONGLONG_name,
    .tp_basicsize = sizeof(PyLongLongScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyUByteArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_UBYTE_name,
    .tp_basicsize = sizeof(PyUByteScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyUShortArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_USHORT_name,
    .tp_basicsize = sizeof(PyUShortScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyUIntArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_UINT_name,
    .tp_basicsize = sizeof(PyUIntScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyULongArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_ULONG_name,
    .tp_basicsize = sizeof(PyULongScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyULongLongArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_ULONGLONG_name,
    .tp_basicsize = sizeof(PyULongLongScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyHalfArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_HALF_name,
    .tp_basicsize = sizeof(PyHalfScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyFloatArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_FLOAT_name,
    .tp_basicsize = sizeof(PyFloatScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyDoubleArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_DOUBLE_name,
    .tp_basicsize = sizeof(PyDoubleScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyLongDoubleArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_LONGDOUBLE_name,
    .tp_basicsize = sizeof(PyLongDoubleScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyCFloatArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_CFLOAT_name,
    .tp_basicsize = sizeof(PyCFloatScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyCDoubleArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_CDOUBLE_name,
    .tp_basicsize = sizeof(PyCDoubleScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyCLongDoubleArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_CLONGDOUBLE_name,
    .tp_basicsize = sizeof(PyCLongDoubleScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyStringArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_STRING_name,
    .tp_basicsize = sizeof(PyStringScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyUnicodeArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_UNICODE_name,
    .tp_basicsize = sizeof(PyUnicodeScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyVoidArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_VOID_name,
    .tp_basicsize = sizeof(PyVoidScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyDatetimeArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_DATETIME_name,
    .tp_basicsize = sizeof(PyDatetimeScalarObject),
};


#line 3674

NPY_NO_EXPORT PyTypeObject PyTimedeltaArrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "numpy." NPY_TIMEDELTA_name,
    .tp_basicsize = sizeof(PyTimedeltaScalarObject),
};




static PyMappingMethods gentype_as_mapping = {
    .mp_subscript = (binaryfunc)gen_arrtype_subscript,
};


/*
 * This table maps the built-in type numbers to their scalar
 * type numbers.  Note that signed integers are mapped to INTNEG_SCALAR,
 * which is different than what PyArray_ScalarKind returns.
 */
NPY_NO_EXPORT signed char
_npy_scalar_kinds_table[NPY_NTYPES];

/*
 * This table maps a scalar kind (excluding NPY_NOSCALAR)
 * to the smallest type number of that kind.
 */
NPY_NO_EXPORT signed char
_npy_smallest_type_of_kind_table[NPY_NSCALARKINDS];

/*
 * This table gives the type of the same kind, but next in the sequence
 * of sizes.
 */
NPY_NO_EXPORT signed char
_npy_next_larger_type_table[NPY_NTYPES];

/*
 * This table gives the smallest-size and smallest-kind type to which
 * the input types may be safely cast, according to _npy_can_cast_safely.
 */
NPY_NO_EXPORT signed char
_npy_type_promotion_table[NPY_NTYPES][NPY_NTYPES];

NPY_NO_EXPORT void
initialize_casting_tables(void)
{
    int i, j;

    _npy_smallest_type_of_kind_table[NPY_BOOL_SCALAR] = NPY_BOOL;
    _npy_smallest_type_of_kind_table[NPY_INTPOS_SCALAR] = NPY_UBYTE;
    _npy_smallest_type_of_kind_table[NPY_INTNEG_SCALAR] = NPY_BYTE;
    _npy_smallest_type_of_kind_table[NPY_FLOAT_SCALAR] = NPY_HALF;
    _npy_smallest_type_of_kind_table[NPY_COMPLEX_SCALAR] = NPY_CFLOAT;
    _npy_smallest_type_of_kind_table[NPY_OBJECT_SCALAR] = NPY_OBJECT;

    /* Default for built-in types is object scalar */
    memset(_npy_scalar_kinds_table, NPY_OBJECT_SCALAR,
                                        sizeof(_npy_scalar_kinds_table));
    /* Default for next largest type is -1, signalling no bigger */
    memset(_npy_next_larger_type_table, -1,
                                        sizeof(_npy_next_larger_type_table));

    /* Compile-time loop of scalar kinds */

    #line 3755

    _npy_scalar_kinds_table[NPY_BOOL] = NPY_BOOL_SCALAR;
    _npy_next_larger_type_table[NPY_BOOL] = -1;

    
#line 3755

    _npy_scalar_kinds_table[NPY_BYTE] = NPY_INTNEG_SCALAR;
    _npy_next_larger_type_table[NPY_BYTE] = NPY_SHORT;

    
#line 3755

    _npy_scalar_kinds_table[NPY_UBYTE] = NPY_INTPOS_SCALAR;
    _npy_next_larger_type_table[NPY_UBYTE] = NPY_USHORT;

    
#line 3755

    _npy_scalar_kinds_table[NPY_SHORT] = NPY_INTNEG_SCALAR;
    _npy_next_larger_type_table[NPY_SHORT] = NPY_INT;

    
#line 3755

    _npy_scalar_kinds_table[NPY_USHORT] = NPY_INTPOS_SCALAR;
    _npy_next_larger_type_table[NPY_USHORT] = NPY_UINT;

    
#line 3755

    _npy_scalar_kinds_table[NPY_INT] = NPY_INTNEG_SCALAR;
    _npy_next_larger_type_table[NPY_INT] = NPY_LONG;

    
#line 3755

    _npy_scalar_kinds_table[NPY_UINT] = NPY_INTPOS_SCALAR;
    _npy_next_larger_type_table[NPY_UINT] = NPY_ULONG;

    
#line 3755

    _npy_scalar_kinds_table[NPY_LONG] = NPY_INTNEG_SCALAR;
    _npy_next_larger_type_table[NPY_LONG] = NPY_LONGLONG;

    
#line 3755

    _npy_scalar_kinds_table[NPY_ULONG] = NPY_INTPOS_SCALAR;
    _npy_next_larger_type_table[NPY_ULONG] = NPY_ULONGLONG;

    
#line 3755

    _npy_scalar_kinds_table[NPY_LONGLONG] = NPY_INTNEG_SCALAR;
    _npy_next_larger_type_table[NPY_LONGLONG] = -1;

    
#line 3755

    _npy_scalar_kinds_table[NPY_ULONGLONG] = NPY_INTPOS_SCALAR;
    _npy_next_larger_type_table[NPY_ULONGLONG] = -1;

    
#line 3755

    _npy_scalar_kinds_table[NPY_HALF] = NPY_FLOAT_SCALAR;
    _npy_next_larger_type_table[NPY_HALF] = NPY_FLOAT;

    
#line 3755

    _npy_scalar_kinds_table[NPY_FLOAT] = NPY_FLOAT_SCALAR;
    _npy_next_larger_type_table[NPY_FLOAT] = NPY_DOUBLE;

    
#line 3755

    _npy_scalar_kinds_table[NPY_DOUBLE] = NPY_FLOAT_SCALAR;
    _npy_next_larger_type_table[NPY_DOUBLE] = NPY_LONGDOUBLE;

    
#line 3755

    _npy_scalar_kinds_table[NPY_LONGDOUBLE] = NPY_FLOAT_SCALAR;
    _npy_next_larger_type_table[NPY_LONGDOUBLE] = -1;

    
#line 3755

    _npy_scalar_kinds_table[NPY_CFLOAT] = NPY_COMPLEX_SCALAR;
    _npy_next_larger_type_table[NPY_CFLOAT] = NPY_CDOUBLE;

    
#line 3755

    _npy_scalar_kinds_table[NPY_CDOUBLE] = NPY_COMPLEX_SCALAR;
    _npy_next_larger_type_table[NPY_CDOUBLE] = NPY_CLONGDOUBLE;

    
#line 3755

    _npy_scalar_kinds_table[NPY_CLONGDOUBLE] = NPY_COMPLEX_SCALAR;
    _npy_next_larger_type_table[NPY_CLONGDOUBLE] = -1;

    

#undef _TO_NUM
#undef _TO_BSIZE

/**end repeat1**/

#undef _FROM_NUM
#undef _FROM_BSIZE

/**end repeat**/

    /*
     * Now that the _can_cast_safely table is finished, we can
     * use it to build the _type_promotion table
     */
    for (i = 0; i < NPY_NTYPES; ++i) {
        _npy_type_promotion_table[i][i] = i;
        /* Don't let number promote to string/unicode/void/datetime/timedelta */
        if (i == NPY_STRING || i == NPY_UNICODE || i == NPY_VOID ||
                i == NPY_DATETIME || i == NPY_TIMEDELTA) {
            /* Promoting these types requires examining their contents */
            _npy_type_promotion_table[i][i] = -1;
            for (j = i + 1; j < NPY_NTYPES; ++j) {
                _npy_type_promotion_table[i][j] = -1;
                _npy_type_promotion_table[j][i] = -1;
            }
            /* Except they can convert to OBJECT */
            _npy_type_promotion_table[i][NPY_OBJECT] = NPY_OBJECT;
            _npy_type_promotion_table[NPY_OBJECT][i] = NPY_OBJECT;
        }
        else {
            for (j = i + 1; j < NPY_NTYPES; ++j) {
                /* Don't let number promote to string/unicode/void */
                if (j == NPY_STRING || j == NPY_UNICODE || j == NPY_VOID) {
                    _npy_type_promotion_table[i][j] = -1;
                    _npy_type_promotion_table[j][i] = -1;
                }
                else if (_npy_can_cast_safely_table[i][j]) {
                    _npy_type_promotion_table[i][j] = j;
                    _npy_type_promotion_table[j][i] = j;
                }
                else if (_npy_can_cast_safely_table[j][i]) {
                    _npy_type_promotion_table[i][j] = i;
                    _npy_type_promotion_table[j][i] = i;
                }
                else {
                    int k, iskind, jskind, skind;
                    iskind = _npy_scalar_kinds_table[i];
                    jskind = _npy_scalar_kinds_table[j];
                    /* If there's no kind (void/string/etc) */
                    if (iskind == NPY_NOSCALAR || jskind == NPY_NOSCALAR) {
                        k = -1;
                    }
                    else {
                        /* Start with the type of larger kind */
                        if (iskind > jskind) {
                            skind = iskind;
                            k = i;
                        }
                        else {
                            skind = jskind;
                            k = j;
                        }
                        for (;;) {
                            /* Try the next larger type of this kind */
                            k = _npy_next_larger_type_table[k];

                            /* If there is no larger, try a larger kind */
                            if (k < 0) {
                                ++skind;
                                /* Use -1 to signal no promoted type found */
                                if (skind < NPY_NSCALARKINDS) {
                                    k = _npy_smallest_type_of_kind_table[skind];
                                }
                                else {
                                    k = -1;
                                    break;
                                }
                            }

                            if (_npy_can_cast_safely_table[i][k] &&
                                            _npy_can_cast_safely_table[j][k]) {
                                break;
                            }
                        }
                    }
                    _npy_type_promotion_table[i][j] = k;
                    _npy_type_promotion_table[j][i] = k;
                }
            }
        }
    }
}

static PyNumberMethods longdoubletype_as_number;
static PyNumberMethods clongdoubletype_as_number;
static void init_basetypes(void);


NPY_NO_EXPORT void
initialize_numeric_types(void)
{
    init_basetypes();
    PyGenericArrType_Type.tp_dealloc = (destructor)gentype_dealloc;
    PyGenericArrType_Type.tp_as_number = &gentype_as_number;
    PyGenericArrType_Type.tp_as_mapping = &gentype_as_mapping;
    PyGenericArrType_Type.tp_flags = BASEFLAGS;
    PyGenericArrType_Type.tp_methods = gentype_methods;
    PyGenericArrType_Type.tp_getset = gentype_getsets;
    PyGenericArrType_Type.tp_new = NULL;
    PyGenericArrType_Type.tp_alloc = gentype_alloc;
    PyGenericArrType_Type.tp_free = (freefunc)gentype_free;
    PyGenericArrType_Type.tp_richcompare = gentype_richcompare;
    PyGenericArrType_Type.tp_as_buffer = &gentype_arrtype_as_buffer;

    PyBoolArrType_Type.tp_as_number = &bool_arrtype_as_number;
    /*
     * need to add dummy versions with filled-in nb_index
     * in-order for PyType_Ready to fill in .__index__() method
     * also fill array_type_as_number struct with reasonable defaults
     */

    #line 3888
    byte_arrtype_as_number = gentype_as_number;
    PyByteArrType_Type.tp_as_number = &byte_arrtype_as_number;
    PyByteArrType_Type.tp_as_number->nb_index = (unaryfunc)byte_index;

    
#line 3888
    short_arrtype_as_number = gentype_as_number;
    PyShortArrType_Type.tp_as_number = &short_arrtype_as_number;
    PyShortArrType_Type.tp_as_number->nb_index = (unaryfunc)short_index;

    
#line 3888
    int_arrtype_as_number = gentype_as_number;
    PyIntArrType_Type.tp_as_number = &int_arrtype_as_number;
    PyIntArrType_Type.tp_as_number->nb_index = (unaryfunc)int_index;

    
#line 3888
    long_arrtype_as_number = gentype_as_number;
    PyLongArrType_Type.tp_as_number = &long_arrtype_as_number;
    PyLongArrType_Type.tp_as_number->nb_index = (unaryfunc)long_index;

    
#line 3888
    longlong_arrtype_as_number = gentype_as_number;
    PyLongLongArrType_Type.tp_as_number = &longlong_arrtype_as_number;
    PyLongLongArrType_Type.tp_as_number->nb_index = (unaryfunc)longlong_index;

    
#line 3888
    ubyte_arrtype_as_number = gentype_as_number;
    PyUByteArrType_Type.tp_as_number = &ubyte_arrtype_as_number;
    PyUByteArrType_Type.tp_as_number->nb_index = (unaryfunc)ubyte_index;

    
#line 3888
    ushort_arrtype_as_number = gentype_as_number;
    PyUShortArrType_Type.tp_as_number = &ushort_arrtype_as_number;
    PyUShortArrType_Type.tp_as_number->nb_index = (unaryfunc)ushort_index;

    
#line 3888
    uint_arrtype_as_number = gentype_as_number;
    PyUIntArrType_Type.tp_as_number = &uint_arrtype_as_number;
    PyUIntArrType_Type.tp_as_number->nb_index = (unaryfunc)uint_index;

    
#line 3888
    ulong_arrtype_as_number = gentype_as_number;
    PyULongArrType_Type.tp_as_number = &ulong_arrtype_as_number;
    PyULongArrType_Type.tp_as_number->nb_index = (unaryfunc)ulong_index;

    
#line 3888
    ulonglong_arrtype_as_number = gentype_as_number;
    PyULongLongArrType_Type.tp_as_number = &ulonglong_arrtype_as_number;
    PyULongLongArrType_Type.tp_as_number->nb_index = (unaryfunc)ulonglong_index;

    

    #line 3900
    half_arrtype_as_number = gentype_as_number;
    PyHalfArrType_Type.tp_as_number = &half_arrtype_as_number;

    
#line 3900
    float_arrtype_as_number = gentype_as_number;
    PyFloatArrType_Type.tp_as_number = &float_arrtype_as_number;

    
#line 3900
    double_arrtype_as_number = gentype_as_number;
    PyDoubleArrType_Type.tp_as_number = &double_arrtype_as_number;

    
#line 3900
    longdouble_arrtype_as_number = gentype_as_number;
    PyLongDoubleArrType_Type.tp_as_number = &longdouble_arrtype_as_number;

    
#line 3900
    cfloat_arrtype_as_number = gentype_as_number;
    PyCFloatArrType_Type.tp_as_number = &cfloat_arrtype_as_number;

    
#line 3900
    cdouble_arrtype_as_number = gentype_as_number;
    PyCDoubleArrType_Type.tp_as_number = &cdouble_arrtype_as_number;

    
#line 3900
    clongdouble_arrtype_as_number = gentype_as_number;
    PyCLongDoubleArrType_Type.tp_as_number = &clongdouble_arrtype_as_number;

    

    PyBoolArrType_Type.tp_as_number->nb_index = (unaryfunc)bool_index;

    PyStringArrType_Type.tp_alloc = NULL;
    PyStringArrType_Type.tp_free = NULL;

    PyStringArrType_Type.tp_repr = stringtype_repr;
    PyStringArrType_Type.tp_str = stringtype_str;

    PyUnicodeArrType_Type.tp_repr = unicodetype_repr;
    PyUnicodeArrType_Type.tp_str = unicodetype_str;

    PyVoidArrType_Type.tp_methods = voidtype_methods;
    PyVoidArrType_Type.tp_getset = voidtype_getsets;
    PyVoidArrType_Type.tp_as_mapping = &voidtype_as_mapping;
    PyVoidArrType_Type.tp_as_sequence = &voidtype_as_sequence;
    PyVoidArrType_Type.tp_repr = voidtype_repr;
    PyVoidArrType_Type.tp_str = voidtype_str;

    PyIntegerArrType_Type.tp_getset = inttype_getsets;

    PyNumberArrType_Type.tp_methods = numbertype_methods;

    #line 3931

    PyNumberArrType_Type.tp_flags = BASEFLAGS;

    
#line 3931

    PyIntegerArrType_Type.tp_flags = BASEFLAGS;

    
#line 3931

    PySignedIntegerArrType_Type.tp_flags = BASEFLAGS;

    
#line 3931

    PyUnsignedIntegerArrType_Type.tp_flags = BASEFLAGS;

    
#line 3931

    PyInexactArrType_Type.tp_flags = BASEFLAGS;

    
#line 3931

    PyFloatingArrType_Type.tp_flags = BASEFLAGS;

    
#line 3931

    PyComplexFloatingArrType_Type.tp_flags = BASEFLAGS;

    
#line 3931

    PyFlexibleArrType_Type.tp_flags = BASEFLAGS;

    
#line 3931

    PyCharacterArrType_Type.tp_flags = BASEFLAGS;

    

    #line 3946

    PyBoolArrType_Type.tp_flags = BASEFLAGS;
    PyBoolArrType_Type.tp_new = bool_arrtype_new;
    PyBoolArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_Bool  /* inherit string buffer */
#if !defined(_IS_String)
    PyBoolArrType_Type.tp_as_buffer = &bool_arrtype_as_buffer;
#endif
#undef _IS_Bool

    
#line 3946

    PyByteArrType_Type.tp_flags = BASEFLAGS;
    PyByteArrType_Type.tp_new = byte_arrtype_new;
    PyByteArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_Byte  /* inherit string buffer */
#if !defined(_IS_String)
    PyByteArrType_Type.tp_as_buffer = &byte_arrtype_as_buffer;
#endif
#undef _IS_Byte

    
#line 3946

    PyShortArrType_Type.tp_flags = BASEFLAGS;
    PyShortArrType_Type.tp_new = short_arrtype_new;
    PyShortArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_Short  /* inherit string buffer */
#if !defined(_IS_String)
    PyShortArrType_Type.tp_as_buffer = &short_arrtype_as_buffer;
#endif
#undef _IS_Short

    
#line 3946

    PyIntArrType_Type.tp_flags = BASEFLAGS;
    PyIntArrType_Type.tp_new = int_arrtype_new;
    PyIntArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_Int  /* inherit string buffer */
#if !defined(_IS_String)
    PyIntArrType_Type.tp_as_buffer = &int_arrtype_as_buffer;
#endif
#undef _IS_Int

    
#line 3946

    PyLongArrType_Type.tp_flags = BASEFLAGS;
    PyLongArrType_Type.tp_new = long_arrtype_new;
    PyLongArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_Long  /* inherit string buffer */
#if !defined(_IS_String)
    PyLongArrType_Type.tp_as_buffer = &long_arrtype_as_buffer;
#endif
#undef _IS_Long

    
#line 3946

    PyLongLongArrType_Type.tp_flags = BASEFLAGS;
    PyLongLongArrType_Type.tp_new = longlong_arrtype_new;
    PyLongLongArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_LongLong  /* inherit string buffer */
#if !defined(_IS_String)
    PyLongLongArrType_Type.tp_as_buffer = &longlong_arrtype_as_buffer;
#endif
#undef _IS_LongLong

    
#line 3946

    PyUByteArrType_Type.tp_flags = BASEFLAGS;
    PyUByteArrType_Type.tp_new = ubyte_arrtype_new;
    PyUByteArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_UByte  /* inherit string buffer */
#if !defined(_IS_String)
    PyUByteArrType_Type.tp_as_buffer = &ubyte_arrtype_as_buffer;
#endif
#undef _IS_UByte

    
#line 3946

    PyUShortArrType_Type.tp_flags = BASEFLAGS;
    PyUShortArrType_Type.tp_new = ushort_arrtype_new;
    PyUShortArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_UShort  /* inherit string buffer */
#if !defined(_IS_String)
    PyUShortArrType_Type.tp_as_buffer = &ushort_arrtype_as_buffer;
#endif
#undef _IS_UShort

    
#line 3946

    PyUIntArrType_Type.tp_flags = BASEFLAGS;
    PyUIntArrType_Type.tp_new = uint_arrtype_new;
    PyUIntArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_UInt  /* inherit string buffer */
#if !defined(_IS_String)
    PyUIntArrType_Type.tp_as_buffer = &uint_arrtype_as_buffer;
#endif
#undef _IS_UInt

    
#line 3946

    PyULongArrType_Type.tp_flags = BASEFLAGS;
    PyULongArrType_Type.tp_new = ulong_arrtype_new;
    PyULongArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_ULong  /* inherit string buffer */
#if !defined(_IS_String)
    PyULongArrType_Type.tp_as_buffer = &ulong_arrtype_as_buffer;
#endif
#undef _IS_ULong

    
#line 3946

    PyULongLongArrType_Type.tp_flags = BASEFLAGS;
    PyULongLongArrType_Type.tp_new = ulonglong_arrtype_new;
    PyULongLongArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_ULongLong  /* inherit string buffer */
#if !defined(_IS_String)
    PyULongLongArrType_Type.tp_as_buffer = &ulonglong_arrtype_as_buffer;
#endif
#undef _IS_ULongLong

    
#line 3946

    PyHalfArrType_Type.tp_flags = BASEFLAGS;
    PyHalfArrType_Type.tp_new = half_arrtype_new;
    PyHalfArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_Half  /* inherit string buffer */
#if !defined(_IS_String)
    PyHalfArrType_Type.tp_as_buffer = &half_arrtype_as_buffer;
#endif
#undef _IS_Half

    
#line 3946

    PyFloatArrType_Type.tp_flags = BASEFLAGS;
    PyFloatArrType_Type.tp_new = float_arrtype_new;
    PyFloatArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_Float  /* inherit string buffer */
#if !defined(_IS_String)
    PyFloatArrType_Type.tp_as_buffer = &float_arrtype_as_buffer;
#endif
#undef _IS_Float

    
#line 3946

    PyDoubleArrType_Type.tp_flags = BASEFLAGS;
    PyDoubleArrType_Type.tp_new = double_arrtype_new;
    PyDoubleArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_Double  /* inherit string buffer */
#if !defined(_IS_String)
    PyDoubleArrType_Type.tp_as_buffer = &double_arrtype_as_buffer;
#endif
#undef _IS_Double

    
#line 3946

    PyLongDoubleArrType_Type.tp_flags = BASEFLAGS;
    PyLongDoubleArrType_Type.tp_new = longdouble_arrtype_new;
    PyLongDoubleArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_LongDouble  /* inherit string buffer */
#if !defined(_IS_String)
    PyLongDoubleArrType_Type.tp_as_buffer = &longdouble_arrtype_as_buffer;
#endif
#undef _IS_LongDouble

    
#line 3946

    PyCFloatArrType_Type.tp_flags = BASEFLAGS;
    PyCFloatArrType_Type.tp_new = cfloat_arrtype_new;
    PyCFloatArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_CFloat  /* inherit string buffer */
#if !defined(_IS_String)
    PyCFloatArrType_Type.tp_as_buffer = &cfloat_arrtype_as_buffer;
#endif
#undef _IS_CFloat

    
#line 3946

    PyCDoubleArrType_Type.tp_flags = BASEFLAGS;
    PyCDoubleArrType_Type.tp_new = cdouble_arrtype_new;
    PyCDoubleArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_CDouble  /* inherit string buffer */
#if !defined(_IS_String)
    PyCDoubleArrType_Type.tp_as_buffer = &cdouble_arrtype_as_buffer;
#endif
#undef _IS_CDouble

    
#line 3946

    PyCLongDoubleArrType_Type.tp_flags = BASEFLAGS;
    PyCLongDoubleArrType_Type.tp_new = clongdouble_arrtype_new;
    PyCLongDoubleArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_CLongDouble  /* inherit string buffer */
#if !defined(_IS_String)
    PyCLongDoubleArrType_Type.tp_as_buffer = &clongdouble_arrtype_as_buffer;
#endif
#undef _IS_CLongDouble

    
#line 3946

    PyStringArrType_Type.tp_flags = BASEFLAGS;
    PyStringArrType_Type.tp_new = string_arrtype_new;
    PyStringArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_String  /* inherit string buffer */
#if !defined(_IS_String)
    PyStringArrType_Type.tp_as_buffer = &string_arrtype_as_buffer;
#endif
#undef _IS_String

    
#line 3946

    PyUnicodeArrType_Type.tp_flags = BASEFLAGS;
    PyUnicodeArrType_Type.tp_new = unicode_arrtype_new;
    PyUnicodeArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_Unicode  /* inherit string buffer */
#if !defined(_IS_String)
    PyUnicodeArrType_Type.tp_as_buffer = &unicode_arrtype_as_buffer;
#endif
#undef _IS_Unicode

    
#line 3946

    PyVoidArrType_Type.tp_flags = BASEFLAGS;
    PyVoidArrType_Type.tp_new = void_arrtype_new;
    PyVoidArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_Void  /* inherit string buffer */
#if !defined(_IS_String)
    PyVoidArrType_Type.tp_as_buffer = &void_arrtype_as_buffer;
#endif
#undef _IS_Void

    
#line 3946

    PyObjectArrType_Type.tp_flags = BASEFLAGS;
    PyObjectArrType_Type.tp_new = object_arrtype_new;
    PyObjectArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_Object  /* inherit string buffer */
#if !defined(_IS_String)
    PyObjectArrType_Type.tp_as_buffer = &object_arrtype_as_buffer;
#endif
#undef _IS_Object

    
#line 3946

    PyDatetimeArrType_Type.tp_flags = BASEFLAGS;
    PyDatetimeArrType_Type.tp_new = datetime_arrtype_new;
    PyDatetimeArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_Datetime  /* inherit string buffer */
#if !defined(_IS_String)
    PyDatetimeArrType_Type.tp_as_buffer = &datetime_arrtype_as_buffer;
#endif
#undef _IS_Datetime

    
#line 3946

    PyTimedeltaArrType_Type.tp_flags = BASEFLAGS;
    PyTimedeltaArrType_Type.tp_new = timedelta_arrtype_new;
    PyTimedeltaArrType_Type.tp_richcompare = gentype_richcompare;

#define _IS_Timedelta  /* inherit string buffer */
#if !defined(_IS_String)
    PyTimedeltaArrType_Type.tp_as_buffer = &timedelta_arrtype_as_buffer;
#endif
#undef _IS_Timedelta

    

    PyUnicodeArrType_Type.tp_dealloc = unicode_arrtype_dealloc;

    #line 3969

    PyBoolArrType_Type.tp_hash = bool_arrtype_hash;

    
#line 3969

    PyByteArrType_Type.tp_hash = byte_arrtype_hash;

    
#line 3969

    PyShortArrType_Type.tp_hash = short_arrtype_hash;

    
#line 3969

    PyUByteArrType_Type.tp_hash = ubyte_arrtype_hash;

    
#line 3969

    PyUShortArrType_Type.tp_hash = ushort_arrtype_hash;

    
#line 3969

    PyUIntArrType_Type.tp_hash = uint_arrtype_hash;

    
#line 3969

    PyULongArrType_Type.tp_hash = ulong_arrtype_hash;

    
#line 3969

    PyULongLongArrType_Type.tp_hash = ulonglong_arrtype_hash;

    
#line 3969

    PyHalfArrType_Type.tp_hash = half_arrtype_hash;

    
#line 3969

    PyFloatArrType_Type.tp_hash = float_arrtype_hash;

    
#line 3969

    PyLongDoubleArrType_Type.tp_hash = longdouble_arrtype_hash;

    
#line 3969

    PyCFloatArrType_Type.tp_hash = cfloat_arrtype_hash;

    
#line 3969

    PyCLongDoubleArrType_Type.tp_hash = clongdouble_arrtype_hash;

    
#line 3969

    PyVoidArrType_Type.tp_hash = void_arrtype_hash;

    
#line 3969

    PyObjectArrType_Type.tp_hash = object_arrtype_hash;

    
#line 3969

    PyDatetimeArrType_Type.tp_hash = datetime_arrtype_hash;

    
#line 3969

    PyTimedeltaArrType_Type.tp_hash = timedelta_arrtype_hash;

    

    #line 3978

    PyCFloatArrType_Type.tp_methods = cfloattype_methods;

    
#line 3978

    PyCLongDoubleArrType_Type.tp_methods = clongdoubletype_methods;

    
#line 3978

    PyFloatingArrType_Type.tp_methods = floatingtype_methods;

    
#line 3978

    PyIntegerArrType_Type.tp_methods = integertype_methods;

    
#line 3978

    PyComplexFloatingArrType_Type.tp_methods = complexfloatingtype_methods;

    

    #line 3989

    PyByteArrType_Type.tp_methods = bytetype_methods;

    
#line 3989

    PyShortArrType_Type.tp_methods = shorttype_methods;

    
#line 3989

    PyIntArrType_Type.tp_methods = inttype_methods;

    
#line 3989

    PyLongArrType_Type.tp_methods = longtype_methods;

    
#line 3989

    PyLongLongArrType_Type.tp_methods = longlongtype_methods;

    
#line 3989

    PyUByteArrType_Type.tp_methods = ubytetype_methods;

    
#line 3989

    PyUShortArrType_Type.tp_methods = ushorttype_methods;

    
#line 3989

    PyUIntArrType_Type.tp_methods = uinttype_methods;

    
#line 3989

    PyULongArrType_Type.tp_methods = ulongtype_methods;

    
#line 3989

    PyULongLongArrType_Type.tp_methods = ulonglongtype_methods;

    

    #line 3998

    PyHalfArrType_Type.tp_methods = halftype_methods;

    
#line 3998

    PyFloatArrType_Type.tp_methods = floattype_methods;

    
#line 3998

    PyDoubleArrType_Type.tp_methods = doubletype_methods;

    
#line 3998

    PyLongDoubleArrType_Type.tp_methods = longdoubletype_methods;

    

    #line 4009

    PyByteArrType_Type.tp_methods = bytetype_methods;

    
#line 4009

    PyShortArrType_Type.tp_methods = shorttype_methods;

    
#line 4009

    PyIntArrType_Type.tp_methods = inttype_methods;

    
#line 4009

    PyLongArrType_Type.tp_methods = longtype_methods;

    
#line 4009

    PyLongLongArrType_Type.tp_methods = longlongtype_methods;

    
#line 4009

    PyUByteArrType_Type.tp_methods = ubytetype_methods;

    
#line 4009

    PyUShortArrType_Type.tp_methods = ushorttype_methods;

    
#line 4009

    PyUIntArrType_Type.tp_methods = uinttype_methods;

    
#line 4009

    PyULongArrType_Type.tp_methods = ulongtype_methods;

    
#line 4009

    PyULongLongArrType_Type.tp_methods = ulonglongtype_methods;

    
#line 4009

    PyTimedeltaArrType_Type.tp_methods = timedeltatype_methods;

    
#line 4009

    PyCDoubleArrType_Type.tp_methods = cdoubletype_methods;

    

    /* We won't be inheriting from Python Int type. */
    PyIntArrType_Type.tp_hash = int_arrtype_hash;

    /* We won't be inheriting from Python Int type. */
    PyLongArrType_Type.tp_hash = long_arrtype_hash;

    /* We won't be inheriting from Python Int type. */
    PyLongLongArrType_Type.tp_hash = longlong_arrtype_hash;

    #line 4026

    PyHalfArrType_Type.tp_repr = halftype_repr;

    PyFloatArrType_Type.tp_repr = floattype_repr;
    PyCFloatArrType_Type.tp_repr = cfloattype_repr;

    PyDoubleArrType_Type.tp_repr = doubletype_repr;
    PyCDoubleArrType_Type.tp_repr  = cdoubletype_repr;

    PyDatetimeArrType_Type.tp_repr = datetimetype_repr;
    PyTimedeltaArrType_Type.tp_repr = timedeltatype_repr;

    
#line 4026

    PyHalfArrType_Type.tp_str = halftype_str;

    PyFloatArrType_Type.tp_str = floattype_str;
    PyCFloatArrType_Type.tp_str = cfloattype_str;

    PyDoubleArrType_Type.tp_str = doubletype_str;
    PyCDoubleArrType_Type.tp_str  = cdoubletype_str;

    PyDatetimeArrType_Type.tp_str = datetimetype_str;
    PyTimedeltaArrType_Type.tp_str = timedeltatype_str;

    


    #line 4045

    /* both str/repr use genint_type_str to avoid trailing "L" of longs */
    PyBoolArrType_Type.tp_str = genint_type_str;
    PyBoolArrType_Type.tp_repr = genint_type_str;

    
#line 4045

    /* both str/repr use genint_type_str to avoid trailing "L" of longs */
    PyByteArrType_Type.tp_str = genint_type_str;
    PyByteArrType_Type.tp_repr = genint_type_str;

    
#line 4045

    /* both str/repr use genint_type_str to avoid trailing "L" of longs */
    PyUByteArrType_Type.tp_str = genint_type_str;
    PyUByteArrType_Type.tp_repr = genint_type_str;

    
#line 4045

    /* both str/repr use genint_type_str to avoid trailing "L" of longs */
    PyShortArrType_Type.tp_str = genint_type_str;
    PyShortArrType_Type.tp_repr = genint_type_str;

    
#line 4045

    /* both str/repr use genint_type_str to avoid trailing "L" of longs */
    PyUShortArrType_Type.tp_str = genint_type_str;
    PyUShortArrType_Type.tp_repr = genint_type_str;

    
#line 4045

    /* both str/repr use genint_type_str to avoid trailing "L" of longs */
    PyIntArrType_Type.tp_str = genint_type_str;
    PyIntArrType_Type.tp_repr = genint_type_str;

    
#line 4045

    /* both str/repr use genint_type_str to avoid trailing "L" of longs */
    PyUIntArrType_Type.tp_str = genint_type_str;
    PyUIntArrType_Type.tp_repr = genint_type_str;

    
#line 4045

    /* both str/repr use genint_type_str to avoid trailing "L" of longs */
    PyLongArrType_Type.tp_str = genint_type_str;
    PyLongArrType_Type.tp_repr = genint_type_str;

    
#line 4045

    /* both str/repr use genint_type_str to avoid trailing "L" of longs */
    PyULongArrType_Type.tp_str = genint_type_str;
    PyULongArrType_Type.tp_repr = genint_type_str;

    
#line 4045

    /* both str/repr use genint_type_str to avoid trailing "L" of longs */
    PyLongLongArrType_Type.tp_str = genint_type_str;
    PyLongLongArrType_Type.tp_repr = genint_type_str;

    
#line 4045

    /* both str/repr use genint_type_str to avoid trailing "L" of longs */
    PyULongLongArrType_Type.tp_str = genint_type_str;
    PyULongLongArrType_Type.tp_repr = genint_type_str;

    



    #line 4058

    /*
     * These need to be coded specially because longdouble/clongdouble getitem
     * does not return a normal Python type
     */
    longdoubletype_as_number.nb_float = longdoubletype_float;
    longdoubletype_as_number.nb_int  = longdoubletype_long;

    PyLongDoubleArrType_Type.tp_as_number = &longdoubletype_as_number;
    PyLongDoubleArrType_Type.tp_repr = longdoubletype_repr;
    PyLongDoubleArrType_Type.tp_str = longdoubletype_str;

    
#line 4058

    /*
     * These need to be coded specially because longdouble/clongdouble getitem
     * does not return a normal Python type
     */
    clongdoubletype_as_number.nb_float = clongdoubletype_float;
    clongdoubletype_as_number.nb_int  = clongdoubletype_long;

    PyCLongDoubleArrType_Type.tp_as_number = &clongdoubletype_as_number;
    PyCLongDoubleArrType_Type.tp_repr = clongdoubletype_repr;
    PyCLongDoubleArrType_Type.tp_str = clongdoubletype_str;

    

    PyStringArrType_Type.tp_itemsize = sizeof(char);
    PyVoidArrType_Type.tp_dealloc = (destructor) void_dealloc;

    PyArrayIter_Type.tp_iter = PyObject_SelfIter;
    PyArrayMapIter_Type.tp_iter = PyObject_SelfIter;
}

typedef struct {
    PyTypeObject * type;
    int typenum;
} scalar_type;

static scalar_type typeobjects[] = {
    {&PyBoolArrType_Type, NPY_BOOL},
    {&PyByteArrType_Type, NPY_BYTE},
    {&PyUByteArrType_Type, NPY_UBYTE},
    {&PyShortArrType_Type, NPY_SHORT},
    {&PyUShortArrType_Type, NPY_USHORT},
    {&PyIntArrType_Type, NPY_INT},
    {&PyUIntArrType_Type, NPY_UINT},
    {&PyLongArrType_Type, NPY_LONG},
    {&PyULongArrType_Type, NPY_ULONG},
    {&PyLongLongArrType_Type, NPY_LONGLONG},
    {&PyULongLongArrType_Type, NPY_ULONGLONG},
    {&PyFloatArrType_Type, NPY_FLOAT},
    {&PyDoubleArrType_Type, NPY_DOUBLE},
    {&PyLongDoubleArrType_Type, NPY_LONGDOUBLE},
    {&PyCFloatArrType_Type, NPY_CFLOAT},
    {&PyCDoubleArrType_Type, NPY_CDOUBLE},
    {&PyCLongDoubleArrType_Type, NPY_CLONGDOUBLE},
    {&PyObjectArrType_Type, NPY_OBJECT},
    {&PyStringArrType_Type, NPY_STRING},
    {&PyUnicodeArrType_Type, NPY_UNICODE},
    {&PyVoidArrType_Type, NPY_VOID},
    {&PyDatetimeArrType_Type, NPY_DATETIME},
    {&PyTimedeltaArrType_Type, NPY_TIMEDELTA},
    {&PyHalfArrType_Type, NPY_HALF}
};

static int compare_types(const void * a_, const void * b_)
{
    const PyTypeObject * a = ((const scalar_type *)a_)->type;
    const PyTypeObject * b = ((const scalar_type *)b_)->type;
    if (a < b) {
        return -1;
    }
    else if (a > b) {
        return 1;
    }
    return 0;
}

static void init_basetypes(void)
{
    qsort(typeobjects, sizeof(typeobjects) / sizeof(typeobjects[0]),
          sizeof(typeobjects[0]),
          compare_types);
}


NPY_NO_EXPORT int
get_typeobj_idx(PyTypeObject * obj)
{
    npy_intp imin = 0, imax = sizeof(typeobjects) / sizeof(typeobjects[0]) - 1;
    while (imax >= imin)
    {
        npy_intp imid = ((imax - imin) / 2) + imin;
        if(typeobjects[imid].type == obj) {
            return imid;
        }
        else if (typeobjects[imid].type < obj) {
            imin = imid + 1;
        }
        else {
            imax = imid - 1;
        }
    }

    return -1;
}

NPY_NO_EXPORT int
is_anyscalar_exact(PyObject *obj)
{
    return get_typeobj_idx(Py_TYPE(obj)) >= 0;
}

NPY_NO_EXPORT int
_typenum_fromtypeobj(PyObject *type, int user)
{
    int typenum, i;

    typenum = NPY_NOTYPE;
    i = get_typeobj_idx((PyTypeObject*)type);
    if (i >= 0) {
        typenum = typeobjects[i].typenum;
    }

    if (!user) {
        return typenum;
    }
    /* Search any registered types */
    i = 0;
    while (i < NPY_NUMUSERTYPES) {
        if (type == (PyObject *)(userdescrs[i]->typeobj)) {
            typenum = i + NPY_USERDEF;
            break;
        }
        i++;
    }
    return typenum;
}

