17db96d56Sopenharmony_ci
27db96d56Sopenharmony_ci/* Complex object implementation */
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci/* Borrows heavily from floatobject.c */
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ci/* Submitted by Jim Hugunin */
77db96d56Sopenharmony_ci
87db96d56Sopenharmony_ci#include "Python.h"
97db96d56Sopenharmony_ci#include "pycore_call.h"          // _PyObject_CallNoArgs()
107db96d56Sopenharmony_ci#include "pycore_long.h"          // _PyLong_GetZero()
117db96d56Sopenharmony_ci#include "pycore_object.h"        // _PyObject_Init()
127db96d56Sopenharmony_ci#include "pycore_pymath.h"        // _Py_ADJUST_ERANGE2()
137db96d56Sopenharmony_ci#include "structmember.h"         // PyMemberDef
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ci/*[clinic input]
177db96d56Sopenharmony_ciclass complex "PyComplexObject *" "&PyComplex_Type"
187db96d56Sopenharmony_ci[clinic start generated code]*/
197db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=819e057d2d10f5ec]*/
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_ci#include "clinic/complexobject.c.h"
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_ci/* elementary operations on complex numbers */
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_cistatic Py_complex c_1 = {1., 0.};
267db96d56Sopenharmony_ci
277db96d56Sopenharmony_ciPy_complex
287db96d56Sopenharmony_ci_Py_c_sum(Py_complex a, Py_complex b)
297db96d56Sopenharmony_ci{
307db96d56Sopenharmony_ci    Py_complex r;
317db96d56Sopenharmony_ci    r.real = a.real + b.real;
327db96d56Sopenharmony_ci    r.imag = a.imag + b.imag;
337db96d56Sopenharmony_ci    return r;
347db96d56Sopenharmony_ci}
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ciPy_complex
377db96d56Sopenharmony_ci_Py_c_diff(Py_complex a, Py_complex b)
387db96d56Sopenharmony_ci{
397db96d56Sopenharmony_ci    Py_complex r;
407db96d56Sopenharmony_ci    r.real = a.real - b.real;
417db96d56Sopenharmony_ci    r.imag = a.imag - b.imag;
427db96d56Sopenharmony_ci    return r;
437db96d56Sopenharmony_ci}
447db96d56Sopenharmony_ci
457db96d56Sopenharmony_ciPy_complex
467db96d56Sopenharmony_ci_Py_c_neg(Py_complex a)
477db96d56Sopenharmony_ci{
487db96d56Sopenharmony_ci    Py_complex r;
497db96d56Sopenharmony_ci    r.real = -a.real;
507db96d56Sopenharmony_ci    r.imag = -a.imag;
517db96d56Sopenharmony_ci    return r;
527db96d56Sopenharmony_ci}
537db96d56Sopenharmony_ci
547db96d56Sopenharmony_ciPy_complex
557db96d56Sopenharmony_ci_Py_c_prod(Py_complex a, Py_complex b)
567db96d56Sopenharmony_ci{
577db96d56Sopenharmony_ci    Py_complex r;
587db96d56Sopenharmony_ci    r.real = a.real*b.real - a.imag*b.imag;
597db96d56Sopenharmony_ci    r.imag = a.real*b.imag + a.imag*b.real;
607db96d56Sopenharmony_ci    return r;
617db96d56Sopenharmony_ci}
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ci/* Avoid bad optimization on Windows ARM64 until the compiler is fixed */
647db96d56Sopenharmony_ci#ifdef _M_ARM64
657db96d56Sopenharmony_ci#pragma optimize("", off)
667db96d56Sopenharmony_ci#endif
677db96d56Sopenharmony_ciPy_complex
687db96d56Sopenharmony_ci_Py_c_quot(Py_complex a, Py_complex b)
697db96d56Sopenharmony_ci{
707db96d56Sopenharmony_ci    /******************************************************************
717db96d56Sopenharmony_ci    This was the original algorithm.  It's grossly prone to spurious
727db96d56Sopenharmony_ci    overflow and underflow errors.  It also merrily divides by 0 despite
737db96d56Sopenharmony_ci    checking for that(!).  The code still serves a doc purpose here, as
747db96d56Sopenharmony_ci    the algorithm following is a simple by-cases transformation of this
757db96d56Sopenharmony_ci    one:
767db96d56Sopenharmony_ci
777db96d56Sopenharmony_ci    Py_complex r;
787db96d56Sopenharmony_ci    double d = b.real*b.real + b.imag*b.imag;
797db96d56Sopenharmony_ci    if (d == 0.)
807db96d56Sopenharmony_ci        errno = EDOM;
817db96d56Sopenharmony_ci    r.real = (a.real*b.real + a.imag*b.imag)/d;
827db96d56Sopenharmony_ci    r.imag = (a.imag*b.real - a.real*b.imag)/d;
837db96d56Sopenharmony_ci    return r;
847db96d56Sopenharmony_ci    ******************************************************************/
857db96d56Sopenharmony_ci
867db96d56Sopenharmony_ci    /* This algorithm is better, and is pretty obvious:  first divide the
877db96d56Sopenharmony_ci     * numerators and denominator by whichever of {b.real, b.imag} has
887db96d56Sopenharmony_ci     * larger magnitude.  The earliest reference I found was to CACM
897db96d56Sopenharmony_ci     * Algorithm 116 (Complex Division, Robert L. Smith, Stanford
907db96d56Sopenharmony_ci     * University).  As usual, though, we're still ignoring all IEEE
917db96d56Sopenharmony_ci     * endcases.
927db96d56Sopenharmony_ci     */
937db96d56Sopenharmony_ci     Py_complex r;      /* the result */
947db96d56Sopenharmony_ci     const double abs_breal = b.real < 0 ? -b.real : b.real;
957db96d56Sopenharmony_ci     const double abs_bimag = b.imag < 0 ? -b.imag : b.imag;
967db96d56Sopenharmony_ci
977db96d56Sopenharmony_ci    if (abs_breal >= abs_bimag) {
987db96d56Sopenharmony_ci        /* divide tops and bottom by b.real */
997db96d56Sopenharmony_ci        if (abs_breal == 0.0) {
1007db96d56Sopenharmony_ci            errno = EDOM;
1017db96d56Sopenharmony_ci            r.real = r.imag = 0.0;
1027db96d56Sopenharmony_ci        }
1037db96d56Sopenharmony_ci        else {
1047db96d56Sopenharmony_ci            const double ratio = b.imag / b.real;
1057db96d56Sopenharmony_ci            const double denom = b.real + b.imag * ratio;
1067db96d56Sopenharmony_ci            r.real = (a.real + a.imag * ratio) / denom;
1077db96d56Sopenharmony_ci            r.imag = (a.imag - a.real * ratio) / denom;
1087db96d56Sopenharmony_ci        }
1097db96d56Sopenharmony_ci    }
1107db96d56Sopenharmony_ci    else if (abs_bimag >= abs_breal) {
1117db96d56Sopenharmony_ci        /* divide tops and bottom by b.imag */
1127db96d56Sopenharmony_ci        const double ratio = b.real / b.imag;
1137db96d56Sopenharmony_ci        const double denom = b.real * ratio + b.imag;
1147db96d56Sopenharmony_ci        assert(b.imag != 0.0);
1157db96d56Sopenharmony_ci        r.real = (a.real * ratio + a.imag) / denom;
1167db96d56Sopenharmony_ci        r.imag = (a.imag * ratio - a.real) / denom;
1177db96d56Sopenharmony_ci    }
1187db96d56Sopenharmony_ci    else {
1197db96d56Sopenharmony_ci        /* At least one of b.real or b.imag is a NaN */
1207db96d56Sopenharmony_ci        r.real = r.imag = Py_NAN;
1217db96d56Sopenharmony_ci    }
1227db96d56Sopenharmony_ci    return r;
1237db96d56Sopenharmony_ci}
1247db96d56Sopenharmony_ci#ifdef _M_ARM64
1257db96d56Sopenharmony_ci#pragma optimize("", on)
1267db96d56Sopenharmony_ci#endif
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_ciPy_complex
1297db96d56Sopenharmony_ci_Py_c_pow(Py_complex a, Py_complex b)
1307db96d56Sopenharmony_ci{
1317db96d56Sopenharmony_ci    Py_complex r;
1327db96d56Sopenharmony_ci    double vabs,len,at,phase;
1337db96d56Sopenharmony_ci    if (b.real == 0. && b.imag == 0.) {
1347db96d56Sopenharmony_ci        r.real = 1.;
1357db96d56Sopenharmony_ci        r.imag = 0.;
1367db96d56Sopenharmony_ci    }
1377db96d56Sopenharmony_ci    else if (a.real == 0. && a.imag == 0.) {
1387db96d56Sopenharmony_ci        if (b.imag != 0. || b.real < 0.)
1397db96d56Sopenharmony_ci            errno = EDOM;
1407db96d56Sopenharmony_ci        r.real = 0.;
1417db96d56Sopenharmony_ci        r.imag = 0.;
1427db96d56Sopenharmony_ci    }
1437db96d56Sopenharmony_ci    else {
1447db96d56Sopenharmony_ci        vabs = hypot(a.real,a.imag);
1457db96d56Sopenharmony_ci        len = pow(vabs,b.real);
1467db96d56Sopenharmony_ci        at = atan2(a.imag, a.real);
1477db96d56Sopenharmony_ci        phase = at*b.real;
1487db96d56Sopenharmony_ci        if (b.imag != 0.0) {
1497db96d56Sopenharmony_ci            len /= exp(at*b.imag);
1507db96d56Sopenharmony_ci            phase += b.imag*log(vabs);
1517db96d56Sopenharmony_ci        }
1527db96d56Sopenharmony_ci        r.real = len*cos(phase);
1537db96d56Sopenharmony_ci        r.imag = len*sin(phase);
1547db96d56Sopenharmony_ci    }
1557db96d56Sopenharmony_ci    return r;
1567db96d56Sopenharmony_ci}
1577db96d56Sopenharmony_ci
1587db96d56Sopenharmony_cistatic Py_complex
1597db96d56Sopenharmony_cic_powu(Py_complex x, long n)
1607db96d56Sopenharmony_ci{
1617db96d56Sopenharmony_ci    Py_complex r, p;
1627db96d56Sopenharmony_ci    long mask = 1;
1637db96d56Sopenharmony_ci    r = c_1;
1647db96d56Sopenharmony_ci    p = x;
1657db96d56Sopenharmony_ci    while (mask > 0 && n >= mask) {
1667db96d56Sopenharmony_ci        if (n & mask)
1677db96d56Sopenharmony_ci            r = _Py_c_prod(r,p);
1687db96d56Sopenharmony_ci        mask <<= 1;
1697db96d56Sopenharmony_ci        p = _Py_c_prod(p,p);
1707db96d56Sopenharmony_ci    }
1717db96d56Sopenharmony_ci    return r;
1727db96d56Sopenharmony_ci}
1737db96d56Sopenharmony_ci
1747db96d56Sopenharmony_cistatic Py_complex
1757db96d56Sopenharmony_cic_powi(Py_complex x, long n)
1767db96d56Sopenharmony_ci{
1777db96d56Sopenharmony_ci    if (n > 0)
1787db96d56Sopenharmony_ci        return c_powu(x,n);
1797db96d56Sopenharmony_ci    else
1807db96d56Sopenharmony_ci        return _Py_c_quot(c_1, c_powu(x,-n));
1817db96d56Sopenharmony_ci
1827db96d56Sopenharmony_ci}
1837db96d56Sopenharmony_ci
1847db96d56Sopenharmony_cidouble
1857db96d56Sopenharmony_ci_Py_c_abs(Py_complex z)
1867db96d56Sopenharmony_ci{
1877db96d56Sopenharmony_ci    /* sets errno = ERANGE on overflow;  otherwise errno = 0 */
1887db96d56Sopenharmony_ci    double result;
1897db96d56Sopenharmony_ci
1907db96d56Sopenharmony_ci    if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
1917db96d56Sopenharmony_ci        /* C99 rules: if either the real or the imaginary part is an
1927db96d56Sopenharmony_ci           infinity, return infinity, even if the other part is a
1937db96d56Sopenharmony_ci           NaN. */
1947db96d56Sopenharmony_ci        if (Py_IS_INFINITY(z.real)) {
1957db96d56Sopenharmony_ci            result = fabs(z.real);
1967db96d56Sopenharmony_ci            errno = 0;
1977db96d56Sopenharmony_ci            return result;
1987db96d56Sopenharmony_ci        }
1997db96d56Sopenharmony_ci        if (Py_IS_INFINITY(z.imag)) {
2007db96d56Sopenharmony_ci            result = fabs(z.imag);
2017db96d56Sopenharmony_ci            errno = 0;
2027db96d56Sopenharmony_ci            return result;
2037db96d56Sopenharmony_ci        }
2047db96d56Sopenharmony_ci        /* either the real or imaginary part is a NaN,
2057db96d56Sopenharmony_ci           and neither is infinite. Result should be NaN. */
2067db96d56Sopenharmony_ci        return Py_NAN;
2077db96d56Sopenharmony_ci    }
2087db96d56Sopenharmony_ci    result = hypot(z.real, z.imag);
2097db96d56Sopenharmony_ci    if (!Py_IS_FINITE(result))
2107db96d56Sopenharmony_ci        errno = ERANGE;
2117db96d56Sopenharmony_ci    else
2127db96d56Sopenharmony_ci        errno = 0;
2137db96d56Sopenharmony_ci    return result;
2147db96d56Sopenharmony_ci}
2157db96d56Sopenharmony_ci
2167db96d56Sopenharmony_cistatic PyObject *
2177db96d56Sopenharmony_cicomplex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
2187db96d56Sopenharmony_ci{
2197db96d56Sopenharmony_ci    PyObject *op;
2207db96d56Sopenharmony_ci
2217db96d56Sopenharmony_ci    op = type->tp_alloc(type, 0);
2227db96d56Sopenharmony_ci    if (op != NULL)
2237db96d56Sopenharmony_ci        ((PyComplexObject *)op)->cval = cval;
2247db96d56Sopenharmony_ci    return op;
2257db96d56Sopenharmony_ci}
2267db96d56Sopenharmony_ci
2277db96d56Sopenharmony_ciPyObject *
2287db96d56Sopenharmony_ciPyComplex_FromCComplex(Py_complex cval)
2297db96d56Sopenharmony_ci{
2307db96d56Sopenharmony_ci    /* Inline PyObject_New */
2317db96d56Sopenharmony_ci    PyComplexObject *op = PyObject_Malloc(sizeof(PyComplexObject));
2327db96d56Sopenharmony_ci    if (op == NULL) {
2337db96d56Sopenharmony_ci        return PyErr_NoMemory();
2347db96d56Sopenharmony_ci    }
2357db96d56Sopenharmony_ci    _PyObject_Init((PyObject*)op, &PyComplex_Type);
2367db96d56Sopenharmony_ci    op->cval = cval;
2377db96d56Sopenharmony_ci    return (PyObject *) op;
2387db96d56Sopenharmony_ci}
2397db96d56Sopenharmony_ci
2407db96d56Sopenharmony_cistatic PyObject *
2417db96d56Sopenharmony_cicomplex_subtype_from_doubles(PyTypeObject *type, double real, double imag)
2427db96d56Sopenharmony_ci{
2437db96d56Sopenharmony_ci    Py_complex c;
2447db96d56Sopenharmony_ci    c.real = real;
2457db96d56Sopenharmony_ci    c.imag = imag;
2467db96d56Sopenharmony_ci    return complex_subtype_from_c_complex(type, c);
2477db96d56Sopenharmony_ci}
2487db96d56Sopenharmony_ci
2497db96d56Sopenharmony_ciPyObject *
2507db96d56Sopenharmony_ciPyComplex_FromDoubles(double real, double imag)
2517db96d56Sopenharmony_ci{
2527db96d56Sopenharmony_ci    Py_complex c;
2537db96d56Sopenharmony_ci    c.real = real;
2547db96d56Sopenharmony_ci    c.imag = imag;
2557db96d56Sopenharmony_ci    return PyComplex_FromCComplex(c);
2567db96d56Sopenharmony_ci}
2577db96d56Sopenharmony_ci
2587db96d56Sopenharmony_cidouble
2597db96d56Sopenharmony_ciPyComplex_RealAsDouble(PyObject *op)
2607db96d56Sopenharmony_ci{
2617db96d56Sopenharmony_ci    if (PyComplex_Check(op)) {
2627db96d56Sopenharmony_ci        return ((PyComplexObject *)op)->cval.real;
2637db96d56Sopenharmony_ci    }
2647db96d56Sopenharmony_ci    else {
2657db96d56Sopenharmony_ci        return PyFloat_AsDouble(op);
2667db96d56Sopenharmony_ci    }
2677db96d56Sopenharmony_ci}
2687db96d56Sopenharmony_ci
2697db96d56Sopenharmony_cidouble
2707db96d56Sopenharmony_ciPyComplex_ImagAsDouble(PyObject *op)
2717db96d56Sopenharmony_ci{
2727db96d56Sopenharmony_ci    if (PyComplex_Check(op)) {
2737db96d56Sopenharmony_ci        return ((PyComplexObject *)op)->cval.imag;
2747db96d56Sopenharmony_ci    }
2757db96d56Sopenharmony_ci    else {
2767db96d56Sopenharmony_ci        return 0.0;
2777db96d56Sopenharmony_ci    }
2787db96d56Sopenharmony_ci}
2797db96d56Sopenharmony_ci
2807db96d56Sopenharmony_cistatic PyObject *
2817db96d56Sopenharmony_citry_complex_special_method(PyObject *op)
2827db96d56Sopenharmony_ci{
2837db96d56Sopenharmony_ci    PyObject *f;
2847db96d56Sopenharmony_ci
2857db96d56Sopenharmony_ci    f = _PyObject_LookupSpecial(op, &_Py_ID(__complex__));
2867db96d56Sopenharmony_ci    if (f) {
2877db96d56Sopenharmony_ci        PyObject *res = _PyObject_CallNoArgs(f);
2887db96d56Sopenharmony_ci        Py_DECREF(f);
2897db96d56Sopenharmony_ci        if (!res || PyComplex_CheckExact(res)) {
2907db96d56Sopenharmony_ci            return res;
2917db96d56Sopenharmony_ci        }
2927db96d56Sopenharmony_ci        if (!PyComplex_Check(res)) {
2937db96d56Sopenharmony_ci            PyErr_Format(PyExc_TypeError,
2947db96d56Sopenharmony_ci                "__complex__ returned non-complex (type %.200s)",
2957db96d56Sopenharmony_ci                Py_TYPE(res)->tp_name);
2967db96d56Sopenharmony_ci            Py_DECREF(res);
2977db96d56Sopenharmony_ci            return NULL;
2987db96d56Sopenharmony_ci        }
2997db96d56Sopenharmony_ci        /* Issue #29894: warn if 'res' not of exact type complex. */
3007db96d56Sopenharmony_ci        if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
3017db96d56Sopenharmony_ci                "__complex__ returned non-complex (type %.200s).  "
3027db96d56Sopenharmony_ci                "The ability to return an instance of a strict subclass of complex "
3037db96d56Sopenharmony_ci                "is deprecated, and may be removed in a future version of Python.",
3047db96d56Sopenharmony_ci                Py_TYPE(res)->tp_name)) {
3057db96d56Sopenharmony_ci            Py_DECREF(res);
3067db96d56Sopenharmony_ci            return NULL;
3077db96d56Sopenharmony_ci        }
3087db96d56Sopenharmony_ci        return res;
3097db96d56Sopenharmony_ci    }
3107db96d56Sopenharmony_ci    return NULL;
3117db96d56Sopenharmony_ci}
3127db96d56Sopenharmony_ci
3137db96d56Sopenharmony_ciPy_complex
3147db96d56Sopenharmony_ciPyComplex_AsCComplex(PyObject *op)
3157db96d56Sopenharmony_ci{
3167db96d56Sopenharmony_ci    Py_complex cv;
3177db96d56Sopenharmony_ci    PyObject *newop = NULL;
3187db96d56Sopenharmony_ci
3197db96d56Sopenharmony_ci    assert(op);
3207db96d56Sopenharmony_ci    /* If op is already of type PyComplex_Type, return its value */
3217db96d56Sopenharmony_ci    if (PyComplex_Check(op)) {
3227db96d56Sopenharmony_ci        return ((PyComplexObject *)op)->cval;
3237db96d56Sopenharmony_ci    }
3247db96d56Sopenharmony_ci    /* If not, use op's __complex__  method, if it exists */
3257db96d56Sopenharmony_ci
3267db96d56Sopenharmony_ci    /* return -1 on failure */
3277db96d56Sopenharmony_ci    cv.real = -1.;
3287db96d56Sopenharmony_ci    cv.imag = 0.;
3297db96d56Sopenharmony_ci
3307db96d56Sopenharmony_ci    newop = try_complex_special_method(op);
3317db96d56Sopenharmony_ci
3327db96d56Sopenharmony_ci    if (newop) {
3337db96d56Sopenharmony_ci        cv = ((PyComplexObject *)newop)->cval;
3347db96d56Sopenharmony_ci        Py_DECREF(newop);
3357db96d56Sopenharmony_ci        return cv;
3367db96d56Sopenharmony_ci    }
3377db96d56Sopenharmony_ci    else if (PyErr_Occurred()) {
3387db96d56Sopenharmony_ci        return cv;
3397db96d56Sopenharmony_ci    }
3407db96d56Sopenharmony_ci    /* If neither of the above works, interpret op as a float giving the
3417db96d56Sopenharmony_ci       real part of the result, and fill in the imaginary part as 0. */
3427db96d56Sopenharmony_ci    else {
3437db96d56Sopenharmony_ci        /* PyFloat_AsDouble will return -1 on failure */
3447db96d56Sopenharmony_ci        cv.real = PyFloat_AsDouble(op);
3457db96d56Sopenharmony_ci        return cv;
3467db96d56Sopenharmony_ci    }
3477db96d56Sopenharmony_ci}
3487db96d56Sopenharmony_ci
3497db96d56Sopenharmony_cistatic PyObject *
3507db96d56Sopenharmony_cicomplex_repr(PyComplexObject *v)
3517db96d56Sopenharmony_ci{
3527db96d56Sopenharmony_ci    int precision = 0;
3537db96d56Sopenharmony_ci    char format_code = 'r';
3547db96d56Sopenharmony_ci    PyObject *result = NULL;
3557db96d56Sopenharmony_ci
3567db96d56Sopenharmony_ci    /* If these are non-NULL, they'll need to be freed. */
3577db96d56Sopenharmony_ci    char *pre = NULL;
3587db96d56Sopenharmony_ci    char *im = NULL;
3597db96d56Sopenharmony_ci
3607db96d56Sopenharmony_ci    /* These do not need to be freed. re is either an alias
3617db96d56Sopenharmony_ci       for pre or a pointer to a constant.  lead and tail
3627db96d56Sopenharmony_ci       are pointers to constants. */
3637db96d56Sopenharmony_ci    const char *re = NULL;
3647db96d56Sopenharmony_ci    const char *lead = "";
3657db96d56Sopenharmony_ci    const char *tail = "";
3667db96d56Sopenharmony_ci
3677db96d56Sopenharmony_ci    if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) {
3687db96d56Sopenharmony_ci        /* Real part is +0: just output the imaginary part and do not
3697db96d56Sopenharmony_ci           include parens. */
3707db96d56Sopenharmony_ci        re = "";
3717db96d56Sopenharmony_ci        im = PyOS_double_to_string(v->cval.imag, format_code,
3727db96d56Sopenharmony_ci                                   precision, 0, NULL);
3737db96d56Sopenharmony_ci        if (!im) {
3747db96d56Sopenharmony_ci            PyErr_NoMemory();
3757db96d56Sopenharmony_ci            goto done;
3767db96d56Sopenharmony_ci        }
3777db96d56Sopenharmony_ci    } else {
3787db96d56Sopenharmony_ci        /* Format imaginary part with sign, real part without. Include
3797db96d56Sopenharmony_ci           parens in the result. */
3807db96d56Sopenharmony_ci        pre = PyOS_double_to_string(v->cval.real, format_code,
3817db96d56Sopenharmony_ci                                    precision, 0, NULL);
3827db96d56Sopenharmony_ci        if (!pre) {
3837db96d56Sopenharmony_ci            PyErr_NoMemory();
3847db96d56Sopenharmony_ci            goto done;
3857db96d56Sopenharmony_ci        }
3867db96d56Sopenharmony_ci        re = pre;
3877db96d56Sopenharmony_ci
3887db96d56Sopenharmony_ci        im = PyOS_double_to_string(v->cval.imag, format_code,
3897db96d56Sopenharmony_ci                                   precision, Py_DTSF_SIGN, NULL);
3907db96d56Sopenharmony_ci        if (!im) {
3917db96d56Sopenharmony_ci            PyErr_NoMemory();
3927db96d56Sopenharmony_ci            goto done;
3937db96d56Sopenharmony_ci        }
3947db96d56Sopenharmony_ci        lead = "(";
3957db96d56Sopenharmony_ci        tail = ")";
3967db96d56Sopenharmony_ci    }
3977db96d56Sopenharmony_ci    result = PyUnicode_FromFormat("%s%s%sj%s", lead, re, im, tail);
3987db96d56Sopenharmony_ci  done:
3997db96d56Sopenharmony_ci    PyMem_Free(im);
4007db96d56Sopenharmony_ci    PyMem_Free(pre);
4017db96d56Sopenharmony_ci
4027db96d56Sopenharmony_ci    return result;
4037db96d56Sopenharmony_ci}
4047db96d56Sopenharmony_ci
4057db96d56Sopenharmony_cistatic Py_hash_t
4067db96d56Sopenharmony_cicomplex_hash(PyComplexObject *v)
4077db96d56Sopenharmony_ci{
4087db96d56Sopenharmony_ci    Py_uhash_t hashreal, hashimag, combined;
4097db96d56Sopenharmony_ci    hashreal = (Py_uhash_t)_Py_HashDouble((PyObject *) v, v->cval.real);
4107db96d56Sopenharmony_ci    if (hashreal == (Py_uhash_t)-1)
4117db96d56Sopenharmony_ci        return -1;
4127db96d56Sopenharmony_ci    hashimag = (Py_uhash_t)_Py_HashDouble((PyObject *)v, v->cval.imag);
4137db96d56Sopenharmony_ci    if (hashimag == (Py_uhash_t)-1)
4147db96d56Sopenharmony_ci        return -1;
4157db96d56Sopenharmony_ci    /* Note:  if the imaginary part is 0, hashimag is 0 now,
4167db96d56Sopenharmony_ci     * so the following returns hashreal unchanged.  This is
4177db96d56Sopenharmony_ci     * important because numbers of different types that
4187db96d56Sopenharmony_ci     * compare equal must have the same hash value, so that
4197db96d56Sopenharmony_ci     * hash(x + 0*j) must equal hash(x).
4207db96d56Sopenharmony_ci     */
4217db96d56Sopenharmony_ci    combined = hashreal + _PyHASH_IMAG * hashimag;
4227db96d56Sopenharmony_ci    if (combined == (Py_uhash_t)-1)
4237db96d56Sopenharmony_ci        combined = (Py_uhash_t)-2;
4247db96d56Sopenharmony_ci    return (Py_hash_t)combined;
4257db96d56Sopenharmony_ci}
4267db96d56Sopenharmony_ci
4277db96d56Sopenharmony_ci/* This macro may return! */
4287db96d56Sopenharmony_ci#define TO_COMPLEX(obj, c) \
4297db96d56Sopenharmony_ci    if (PyComplex_Check(obj)) \
4307db96d56Sopenharmony_ci        c = ((PyComplexObject *)(obj))->cval; \
4317db96d56Sopenharmony_ci    else if (to_complex(&(obj), &(c)) < 0) \
4327db96d56Sopenharmony_ci        return (obj)
4337db96d56Sopenharmony_ci
4347db96d56Sopenharmony_cistatic int
4357db96d56Sopenharmony_cito_complex(PyObject **pobj, Py_complex *pc)
4367db96d56Sopenharmony_ci{
4377db96d56Sopenharmony_ci    PyObject *obj = *pobj;
4387db96d56Sopenharmony_ci
4397db96d56Sopenharmony_ci    pc->real = pc->imag = 0.0;
4407db96d56Sopenharmony_ci    if (PyLong_Check(obj)) {
4417db96d56Sopenharmony_ci        pc->real = PyLong_AsDouble(obj);
4427db96d56Sopenharmony_ci        if (pc->real == -1.0 && PyErr_Occurred()) {
4437db96d56Sopenharmony_ci            *pobj = NULL;
4447db96d56Sopenharmony_ci            return -1;
4457db96d56Sopenharmony_ci        }
4467db96d56Sopenharmony_ci        return 0;
4477db96d56Sopenharmony_ci    }
4487db96d56Sopenharmony_ci    if (PyFloat_Check(obj)) {
4497db96d56Sopenharmony_ci        pc->real = PyFloat_AsDouble(obj);
4507db96d56Sopenharmony_ci        return 0;
4517db96d56Sopenharmony_ci    }
4527db96d56Sopenharmony_ci    Py_INCREF(Py_NotImplemented);
4537db96d56Sopenharmony_ci    *pobj = Py_NotImplemented;
4547db96d56Sopenharmony_ci    return -1;
4557db96d56Sopenharmony_ci}
4567db96d56Sopenharmony_ci
4577db96d56Sopenharmony_ci
4587db96d56Sopenharmony_cistatic PyObject *
4597db96d56Sopenharmony_cicomplex_add(PyObject *v, PyObject *w)
4607db96d56Sopenharmony_ci{
4617db96d56Sopenharmony_ci    Py_complex result;
4627db96d56Sopenharmony_ci    Py_complex a, b;
4637db96d56Sopenharmony_ci    TO_COMPLEX(v, a);
4647db96d56Sopenharmony_ci    TO_COMPLEX(w, b);
4657db96d56Sopenharmony_ci    result = _Py_c_sum(a, b);
4667db96d56Sopenharmony_ci    return PyComplex_FromCComplex(result);
4677db96d56Sopenharmony_ci}
4687db96d56Sopenharmony_ci
4697db96d56Sopenharmony_cistatic PyObject *
4707db96d56Sopenharmony_cicomplex_sub(PyObject *v, PyObject *w)
4717db96d56Sopenharmony_ci{
4727db96d56Sopenharmony_ci    Py_complex result;
4737db96d56Sopenharmony_ci    Py_complex a, b;
4747db96d56Sopenharmony_ci    TO_COMPLEX(v, a);
4757db96d56Sopenharmony_ci    TO_COMPLEX(w, b);
4767db96d56Sopenharmony_ci    result = _Py_c_diff(a, b);
4777db96d56Sopenharmony_ci    return PyComplex_FromCComplex(result);
4787db96d56Sopenharmony_ci}
4797db96d56Sopenharmony_ci
4807db96d56Sopenharmony_cistatic PyObject *
4817db96d56Sopenharmony_cicomplex_mul(PyObject *v, PyObject *w)
4827db96d56Sopenharmony_ci{
4837db96d56Sopenharmony_ci    Py_complex result;
4847db96d56Sopenharmony_ci    Py_complex a, b;
4857db96d56Sopenharmony_ci    TO_COMPLEX(v, a);
4867db96d56Sopenharmony_ci    TO_COMPLEX(w, b);
4877db96d56Sopenharmony_ci    result = _Py_c_prod(a, b);
4887db96d56Sopenharmony_ci    return PyComplex_FromCComplex(result);
4897db96d56Sopenharmony_ci}
4907db96d56Sopenharmony_ci
4917db96d56Sopenharmony_cistatic PyObject *
4927db96d56Sopenharmony_cicomplex_div(PyObject *v, PyObject *w)
4937db96d56Sopenharmony_ci{
4947db96d56Sopenharmony_ci    Py_complex quot;
4957db96d56Sopenharmony_ci    Py_complex a, b;
4967db96d56Sopenharmony_ci    TO_COMPLEX(v, a);
4977db96d56Sopenharmony_ci    TO_COMPLEX(w, b);
4987db96d56Sopenharmony_ci    errno = 0;
4997db96d56Sopenharmony_ci    quot = _Py_c_quot(a, b);
5007db96d56Sopenharmony_ci    if (errno == EDOM) {
5017db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ZeroDivisionError, "complex division by zero");
5027db96d56Sopenharmony_ci        return NULL;
5037db96d56Sopenharmony_ci    }
5047db96d56Sopenharmony_ci    return PyComplex_FromCComplex(quot);
5057db96d56Sopenharmony_ci}
5067db96d56Sopenharmony_ci
5077db96d56Sopenharmony_cistatic PyObject *
5087db96d56Sopenharmony_cicomplex_pow(PyObject *v, PyObject *w, PyObject *z)
5097db96d56Sopenharmony_ci{
5107db96d56Sopenharmony_ci    Py_complex p;
5117db96d56Sopenharmony_ci    Py_complex a, b;
5127db96d56Sopenharmony_ci    TO_COMPLEX(v, a);
5137db96d56Sopenharmony_ci    TO_COMPLEX(w, b);
5147db96d56Sopenharmony_ci
5157db96d56Sopenharmony_ci    if (z != Py_None) {
5167db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "complex modulo");
5177db96d56Sopenharmony_ci        return NULL;
5187db96d56Sopenharmony_ci    }
5197db96d56Sopenharmony_ci    errno = 0;
5207db96d56Sopenharmony_ci    // Check whether the exponent has a small integer value, and if so use
5217db96d56Sopenharmony_ci    // a faster and more accurate algorithm.
5227db96d56Sopenharmony_ci    if (b.imag == 0.0 && b.real == floor(b.real) && fabs(b.real) <= 100.0) {
5237db96d56Sopenharmony_ci        p = c_powi(a, (long)b.real);
5247db96d56Sopenharmony_ci    }
5257db96d56Sopenharmony_ci    else {
5267db96d56Sopenharmony_ci        p = _Py_c_pow(a, b);
5277db96d56Sopenharmony_ci    }
5287db96d56Sopenharmony_ci
5297db96d56Sopenharmony_ci    _Py_ADJUST_ERANGE2(p.real, p.imag);
5307db96d56Sopenharmony_ci    if (errno == EDOM) {
5317db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ZeroDivisionError,
5327db96d56Sopenharmony_ci                        "0.0 to a negative or complex power");
5337db96d56Sopenharmony_ci        return NULL;
5347db96d56Sopenharmony_ci    }
5357db96d56Sopenharmony_ci    else if (errno == ERANGE) {
5367db96d56Sopenharmony_ci        PyErr_SetString(PyExc_OverflowError,
5377db96d56Sopenharmony_ci                        "complex exponentiation");
5387db96d56Sopenharmony_ci        return NULL;
5397db96d56Sopenharmony_ci    }
5407db96d56Sopenharmony_ci    return PyComplex_FromCComplex(p);
5417db96d56Sopenharmony_ci}
5427db96d56Sopenharmony_ci
5437db96d56Sopenharmony_cistatic PyObject *
5447db96d56Sopenharmony_cicomplex_neg(PyComplexObject *v)
5457db96d56Sopenharmony_ci{
5467db96d56Sopenharmony_ci    Py_complex neg;
5477db96d56Sopenharmony_ci    neg.real = -v->cval.real;
5487db96d56Sopenharmony_ci    neg.imag = -v->cval.imag;
5497db96d56Sopenharmony_ci    return PyComplex_FromCComplex(neg);
5507db96d56Sopenharmony_ci}
5517db96d56Sopenharmony_ci
5527db96d56Sopenharmony_cistatic PyObject *
5537db96d56Sopenharmony_cicomplex_pos(PyComplexObject *v)
5547db96d56Sopenharmony_ci{
5557db96d56Sopenharmony_ci    if (PyComplex_CheckExact(v)) {
5567db96d56Sopenharmony_ci        Py_INCREF(v);
5577db96d56Sopenharmony_ci        return (PyObject *)v;
5587db96d56Sopenharmony_ci    }
5597db96d56Sopenharmony_ci    else
5607db96d56Sopenharmony_ci        return PyComplex_FromCComplex(v->cval);
5617db96d56Sopenharmony_ci}
5627db96d56Sopenharmony_ci
5637db96d56Sopenharmony_cistatic PyObject *
5647db96d56Sopenharmony_cicomplex_abs(PyComplexObject *v)
5657db96d56Sopenharmony_ci{
5667db96d56Sopenharmony_ci    double result;
5677db96d56Sopenharmony_ci
5687db96d56Sopenharmony_ci    result = _Py_c_abs(v->cval);
5697db96d56Sopenharmony_ci
5707db96d56Sopenharmony_ci    if (errno == ERANGE) {
5717db96d56Sopenharmony_ci        PyErr_SetString(PyExc_OverflowError,
5727db96d56Sopenharmony_ci                        "absolute value too large");
5737db96d56Sopenharmony_ci        return NULL;
5747db96d56Sopenharmony_ci    }
5757db96d56Sopenharmony_ci    return PyFloat_FromDouble(result);
5767db96d56Sopenharmony_ci}
5777db96d56Sopenharmony_ci
5787db96d56Sopenharmony_cistatic int
5797db96d56Sopenharmony_cicomplex_bool(PyComplexObject *v)
5807db96d56Sopenharmony_ci{
5817db96d56Sopenharmony_ci    return v->cval.real != 0.0 || v->cval.imag != 0.0;
5827db96d56Sopenharmony_ci}
5837db96d56Sopenharmony_ci
5847db96d56Sopenharmony_cistatic PyObject *
5857db96d56Sopenharmony_cicomplex_richcompare(PyObject *v, PyObject *w, int op)
5867db96d56Sopenharmony_ci{
5877db96d56Sopenharmony_ci    PyObject *res;
5887db96d56Sopenharmony_ci    Py_complex i;
5897db96d56Sopenharmony_ci    int equal;
5907db96d56Sopenharmony_ci
5917db96d56Sopenharmony_ci    if (op != Py_EQ && op != Py_NE) {
5927db96d56Sopenharmony_ci        goto Unimplemented;
5937db96d56Sopenharmony_ci    }
5947db96d56Sopenharmony_ci
5957db96d56Sopenharmony_ci    assert(PyComplex_Check(v));
5967db96d56Sopenharmony_ci    TO_COMPLEX(v, i);
5977db96d56Sopenharmony_ci
5987db96d56Sopenharmony_ci    if (PyLong_Check(w)) {
5997db96d56Sopenharmony_ci        /* Check for 0.0 imaginary part first to avoid the rich
6007db96d56Sopenharmony_ci         * comparison when possible.
6017db96d56Sopenharmony_ci         */
6027db96d56Sopenharmony_ci        if (i.imag == 0.0) {
6037db96d56Sopenharmony_ci            PyObject *j, *sub_res;
6047db96d56Sopenharmony_ci            j = PyFloat_FromDouble(i.real);
6057db96d56Sopenharmony_ci            if (j == NULL)
6067db96d56Sopenharmony_ci                return NULL;
6077db96d56Sopenharmony_ci
6087db96d56Sopenharmony_ci            sub_res = PyObject_RichCompare(j, w, op);
6097db96d56Sopenharmony_ci            Py_DECREF(j);
6107db96d56Sopenharmony_ci            return sub_res;
6117db96d56Sopenharmony_ci        }
6127db96d56Sopenharmony_ci        else {
6137db96d56Sopenharmony_ci            equal = 0;
6147db96d56Sopenharmony_ci        }
6157db96d56Sopenharmony_ci    }
6167db96d56Sopenharmony_ci    else if (PyFloat_Check(w)) {
6177db96d56Sopenharmony_ci        equal = (i.real == PyFloat_AsDouble(w) && i.imag == 0.0);
6187db96d56Sopenharmony_ci    }
6197db96d56Sopenharmony_ci    else if (PyComplex_Check(w)) {
6207db96d56Sopenharmony_ci        Py_complex j;
6217db96d56Sopenharmony_ci
6227db96d56Sopenharmony_ci        TO_COMPLEX(w, j);
6237db96d56Sopenharmony_ci        equal = (i.real == j.real && i.imag == j.imag);
6247db96d56Sopenharmony_ci    }
6257db96d56Sopenharmony_ci    else {
6267db96d56Sopenharmony_ci        goto Unimplemented;
6277db96d56Sopenharmony_ci    }
6287db96d56Sopenharmony_ci
6297db96d56Sopenharmony_ci    if (equal == (op == Py_EQ))
6307db96d56Sopenharmony_ci         res = Py_True;
6317db96d56Sopenharmony_ci    else
6327db96d56Sopenharmony_ci         res = Py_False;
6337db96d56Sopenharmony_ci
6347db96d56Sopenharmony_ci    Py_INCREF(res);
6357db96d56Sopenharmony_ci    return res;
6367db96d56Sopenharmony_ci
6377db96d56Sopenharmony_ciUnimplemented:
6387db96d56Sopenharmony_ci    Py_RETURN_NOTIMPLEMENTED;
6397db96d56Sopenharmony_ci}
6407db96d56Sopenharmony_ci
6417db96d56Sopenharmony_ci/*[clinic input]
6427db96d56Sopenharmony_cicomplex.conjugate
6437db96d56Sopenharmony_ci
6447db96d56Sopenharmony_ciReturn the complex conjugate of its argument. (3-4j).conjugate() == 3+4j.
6457db96d56Sopenharmony_ci[clinic start generated code]*/
6467db96d56Sopenharmony_ci
6477db96d56Sopenharmony_cistatic PyObject *
6487db96d56Sopenharmony_cicomplex_conjugate_impl(PyComplexObject *self)
6497db96d56Sopenharmony_ci/*[clinic end generated code: output=5059ef162edfc68e input=5fea33e9747ec2c4]*/
6507db96d56Sopenharmony_ci{
6517db96d56Sopenharmony_ci    Py_complex c = self->cval;
6527db96d56Sopenharmony_ci    c.imag = -c.imag;
6537db96d56Sopenharmony_ci    return PyComplex_FromCComplex(c);
6547db96d56Sopenharmony_ci}
6557db96d56Sopenharmony_ci
6567db96d56Sopenharmony_ci/*[clinic input]
6577db96d56Sopenharmony_cicomplex.__getnewargs__
6587db96d56Sopenharmony_ci
6597db96d56Sopenharmony_ci[clinic start generated code]*/
6607db96d56Sopenharmony_ci
6617db96d56Sopenharmony_cistatic PyObject *
6627db96d56Sopenharmony_cicomplex___getnewargs___impl(PyComplexObject *self)
6637db96d56Sopenharmony_ci/*[clinic end generated code: output=689b8206e8728934 input=539543e0a50533d7]*/
6647db96d56Sopenharmony_ci{
6657db96d56Sopenharmony_ci    Py_complex c = self->cval;
6667db96d56Sopenharmony_ci    return Py_BuildValue("(dd)", c.real, c.imag);
6677db96d56Sopenharmony_ci}
6687db96d56Sopenharmony_ci
6697db96d56Sopenharmony_ci
6707db96d56Sopenharmony_ci/*[clinic input]
6717db96d56Sopenharmony_cicomplex.__format__
6727db96d56Sopenharmony_ci
6737db96d56Sopenharmony_ci    format_spec: unicode
6747db96d56Sopenharmony_ci    /
6757db96d56Sopenharmony_ci
6767db96d56Sopenharmony_ciConvert to a string according to format_spec.
6777db96d56Sopenharmony_ci[clinic start generated code]*/
6787db96d56Sopenharmony_ci
6797db96d56Sopenharmony_cistatic PyObject *
6807db96d56Sopenharmony_cicomplex___format___impl(PyComplexObject *self, PyObject *format_spec)
6817db96d56Sopenharmony_ci/*[clinic end generated code: output=bfcb60df24cafea0 input=014ef5488acbe1d5]*/
6827db96d56Sopenharmony_ci{
6837db96d56Sopenharmony_ci    _PyUnicodeWriter writer;
6847db96d56Sopenharmony_ci    int ret;
6857db96d56Sopenharmony_ci    _PyUnicodeWriter_Init(&writer);
6867db96d56Sopenharmony_ci    ret = _PyComplex_FormatAdvancedWriter(
6877db96d56Sopenharmony_ci        &writer,
6887db96d56Sopenharmony_ci        (PyObject *)self,
6897db96d56Sopenharmony_ci        format_spec, 0, PyUnicode_GET_LENGTH(format_spec));
6907db96d56Sopenharmony_ci    if (ret == -1) {
6917db96d56Sopenharmony_ci        _PyUnicodeWriter_Dealloc(&writer);
6927db96d56Sopenharmony_ci        return NULL;
6937db96d56Sopenharmony_ci    }
6947db96d56Sopenharmony_ci    return _PyUnicodeWriter_Finish(&writer);
6957db96d56Sopenharmony_ci}
6967db96d56Sopenharmony_ci
6977db96d56Sopenharmony_ci/*[clinic input]
6987db96d56Sopenharmony_cicomplex.__complex__
6997db96d56Sopenharmony_ci
7007db96d56Sopenharmony_ciConvert this value to exact type complex.
7017db96d56Sopenharmony_ci[clinic start generated code]*/
7027db96d56Sopenharmony_ci
7037db96d56Sopenharmony_cistatic PyObject *
7047db96d56Sopenharmony_cicomplex___complex___impl(PyComplexObject *self)
7057db96d56Sopenharmony_ci/*[clinic end generated code: output=e6b35ba3d275dc9c input=3589ada9d27db854]*/
7067db96d56Sopenharmony_ci{
7077db96d56Sopenharmony_ci    if (PyComplex_CheckExact(self)) {
7087db96d56Sopenharmony_ci        Py_INCREF(self);
7097db96d56Sopenharmony_ci        return (PyObject *)self;
7107db96d56Sopenharmony_ci    }
7117db96d56Sopenharmony_ci    else {
7127db96d56Sopenharmony_ci        return PyComplex_FromCComplex(self->cval);
7137db96d56Sopenharmony_ci    }
7147db96d56Sopenharmony_ci}
7157db96d56Sopenharmony_ci
7167db96d56Sopenharmony_ci
7177db96d56Sopenharmony_cistatic PyMethodDef complex_methods[] = {
7187db96d56Sopenharmony_ci    COMPLEX_CONJUGATE_METHODDEF
7197db96d56Sopenharmony_ci    COMPLEX___COMPLEX___METHODDEF
7207db96d56Sopenharmony_ci    COMPLEX___GETNEWARGS___METHODDEF
7217db96d56Sopenharmony_ci    COMPLEX___FORMAT___METHODDEF
7227db96d56Sopenharmony_ci    {NULL,              NULL}           /* sentinel */
7237db96d56Sopenharmony_ci};
7247db96d56Sopenharmony_ci
7257db96d56Sopenharmony_cistatic PyMemberDef complex_members[] = {
7267db96d56Sopenharmony_ci    {"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), READONLY,
7277db96d56Sopenharmony_ci     "the real part of a complex number"},
7287db96d56Sopenharmony_ci    {"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), READONLY,
7297db96d56Sopenharmony_ci     "the imaginary part of a complex number"},
7307db96d56Sopenharmony_ci    {0},
7317db96d56Sopenharmony_ci};
7327db96d56Sopenharmony_ci
7337db96d56Sopenharmony_cistatic PyObject *
7347db96d56Sopenharmony_cicomplex_from_string_inner(const char *s, Py_ssize_t len, void *type)
7357db96d56Sopenharmony_ci{
7367db96d56Sopenharmony_ci    double x=0.0, y=0.0, z;
7377db96d56Sopenharmony_ci    int got_bracket=0;
7387db96d56Sopenharmony_ci    const char *start;
7397db96d56Sopenharmony_ci    char *end;
7407db96d56Sopenharmony_ci
7417db96d56Sopenharmony_ci    /* position on first nonblank */
7427db96d56Sopenharmony_ci    start = s;
7437db96d56Sopenharmony_ci    while (Py_ISSPACE(*s))
7447db96d56Sopenharmony_ci        s++;
7457db96d56Sopenharmony_ci    if (*s == '(') {
7467db96d56Sopenharmony_ci        /* Skip over possible bracket from repr(). */
7477db96d56Sopenharmony_ci        got_bracket = 1;
7487db96d56Sopenharmony_ci        s++;
7497db96d56Sopenharmony_ci        while (Py_ISSPACE(*s))
7507db96d56Sopenharmony_ci            s++;
7517db96d56Sopenharmony_ci    }
7527db96d56Sopenharmony_ci
7537db96d56Sopenharmony_ci    /* a valid complex string usually takes one of the three forms:
7547db96d56Sopenharmony_ci
7557db96d56Sopenharmony_ci         <float>                  - real part only
7567db96d56Sopenharmony_ci         <float>j                 - imaginary part only
7577db96d56Sopenharmony_ci         <float><signed-float>j   - real and imaginary parts
7587db96d56Sopenharmony_ci
7597db96d56Sopenharmony_ci       where <float> represents any numeric string that's accepted by the
7607db96d56Sopenharmony_ci       float constructor (including 'nan', 'inf', 'infinity', etc.), and
7617db96d56Sopenharmony_ci       <signed-float> is any string of the form <float> whose first
7627db96d56Sopenharmony_ci       character is '+' or '-'.
7637db96d56Sopenharmony_ci
7647db96d56Sopenharmony_ci       For backwards compatibility, the extra forms
7657db96d56Sopenharmony_ci
7667db96d56Sopenharmony_ci         <float><sign>j
7677db96d56Sopenharmony_ci         <sign>j
7687db96d56Sopenharmony_ci         j
7697db96d56Sopenharmony_ci
7707db96d56Sopenharmony_ci       are also accepted, though support for these forms may be removed from
7717db96d56Sopenharmony_ci       a future version of Python.
7727db96d56Sopenharmony_ci    */
7737db96d56Sopenharmony_ci
7747db96d56Sopenharmony_ci    /* first look for forms starting with <float> */
7757db96d56Sopenharmony_ci    z = PyOS_string_to_double(s, &end, NULL);
7767db96d56Sopenharmony_ci    if (z == -1.0 && PyErr_Occurred()) {
7777db96d56Sopenharmony_ci        if (PyErr_ExceptionMatches(PyExc_ValueError))
7787db96d56Sopenharmony_ci            PyErr_Clear();
7797db96d56Sopenharmony_ci        else
7807db96d56Sopenharmony_ci            return NULL;
7817db96d56Sopenharmony_ci    }
7827db96d56Sopenharmony_ci    if (end != s) {
7837db96d56Sopenharmony_ci        /* all 4 forms starting with <float> land here */
7847db96d56Sopenharmony_ci        s = end;
7857db96d56Sopenharmony_ci        if (*s == '+' || *s == '-') {
7867db96d56Sopenharmony_ci            /* <float><signed-float>j | <float><sign>j */
7877db96d56Sopenharmony_ci            x = z;
7887db96d56Sopenharmony_ci            y = PyOS_string_to_double(s, &end, NULL);
7897db96d56Sopenharmony_ci            if (y == -1.0 && PyErr_Occurred()) {
7907db96d56Sopenharmony_ci                if (PyErr_ExceptionMatches(PyExc_ValueError))
7917db96d56Sopenharmony_ci                    PyErr_Clear();
7927db96d56Sopenharmony_ci                else
7937db96d56Sopenharmony_ci                    return NULL;
7947db96d56Sopenharmony_ci            }
7957db96d56Sopenharmony_ci            if (end != s)
7967db96d56Sopenharmony_ci                /* <float><signed-float>j */
7977db96d56Sopenharmony_ci                s = end;
7987db96d56Sopenharmony_ci            else {
7997db96d56Sopenharmony_ci                /* <float><sign>j */
8007db96d56Sopenharmony_ci                y = *s == '+' ? 1.0 : -1.0;
8017db96d56Sopenharmony_ci                s++;
8027db96d56Sopenharmony_ci            }
8037db96d56Sopenharmony_ci            if (!(*s == 'j' || *s == 'J'))
8047db96d56Sopenharmony_ci                goto parse_error;
8057db96d56Sopenharmony_ci            s++;
8067db96d56Sopenharmony_ci        }
8077db96d56Sopenharmony_ci        else if (*s == 'j' || *s == 'J') {
8087db96d56Sopenharmony_ci            /* <float>j */
8097db96d56Sopenharmony_ci            s++;
8107db96d56Sopenharmony_ci            y = z;
8117db96d56Sopenharmony_ci        }
8127db96d56Sopenharmony_ci        else
8137db96d56Sopenharmony_ci            /* <float> */
8147db96d56Sopenharmony_ci            x = z;
8157db96d56Sopenharmony_ci    }
8167db96d56Sopenharmony_ci    else {
8177db96d56Sopenharmony_ci        /* not starting with <float>; must be <sign>j or j */
8187db96d56Sopenharmony_ci        if (*s == '+' || *s == '-') {
8197db96d56Sopenharmony_ci            /* <sign>j */
8207db96d56Sopenharmony_ci            y = *s == '+' ? 1.0 : -1.0;
8217db96d56Sopenharmony_ci            s++;
8227db96d56Sopenharmony_ci        }
8237db96d56Sopenharmony_ci        else
8247db96d56Sopenharmony_ci            /* j */
8257db96d56Sopenharmony_ci            y = 1.0;
8267db96d56Sopenharmony_ci        if (!(*s == 'j' || *s == 'J'))
8277db96d56Sopenharmony_ci            goto parse_error;
8287db96d56Sopenharmony_ci        s++;
8297db96d56Sopenharmony_ci    }
8307db96d56Sopenharmony_ci
8317db96d56Sopenharmony_ci    /* trailing whitespace and closing bracket */
8327db96d56Sopenharmony_ci    while (Py_ISSPACE(*s))
8337db96d56Sopenharmony_ci        s++;
8347db96d56Sopenharmony_ci    if (got_bracket) {
8357db96d56Sopenharmony_ci        /* if there was an opening parenthesis, then the corresponding
8367db96d56Sopenharmony_ci           closing parenthesis should be right here */
8377db96d56Sopenharmony_ci        if (*s != ')')
8387db96d56Sopenharmony_ci            goto parse_error;
8397db96d56Sopenharmony_ci        s++;
8407db96d56Sopenharmony_ci        while (Py_ISSPACE(*s))
8417db96d56Sopenharmony_ci            s++;
8427db96d56Sopenharmony_ci    }
8437db96d56Sopenharmony_ci
8447db96d56Sopenharmony_ci    /* we should now be at the end of the string */
8457db96d56Sopenharmony_ci    if (s-start != len)
8467db96d56Sopenharmony_ci        goto parse_error;
8477db96d56Sopenharmony_ci
8487db96d56Sopenharmony_ci    return complex_subtype_from_doubles(_PyType_CAST(type), x, y);
8497db96d56Sopenharmony_ci
8507db96d56Sopenharmony_ci  parse_error:
8517db96d56Sopenharmony_ci    PyErr_SetString(PyExc_ValueError,
8527db96d56Sopenharmony_ci                    "complex() arg is a malformed string");
8537db96d56Sopenharmony_ci    return NULL;
8547db96d56Sopenharmony_ci}
8557db96d56Sopenharmony_ci
8567db96d56Sopenharmony_cistatic PyObject *
8577db96d56Sopenharmony_cicomplex_subtype_from_string(PyTypeObject *type, PyObject *v)
8587db96d56Sopenharmony_ci{
8597db96d56Sopenharmony_ci    const char *s;
8607db96d56Sopenharmony_ci    PyObject *s_buffer = NULL, *result = NULL;
8617db96d56Sopenharmony_ci    Py_ssize_t len;
8627db96d56Sopenharmony_ci
8637db96d56Sopenharmony_ci    if (PyUnicode_Check(v)) {
8647db96d56Sopenharmony_ci        s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v);
8657db96d56Sopenharmony_ci        if (s_buffer == NULL) {
8667db96d56Sopenharmony_ci            return NULL;
8677db96d56Sopenharmony_ci        }
8687db96d56Sopenharmony_ci        assert(PyUnicode_IS_ASCII(s_buffer));
8697db96d56Sopenharmony_ci        /* Simply get a pointer to existing ASCII characters. */
8707db96d56Sopenharmony_ci        s = PyUnicode_AsUTF8AndSize(s_buffer, &len);
8717db96d56Sopenharmony_ci        assert(s != NULL);
8727db96d56Sopenharmony_ci    }
8737db96d56Sopenharmony_ci    else {
8747db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
8757db96d56Sopenharmony_ci            "complex() argument must be a string or a number, not '%.200s'",
8767db96d56Sopenharmony_ci            Py_TYPE(v)->tp_name);
8777db96d56Sopenharmony_ci        return NULL;
8787db96d56Sopenharmony_ci    }
8797db96d56Sopenharmony_ci
8807db96d56Sopenharmony_ci    result = _Py_string_to_number_with_underscores(s, len, "complex", v, type,
8817db96d56Sopenharmony_ci                                                   complex_from_string_inner);
8827db96d56Sopenharmony_ci    Py_DECREF(s_buffer);
8837db96d56Sopenharmony_ci    return result;
8847db96d56Sopenharmony_ci}
8857db96d56Sopenharmony_ci
8867db96d56Sopenharmony_ci/*[clinic input]
8877db96d56Sopenharmony_ci@classmethod
8887db96d56Sopenharmony_cicomplex.__new__ as complex_new
8897db96d56Sopenharmony_ci    real as r: object(c_default="NULL") = 0
8907db96d56Sopenharmony_ci    imag as i: object(c_default="NULL") = 0
8917db96d56Sopenharmony_ci
8927db96d56Sopenharmony_ciCreate a complex number from a real part and an optional imaginary part.
8937db96d56Sopenharmony_ci
8947db96d56Sopenharmony_ciThis is equivalent to (real + imag*1j) where imag defaults to 0.
8957db96d56Sopenharmony_ci[clinic start generated code]*/
8967db96d56Sopenharmony_ci
8977db96d56Sopenharmony_cistatic PyObject *
8987db96d56Sopenharmony_cicomplex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i)
8997db96d56Sopenharmony_ci/*[clinic end generated code: output=b6c7dd577b537dc1 input=f4c667f2596d4fd1]*/
9007db96d56Sopenharmony_ci{
9017db96d56Sopenharmony_ci    PyObject *tmp;
9027db96d56Sopenharmony_ci    PyNumberMethods *nbr, *nbi = NULL;
9037db96d56Sopenharmony_ci    Py_complex cr, ci;
9047db96d56Sopenharmony_ci    int own_r = 0;
9057db96d56Sopenharmony_ci    int cr_is_complex = 0;
9067db96d56Sopenharmony_ci    int ci_is_complex = 0;
9077db96d56Sopenharmony_ci
9087db96d56Sopenharmony_ci    if (r == NULL) {
9097db96d56Sopenharmony_ci        r = _PyLong_GetZero();
9107db96d56Sopenharmony_ci    }
9117db96d56Sopenharmony_ci
9127db96d56Sopenharmony_ci    /* Special-case for a single argument when type(arg) is complex. */
9137db96d56Sopenharmony_ci    if (PyComplex_CheckExact(r) && i == NULL &&
9147db96d56Sopenharmony_ci        type == &PyComplex_Type) {
9157db96d56Sopenharmony_ci        /* Note that we can't know whether it's safe to return
9167db96d56Sopenharmony_ci           a complex *subclass* instance as-is, hence the restriction
9177db96d56Sopenharmony_ci           to exact complexes here.  If either the input or the
9187db96d56Sopenharmony_ci           output is a complex subclass, it will be handled below
9197db96d56Sopenharmony_ci           as a non-orthogonal vector.  */
9207db96d56Sopenharmony_ci        Py_INCREF(r);
9217db96d56Sopenharmony_ci        return r;
9227db96d56Sopenharmony_ci    }
9237db96d56Sopenharmony_ci    if (PyUnicode_Check(r)) {
9247db96d56Sopenharmony_ci        if (i != NULL) {
9257db96d56Sopenharmony_ci            PyErr_SetString(PyExc_TypeError,
9267db96d56Sopenharmony_ci                            "complex() can't take second arg"
9277db96d56Sopenharmony_ci                            " if first is a string");
9287db96d56Sopenharmony_ci            return NULL;
9297db96d56Sopenharmony_ci        }
9307db96d56Sopenharmony_ci        return complex_subtype_from_string(type, r);
9317db96d56Sopenharmony_ci    }
9327db96d56Sopenharmony_ci    if (i != NULL && PyUnicode_Check(i)) {
9337db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
9347db96d56Sopenharmony_ci                        "complex() second arg can't be a string");
9357db96d56Sopenharmony_ci        return NULL;
9367db96d56Sopenharmony_ci    }
9377db96d56Sopenharmony_ci
9387db96d56Sopenharmony_ci    tmp = try_complex_special_method(r);
9397db96d56Sopenharmony_ci    if (tmp) {
9407db96d56Sopenharmony_ci        r = tmp;
9417db96d56Sopenharmony_ci        own_r = 1;
9427db96d56Sopenharmony_ci    }
9437db96d56Sopenharmony_ci    else if (PyErr_Occurred()) {
9447db96d56Sopenharmony_ci        return NULL;
9457db96d56Sopenharmony_ci    }
9467db96d56Sopenharmony_ci
9477db96d56Sopenharmony_ci    nbr = Py_TYPE(r)->tp_as_number;
9487db96d56Sopenharmony_ci    if (nbr == NULL ||
9497db96d56Sopenharmony_ci        (nbr->nb_float == NULL && nbr->nb_index == NULL && !PyComplex_Check(r)))
9507db96d56Sopenharmony_ci    {
9517db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
9527db96d56Sopenharmony_ci                     "complex() first argument must be a string or a number, "
9537db96d56Sopenharmony_ci                     "not '%.200s'",
9547db96d56Sopenharmony_ci                     Py_TYPE(r)->tp_name);
9557db96d56Sopenharmony_ci        if (own_r) {
9567db96d56Sopenharmony_ci            Py_DECREF(r);
9577db96d56Sopenharmony_ci        }
9587db96d56Sopenharmony_ci        return NULL;
9597db96d56Sopenharmony_ci    }
9607db96d56Sopenharmony_ci    if (i != NULL) {
9617db96d56Sopenharmony_ci        nbi = Py_TYPE(i)->tp_as_number;
9627db96d56Sopenharmony_ci        if (nbi == NULL ||
9637db96d56Sopenharmony_ci            (nbi->nb_float == NULL && nbi->nb_index == NULL && !PyComplex_Check(i)))
9647db96d56Sopenharmony_ci        {
9657db96d56Sopenharmony_ci            PyErr_Format(PyExc_TypeError,
9667db96d56Sopenharmony_ci                         "complex() second argument must be a number, "
9677db96d56Sopenharmony_ci                         "not '%.200s'",
9687db96d56Sopenharmony_ci                         Py_TYPE(i)->tp_name);
9697db96d56Sopenharmony_ci            if (own_r) {
9707db96d56Sopenharmony_ci                Py_DECREF(r);
9717db96d56Sopenharmony_ci            }
9727db96d56Sopenharmony_ci            return NULL;
9737db96d56Sopenharmony_ci        }
9747db96d56Sopenharmony_ci    }
9757db96d56Sopenharmony_ci
9767db96d56Sopenharmony_ci    /* If we get this far, then the "real" and "imag" parts should
9777db96d56Sopenharmony_ci       both be treated as numbers, and the constructor should return a
9787db96d56Sopenharmony_ci       complex number equal to (real + imag*1j).
9797db96d56Sopenharmony_ci
9807db96d56Sopenharmony_ci       Note that we do NOT assume the input to already be in canonical
9817db96d56Sopenharmony_ci       form; the "real" and "imag" parts might themselves be complex
9827db96d56Sopenharmony_ci       numbers, which slightly complicates the code below. */
9837db96d56Sopenharmony_ci    if (PyComplex_Check(r)) {
9847db96d56Sopenharmony_ci        /* Note that if r is of a complex subtype, we're only
9857db96d56Sopenharmony_ci           retaining its real & imag parts here, and the return
9867db96d56Sopenharmony_ci           value is (properly) of the builtin complex type. */
9877db96d56Sopenharmony_ci        cr = ((PyComplexObject*)r)->cval;
9887db96d56Sopenharmony_ci        cr_is_complex = 1;
9897db96d56Sopenharmony_ci        if (own_r) {
9907db96d56Sopenharmony_ci            Py_DECREF(r);
9917db96d56Sopenharmony_ci        }
9927db96d56Sopenharmony_ci    }
9937db96d56Sopenharmony_ci    else {
9947db96d56Sopenharmony_ci        /* The "real" part really is entirely real, and contributes
9957db96d56Sopenharmony_ci           nothing in the imaginary direction.
9967db96d56Sopenharmony_ci           Just treat it as a double. */
9977db96d56Sopenharmony_ci        tmp = PyNumber_Float(r);
9987db96d56Sopenharmony_ci        if (own_r) {
9997db96d56Sopenharmony_ci            /* r was a newly created complex number, rather
10007db96d56Sopenharmony_ci               than the original "real" argument. */
10017db96d56Sopenharmony_ci            Py_DECREF(r);
10027db96d56Sopenharmony_ci        }
10037db96d56Sopenharmony_ci        if (tmp == NULL)
10047db96d56Sopenharmony_ci            return NULL;
10057db96d56Sopenharmony_ci        assert(PyFloat_Check(tmp));
10067db96d56Sopenharmony_ci        cr.real = PyFloat_AsDouble(tmp);
10077db96d56Sopenharmony_ci        cr.imag = 0.0;
10087db96d56Sopenharmony_ci        Py_DECREF(tmp);
10097db96d56Sopenharmony_ci    }
10107db96d56Sopenharmony_ci    if (i == NULL) {
10117db96d56Sopenharmony_ci        ci.real = cr.imag;
10127db96d56Sopenharmony_ci    }
10137db96d56Sopenharmony_ci    else if (PyComplex_Check(i)) {
10147db96d56Sopenharmony_ci        ci = ((PyComplexObject*)i)->cval;
10157db96d56Sopenharmony_ci        ci_is_complex = 1;
10167db96d56Sopenharmony_ci    } else {
10177db96d56Sopenharmony_ci        /* The "imag" part really is entirely imaginary, and
10187db96d56Sopenharmony_ci           contributes nothing in the real direction.
10197db96d56Sopenharmony_ci           Just treat it as a double. */
10207db96d56Sopenharmony_ci        tmp = PyNumber_Float(i);
10217db96d56Sopenharmony_ci        if (tmp == NULL)
10227db96d56Sopenharmony_ci            return NULL;
10237db96d56Sopenharmony_ci        ci.real = PyFloat_AsDouble(tmp);
10247db96d56Sopenharmony_ci        Py_DECREF(tmp);
10257db96d56Sopenharmony_ci    }
10267db96d56Sopenharmony_ci    /*  If the input was in canonical form, then the "real" and "imag"
10277db96d56Sopenharmony_ci        parts are real numbers, so that ci.imag and cr.imag are zero.
10287db96d56Sopenharmony_ci        We need this correction in case they were not real numbers. */
10297db96d56Sopenharmony_ci
10307db96d56Sopenharmony_ci    if (ci_is_complex) {
10317db96d56Sopenharmony_ci        cr.real -= ci.imag;
10327db96d56Sopenharmony_ci    }
10337db96d56Sopenharmony_ci    if (cr_is_complex && i != NULL) {
10347db96d56Sopenharmony_ci        ci.real += cr.imag;
10357db96d56Sopenharmony_ci    }
10367db96d56Sopenharmony_ci    return complex_subtype_from_doubles(type, cr.real, ci.real);
10377db96d56Sopenharmony_ci}
10387db96d56Sopenharmony_ci
10397db96d56Sopenharmony_cistatic PyNumberMethods complex_as_number = {
10407db96d56Sopenharmony_ci    (binaryfunc)complex_add,                    /* nb_add */
10417db96d56Sopenharmony_ci    (binaryfunc)complex_sub,                    /* nb_subtract */
10427db96d56Sopenharmony_ci    (binaryfunc)complex_mul,                    /* nb_multiply */
10437db96d56Sopenharmony_ci    0,                                          /* nb_remainder */
10447db96d56Sopenharmony_ci    0,                                          /* nb_divmod */
10457db96d56Sopenharmony_ci    (ternaryfunc)complex_pow,                   /* nb_power */
10467db96d56Sopenharmony_ci    (unaryfunc)complex_neg,                     /* nb_negative */
10477db96d56Sopenharmony_ci    (unaryfunc)complex_pos,                     /* nb_positive */
10487db96d56Sopenharmony_ci    (unaryfunc)complex_abs,                     /* nb_absolute */
10497db96d56Sopenharmony_ci    (inquiry)complex_bool,                      /* nb_bool */
10507db96d56Sopenharmony_ci    0,                                          /* nb_invert */
10517db96d56Sopenharmony_ci    0,                                          /* nb_lshift */
10527db96d56Sopenharmony_ci    0,                                          /* nb_rshift */
10537db96d56Sopenharmony_ci    0,                                          /* nb_and */
10547db96d56Sopenharmony_ci    0,                                          /* nb_xor */
10557db96d56Sopenharmony_ci    0,                                          /* nb_or */
10567db96d56Sopenharmony_ci    0,                                          /* nb_int */
10577db96d56Sopenharmony_ci    0,                                          /* nb_reserved */
10587db96d56Sopenharmony_ci    0,                                          /* nb_float */
10597db96d56Sopenharmony_ci    0,                                          /* nb_inplace_add */
10607db96d56Sopenharmony_ci    0,                                          /* nb_inplace_subtract */
10617db96d56Sopenharmony_ci    0,                                          /* nb_inplace_multiply*/
10627db96d56Sopenharmony_ci    0,                                          /* nb_inplace_remainder */
10637db96d56Sopenharmony_ci    0,                                          /* nb_inplace_power */
10647db96d56Sopenharmony_ci    0,                                          /* nb_inplace_lshift */
10657db96d56Sopenharmony_ci    0,                                          /* nb_inplace_rshift */
10667db96d56Sopenharmony_ci    0,                                          /* nb_inplace_and */
10677db96d56Sopenharmony_ci    0,                                          /* nb_inplace_xor */
10687db96d56Sopenharmony_ci    0,                                          /* nb_inplace_or */
10697db96d56Sopenharmony_ci    0,                                          /* nb_floor_divide */
10707db96d56Sopenharmony_ci    (binaryfunc)complex_div,                    /* nb_true_divide */
10717db96d56Sopenharmony_ci    0,                                          /* nb_inplace_floor_divide */
10727db96d56Sopenharmony_ci    0,                                          /* nb_inplace_true_divide */
10737db96d56Sopenharmony_ci};
10747db96d56Sopenharmony_ci
10757db96d56Sopenharmony_ciPyTypeObject PyComplex_Type = {
10767db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
10777db96d56Sopenharmony_ci    "complex",
10787db96d56Sopenharmony_ci    sizeof(PyComplexObject),
10797db96d56Sopenharmony_ci    0,
10807db96d56Sopenharmony_ci    0,                                          /* tp_dealloc */
10817db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
10827db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
10837db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
10847db96d56Sopenharmony_ci    0,                                          /* tp_as_async */
10857db96d56Sopenharmony_ci    (reprfunc)complex_repr,                     /* tp_repr */
10867db96d56Sopenharmony_ci    &complex_as_number,                         /* tp_as_number */
10877db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
10887db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
10897db96d56Sopenharmony_ci    (hashfunc)complex_hash,                     /* tp_hash */
10907db96d56Sopenharmony_ci    0,                                          /* tp_call */
10917db96d56Sopenharmony_ci    0,                                          /* tp_str */
10927db96d56Sopenharmony_ci    PyObject_GenericGetAttr,                    /* tp_getattro */
10937db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
10947db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
10957db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
10967db96d56Sopenharmony_ci    complex_new__doc__,                         /* tp_doc */
10977db96d56Sopenharmony_ci    0,                                          /* tp_traverse */
10987db96d56Sopenharmony_ci    0,                                          /* tp_clear */
10997db96d56Sopenharmony_ci    complex_richcompare,                        /* tp_richcompare */
11007db96d56Sopenharmony_ci    0,                                          /* tp_weaklistoffset */
11017db96d56Sopenharmony_ci    0,                                          /* tp_iter */
11027db96d56Sopenharmony_ci    0,                                          /* tp_iternext */
11037db96d56Sopenharmony_ci    complex_methods,                            /* tp_methods */
11047db96d56Sopenharmony_ci    complex_members,                            /* tp_members */
11057db96d56Sopenharmony_ci    0,                                          /* tp_getset */
11067db96d56Sopenharmony_ci    0,                                          /* tp_base */
11077db96d56Sopenharmony_ci    0,                                          /* tp_dict */
11087db96d56Sopenharmony_ci    0,                                          /* tp_descr_get */
11097db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
11107db96d56Sopenharmony_ci    0,                                          /* tp_dictoffset */
11117db96d56Sopenharmony_ci    0,                                          /* tp_init */
11127db96d56Sopenharmony_ci    PyType_GenericAlloc,                        /* tp_alloc */
11137db96d56Sopenharmony_ci    complex_new,                                /* tp_new */
11147db96d56Sopenharmony_ci    PyObject_Del,                               /* tp_free */
11157db96d56Sopenharmony_ci};
1116