17db96d56Sopenharmony_ci
27db96d56Sopenharmony_ci/* Generic object operations; and implementation of None */
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci#include "Python.h"
57db96d56Sopenharmony_ci#include "pycore_call.h"          // _PyObject_CallNoArgs()
67db96d56Sopenharmony_ci#include "pycore_ceval.h"         // _Py_EnterRecursiveCallTstate()
77db96d56Sopenharmony_ci#include "pycore_context.h"       // _PyContextTokenMissing_Type
87db96d56Sopenharmony_ci#include "pycore_dict.h"          // _PyObject_MakeDictFromInstanceAttributes()
97db96d56Sopenharmony_ci#include "pycore_floatobject.h"   // _PyFloat_DebugMallocStats()
107db96d56Sopenharmony_ci#include "pycore_initconfig.h"    // _PyStatus_EXCEPTION()
117db96d56Sopenharmony_ci#include "pycore_namespace.h"     // _PyNamespace_Type
127db96d56Sopenharmony_ci#include "pycore_object.h"        // _PyType_CheckConsistency(), _Py_FatalRefcountError()
137db96d56Sopenharmony_ci#include "pycore_pyerrors.h"      // _PyErr_Occurred()
147db96d56Sopenharmony_ci#include "pycore_pymem.h"         // _PyMem_IsPtrFreed()
157db96d56Sopenharmony_ci#include "pycore_pystate.h"       // _PyThreadState_GET()
167db96d56Sopenharmony_ci#include "pycore_symtable.h"      // PySTEntry_Type
177db96d56Sopenharmony_ci#include "pycore_typeobject.h"    // _PyTypes_InitSlotDefs()
187db96d56Sopenharmony_ci#include "pycore_unionobject.h"   // _PyUnion_Type
197db96d56Sopenharmony_ci#include "pycore_interpreteridobject.h"  // _PyInterpreterID_Type
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_ci#ifdef Py_LIMITED_API
227db96d56Sopenharmony_ci   // Prevent recursive call _Py_IncRef() <=> Py_INCREF()
237db96d56Sopenharmony_ci#  error "Py_LIMITED_API macro must not be defined"
247db96d56Sopenharmony_ci#endif
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_ci#ifdef __cplusplus
277db96d56Sopenharmony_ciextern "C" {
287db96d56Sopenharmony_ci#endif
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ci/* Defined in tracemalloc.c */
317db96d56Sopenharmony_ciextern void _PyMem_DumpTraceback(int fd, const void *ptr);
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ci
347db96d56Sopenharmony_ciint
357db96d56Sopenharmony_ci_PyObject_CheckConsistency(PyObject *op, int check_content)
367db96d56Sopenharmony_ci{
377db96d56Sopenharmony_ci#define CHECK(expr) \
387db96d56Sopenharmony_ci    do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0)
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_ci    CHECK(!_PyObject_IsFreed(op));
417db96d56Sopenharmony_ci    CHECK(Py_REFCNT(op) >= 1);
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_ci    _PyType_CheckConsistency(Py_TYPE(op));
447db96d56Sopenharmony_ci
457db96d56Sopenharmony_ci    if (PyUnicode_Check(op)) {
467db96d56Sopenharmony_ci        _PyUnicode_CheckConsistency(op, check_content);
477db96d56Sopenharmony_ci    }
487db96d56Sopenharmony_ci    else if (PyDict_Check(op)) {
497db96d56Sopenharmony_ci        _PyDict_CheckConsistency(op, check_content);
507db96d56Sopenharmony_ci    }
517db96d56Sopenharmony_ci    return 1;
527db96d56Sopenharmony_ci
537db96d56Sopenharmony_ci#undef CHECK
547db96d56Sopenharmony_ci}
557db96d56Sopenharmony_ci
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci#ifdef Py_REF_DEBUG
587db96d56Sopenharmony_ciPy_ssize_t _Py_RefTotal;
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ciPy_ssize_t
617db96d56Sopenharmony_ci_Py_GetRefTotal(void)
627db96d56Sopenharmony_ci{
637db96d56Sopenharmony_ci    return _Py_RefTotal;
647db96d56Sopenharmony_ci}
657db96d56Sopenharmony_ci
667db96d56Sopenharmony_civoid
677db96d56Sopenharmony_ci_PyDebug_PrintTotalRefs(void) {
687db96d56Sopenharmony_ci    fprintf(stderr,
697db96d56Sopenharmony_ci            "[%zd refs, %zd blocks]\n",
707db96d56Sopenharmony_ci            _Py_GetRefTotal(), _Py_GetAllocatedBlocks());
717db96d56Sopenharmony_ci}
727db96d56Sopenharmony_ci#endif /* Py_REF_DEBUG */
737db96d56Sopenharmony_ci
747db96d56Sopenharmony_ci/* Object allocation routines used by NEWOBJ and NEWVAROBJ macros.
757db96d56Sopenharmony_ci   These are used by the individual routines for object creation.
767db96d56Sopenharmony_ci   Do not call them otherwise, they do not initialize the object! */
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_ci#ifdef Py_TRACE_REFS
797db96d56Sopenharmony_ci/* Head of circular doubly-linked list of all objects.  These are linked
807db96d56Sopenharmony_ci * together via the _ob_prev and _ob_next members of a PyObject, which
817db96d56Sopenharmony_ci * exist only in a Py_TRACE_REFS build.
827db96d56Sopenharmony_ci */
837db96d56Sopenharmony_cistatic PyObject refchain = {&refchain, &refchain};
847db96d56Sopenharmony_ci
857db96d56Sopenharmony_ci/* Insert op at the front of the list of all objects.  If force is true,
867db96d56Sopenharmony_ci * op is added even if _ob_prev and _ob_next are non-NULL already.  If
877db96d56Sopenharmony_ci * force is false amd _ob_prev or _ob_next are non-NULL, do nothing.
887db96d56Sopenharmony_ci * force should be true if and only if op points to freshly allocated,
897db96d56Sopenharmony_ci * uninitialized memory, or you've unlinked op from the list and are
907db96d56Sopenharmony_ci * relinking it into the front.
917db96d56Sopenharmony_ci * Note that objects are normally added to the list via _Py_NewReference,
927db96d56Sopenharmony_ci * which is called by PyObject_Init.  Not all objects are initialized that
937db96d56Sopenharmony_ci * way, though; exceptions include statically allocated type objects, and
947db96d56Sopenharmony_ci * statically allocated singletons (like Py_True and Py_None).
957db96d56Sopenharmony_ci */
967db96d56Sopenharmony_civoid
977db96d56Sopenharmony_ci_Py_AddToAllObjects(PyObject *op, int force)
987db96d56Sopenharmony_ci{
997db96d56Sopenharmony_ci#ifdef  Py_DEBUG
1007db96d56Sopenharmony_ci    if (!force) {
1017db96d56Sopenharmony_ci        /* If it's initialized memory, op must be in or out of
1027db96d56Sopenharmony_ci         * the list unambiguously.
1037db96d56Sopenharmony_ci         */
1047db96d56Sopenharmony_ci        _PyObject_ASSERT(op, (op->_ob_prev == NULL) == (op->_ob_next == NULL));
1057db96d56Sopenharmony_ci    }
1067db96d56Sopenharmony_ci#endif
1077db96d56Sopenharmony_ci    if (force || op->_ob_prev == NULL) {
1087db96d56Sopenharmony_ci        op->_ob_next = refchain._ob_next;
1097db96d56Sopenharmony_ci        op->_ob_prev = &refchain;
1107db96d56Sopenharmony_ci        refchain._ob_next->_ob_prev = op;
1117db96d56Sopenharmony_ci        refchain._ob_next = op;
1127db96d56Sopenharmony_ci    }
1137db96d56Sopenharmony_ci}
1147db96d56Sopenharmony_ci#endif  /* Py_TRACE_REFS */
1157db96d56Sopenharmony_ci
1167db96d56Sopenharmony_ci#ifdef Py_REF_DEBUG
1177db96d56Sopenharmony_ci/* Log a fatal error; doesn't return. */
1187db96d56Sopenharmony_civoid
1197db96d56Sopenharmony_ci_Py_NegativeRefcount(const char *filename, int lineno, PyObject *op)
1207db96d56Sopenharmony_ci{
1217db96d56Sopenharmony_ci    _PyObject_AssertFailed(op, NULL, "object has negative ref count",
1227db96d56Sopenharmony_ci                           filename, lineno, __func__);
1237db96d56Sopenharmony_ci}
1247db96d56Sopenharmony_ci
1257db96d56Sopenharmony_ci#endif /* Py_REF_DEBUG */
1267db96d56Sopenharmony_ci
1277db96d56Sopenharmony_civoid
1287db96d56Sopenharmony_ciPy_IncRef(PyObject *o)
1297db96d56Sopenharmony_ci{
1307db96d56Sopenharmony_ci    Py_XINCREF(o);
1317db96d56Sopenharmony_ci}
1327db96d56Sopenharmony_ci
1337db96d56Sopenharmony_civoid
1347db96d56Sopenharmony_ciPy_DecRef(PyObject *o)
1357db96d56Sopenharmony_ci{
1367db96d56Sopenharmony_ci    Py_XDECREF(o);
1377db96d56Sopenharmony_ci}
1387db96d56Sopenharmony_ci
1397db96d56Sopenharmony_civoid
1407db96d56Sopenharmony_ci_Py_IncRef(PyObject *o)
1417db96d56Sopenharmony_ci{
1427db96d56Sopenharmony_ci    Py_INCREF(o);
1437db96d56Sopenharmony_ci}
1447db96d56Sopenharmony_ci
1457db96d56Sopenharmony_civoid
1467db96d56Sopenharmony_ci_Py_DecRef(PyObject *o)
1477db96d56Sopenharmony_ci{
1487db96d56Sopenharmony_ci    Py_DECREF(o);
1497db96d56Sopenharmony_ci}
1507db96d56Sopenharmony_ci
1517db96d56Sopenharmony_ciPyObject *
1527db96d56Sopenharmony_ciPyObject_Init(PyObject *op, PyTypeObject *tp)
1537db96d56Sopenharmony_ci{
1547db96d56Sopenharmony_ci    if (op == NULL) {
1557db96d56Sopenharmony_ci        return PyErr_NoMemory();
1567db96d56Sopenharmony_ci    }
1577db96d56Sopenharmony_ci
1587db96d56Sopenharmony_ci    _PyObject_Init(op, tp);
1597db96d56Sopenharmony_ci    return op;
1607db96d56Sopenharmony_ci}
1617db96d56Sopenharmony_ci
1627db96d56Sopenharmony_ciPyVarObject *
1637db96d56Sopenharmony_ciPyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size)
1647db96d56Sopenharmony_ci{
1657db96d56Sopenharmony_ci    if (op == NULL) {
1667db96d56Sopenharmony_ci        return (PyVarObject *) PyErr_NoMemory();
1677db96d56Sopenharmony_ci    }
1687db96d56Sopenharmony_ci
1697db96d56Sopenharmony_ci    _PyObject_InitVar(op, tp, size);
1707db96d56Sopenharmony_ci    return op;
1717db96d56Sopenharmony_ci}
1727db96d56Sopenharmony_ci
1737db96d56Sopenharmony_ciPyObject *
1747db96d56Sopenharmony_ci_PyObject_New(PyTypeObject *tp)
1757db96d56Sopenharmony_ci{
1767db96d56Sopenharmony_ci    PyObject *op = (PyObject *) PyObject_Malloc(_PyObject_SIZE(tp));
1777db96d56Sopenharmony_ci    if (op == NULL) {
1787db96d56Sopenharmony_ci        return PyErr_NoMemory();
1797db96d56Sopenharmony_ci    }
1807db96d56Sopenharmony_ci    _PyObject_Init(op, tp);
1817db96d56Sopenharmony_ci    return op;
1827db96d56Sopenharmony_ci}
1837db96d56Sopenharmony_ci
1847db96d56Sopenharmony_ciPyVarObject *
1857db96d56Sopenharmony_ci_PyObject_NewVar(PyTypeObject *tp, Py_ssize_t nitems)
1867db96d56Sopenharmony_ci{
1877db96d56Sopenharmony_ci    PyVarObject *op;
1887db96d56Sopenharmony_ci    const size_t size = _PyObject_VAR_SIZE(tp, nitems);
1897db96d56Sopenharmony_ci    op = (PyVarObject *) PyObject_Malloc(size);
1907db96d56Sopenharmony_ci    if (op == NULL) {
1917db96d56Sopenharmony_ci        return (PyVarObject *)PyErr_NoMemory();
1927db96d56Sopenharmony_ci    }
1937db96d56Sopenharmony_ci    _PyObject_InitVar(op, tp, nitems);
1947db96d56Sopenharmony_ci    return op;
1957db96d56Sopenharmony_ci}
1967db96d56Sopenharmony_ci
1977db96d56Sopenharmony_civoid
1987db96d56Sopenharmony_ciPyObject_CallFinalizer(PyObject *self)
1997db96d56Sopenharmony_ci{
2007db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(self);
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_ci    if (tp->tp_finalize == NULL)
2037db96d56Sopenharmony_ci        return;
2047db96d56Sopenharmony_ci    /* tp_finalize should only be called once. */
2057db96d56Sopenharmony_ci    if (_PyType_IS_GC(tp) && _PyGC_FINALIZED(self))
2067db96d56Sopenharmony_ci        return;
2077db96d56Sopenharmony_ci
2087db96d56Sopenharmony_ci    tp->tp_finalize(self);
2097db96d56Sopenharmony_ci    if (_PyType_IS_GC(tp)) {
2107db96d56Sopenharmony_ci        _PyGC_SET_FINALIZED(self);
2117db96d56Sopenharmony_ci    }
2127db96d56Sopenharmony_ci}
2137db96d56Sopenharmony_ci
2147db96d56Sopenharmony_ciint
2157db96d56Sopenharmony_ciPyObject_CallFinalizerFromDealloc(PyObject *self)
2167db96d56Sopenharmony_ci{
2177db96d56Sopenharmony_ci    if (Py_REFCNT(self) != 0) {
2187db96d56Sopenharmony_ci        _PyObject_ASSERT_FAILED_MSG(self,
2197db96d56Sopenharmony_ci                                    "PyObject_CallFinalizerFromDealloc called "
2207db96d56Sopenharmony_ci                                    "on object with a non-zero refcount");
2217db96d56Sopenharmony_ci    }
2227db96d56Sopenharmony_ci
2237db96d56Sopenharmony_ci    /* Temporarily resurrect the object. */
2247db96d56Sopenharmony_ci    Py_SET_REFCNT(self, 1);
2257db96d56Sopenharmony_ci
2267db96d56Sopenharmony_ci    PyObject_CallFinalizer(self);
2277db96d56Sopenharmony_ci
2287db96d56Sopenharmony_ci    _PyObject_ASSERT_WITH_MSG(self,
2297db96d56Sopenharmony_ci                              Py_REFCNT(self) > 0,
2307db96d56Sopenharmony_ci                              "refcount is too small");
2317db96d56Sopenharmony_ci
2327db96d56Sopenharmony_ci    /* Undo the temporary resurrection; can't use DECREF here, it would
2337db96d56Sopenharmony_ci     * cause a recursive call. */
2347db96d56Sopenharmony_ci    Py_SET_REFCNT(self, Py_REFCNT(self) - 1);
2357db96d56Sopenharmony_ci    if (Py_REFCNT(self) == 0) {
2367db96d56Sopenharmony_ci        return 0;         /* this is the normal path out */
2377db96d56Sopenharmony_ci    }
2387db96d56Sopenharmony_ci
2397db96d56Sopenharmony_ci    /* tp_finalize resurrected it!  Make it look like the original Py_DECREF
2407db96d56Sopenharmony_ci     * never happened. */
2417db96d56Sopenharmony_ci    Py_ssize_t refcnt = Py_REFCNT(self);
2427db96d56Sopenharmony_ci    _Py_NewReference(self);
2437db96d56Sopenharmony_ci    Py_SET_REFCNT(self, refcnt);
2447db96d56Sopenharmony_ci
2457db96d56Sopenharmony_ci    _PyObject_ASSERT(self,
2467db96d56Sopenharmony_ci                     (!_PyType_IS_GC(Py_TYPE(self))
2477db96d56Sopenharmony_ci                      || _PyObject_GC_IS_TRACKED(self)));
2487db96d56Sopenharmony_ci    /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased
2497db96d56Sopenharmony_ci       _Py_RefTotal, so we need to undo that. */
2507db96d56Sopenharmony_ci#ifdef Py_REF_DEBUG
2517db96d56Sopenharmony_ci    _Py_RefTotal--;
2527db96d56Sopenharmony_ci#endif
2537db96d56Sopenharmony_ci    return -1;
2547db96d56Sopenharmony_ci}
2557db96d56Sopenharmony_ci
2567db96d56Sopenharmony_ciint
2577db96d56Sopenharmony_ciPyObject_Print(PyObject *op, FILE *fp, int flags)
2587db96d56Sopenharmony_ci{
2597db96d56Sopenharmony_ci    int ret = 0;
2607db96d56Sopenharmony_ci    if (PyErr_CheckSignals())
2617db96d56Sopenharmony_ci        return -1;
2627db96d56Sopenharmony_ci#ifdef USE_STACKCHECK
2637db96d56Sopenharmony_ci    if (PyOS_CheckStack()) {
2647db96d56Sopenharmony_ci        PyErr_SetString(PyExc_MemoryError, "stack overflow");
2657db96d56Sopenharmony_ci        return -1;
2667db96d56Sopenharmony_ci    }
2677db96d56Sopenharmony_ci#endif
2687db96d56Sopenharmony_ci    clearerr(fp); /* Clear any previous error condition */
2697db96d56Sopenharmony_ci    if (op == NULL) {
2707db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
2717db96d56Sopenharmony_ci        fprintf(fp, "<nil>");
2727db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
2737db96d56Sopenharmony_ci    }
2747db96d56Sopenharmony_ci    else {
2757db96d56Sopenharmony_ci        if (Py_REFCNT(op) <= 0) {
2767db96d56Sopenharmony_ci            /* XXX(twouters) cast refcount to long until %zd is
2777db96d56Sopenharmony_ci               universally available */
2787db96d56Sopenharmony_ci            Py_BEGIN_ALLOW_THREADS
2797db96d56Sopenharmony_ci            fprintf(fp, "<refcnt %ld at %p>",
2807db96d56Sopenharmony_ci                (long)Py_REFCNT(op), (void *)op);
2817db96d56Sopenharmony_ci            Py_END_ALLOW_THREADS
2827db96d56Sopenharmony_ci        }
2837db96d56Sopenharmony_ci        else {
2847db96d56Sopenharmony_ci            PyObject *s;
2857db96d56Sopenharmony_ci            if (flags & Py_PRINT_RAW)
2867db96d56Sopenharmony_ci                s = PyObject_Str(op);
2877db96d56Sopenharmony_ci            else
2887db96d56Sopenharmony_ci                s = PyObject_Repr(op);
2897db96d56Sopenharmony_ci            if (s == NULL)
2907db96d56Sopenharmony_ci                ret = -1;
2917db96d56Sopenharmony_ci            else if (PyBytes_Check(s)) {
2927db96d56Sopenharmony_ci                fwrite(PyBytes_AS_STRING(s), 1,
2937db96d56Sopenharmony_ci                       PyBytes_GET_SIZE(s), fp);
2947db96d56Sopenharmony_ci            }
2957db96d56Sopenharmony_ci            else if (PyUnicode_Check(s)) {
2967db96d56Sopenharmony_ci                PyObject *t;
2977db96d56Sopenharmony_ci                t = PyUnicode_AsEncodedString(s, "utf-8", "backslashreplace");
2987db96d56Sopenharmony_ci                if (t == NULL) {
2997db96d56Sopenharmony_ci                    ret = -1;
3007db96d56Sopenharmony_ci                }
3017db96d56Sopenharmony_ci                else {
3027db96d56Sopenharmony_ci                    fwrite(PyBytes_AS_STRING(t), 1,
3037db96d56Sopenharmony_ci                           PyBytes_GET_SIZE(t), fp);
3047db96d56Sopenharmony_ci                    Py_DECREF(t);
3057db96d56Sopenharmony_ci                }
3067db96d56Sopenharmony_ci            }
3077db96d56Sopenharmony_ci            else {
3087db96d56Sopenharmony_ci                PyErr_Format(PyExc_TypeError,
3097db96d56Sopenharmony_ci                             "str() or repr() returned '%.100s'",
3107db96d56Sopenharmony_ci                             Py_TYPE(s)->tp_name);
3117db96d56Sopenharmony_ci                ret = -1;
3127db96d56Sopenharmony_ci            }
3137db96d56Sopenharmony_ci            Py_XDECREF(s);
3147db96d56Sopenharmony_ci        }
3157db96d56Sopenharmony_ci    }
3167db96d56Sopenharmony_ci    if (ret == 0) {
3177db96d56Sopenharmony_ci        if (ferror(fp)) {
3187db96d56Sopenharmony_ci            PyErr_SetFromErrno(PyExc_OSError);
3197db96d56Sopenharmony_ci            clearerr(fp);
3207db96d56Sopenharmony_ci            ret = -1;
3217db96d56Sopenharmony_ci        }
3227db96d56Sopenharmony_ci    }
3237db96d56Sopenharmony_ci    return ret;
3247db96d56Sopenharmony_ci}
3257db96d56Sopenharmony_ci
3267db96d56Sopenharmony_ci/* For debugging convenience.  Set a breakpoint here and call it from your DLL */
3277db96d56Sopenharmony_civoid
3287db96d56Sopenharmony_ci_Py_BreakPoint(void)
3297db96d56Sopenharmony_ci{
3307db96d56Sopenharmony_ci}
3317db96d56Sopenharmony_ci
3327db96d56Sopenharmony_ci
3337db96d56Sopenharmony_ci/* Heuristic checking if the object memory is uninitialized or deallocated.
3347db96d56Sopenharmony_ci   Rely on the debug hooks on Python memory allocators:
3357db96d56Sopenharmony_ci   see _PyMem_IsPtrFreed().
3367db96d56Sopenharmony_ci
3377db96d56Sopenharmony_ci   The function can be used to prevent segmentation fault on dereferencing
3387db96d56Sopenharmony_ci   pointers like 0xDDDDDDDDDDDDDDDD. */
3397db96d56Sopenharmony_ciint
3407db96d56Sopenharmony_ci_PyObject_IsFreed(PyObject *op)
3417db96d56Sopenharmony_ci{
3427db96d56Sopenharmony_ci    if (_PyMem_IsPtrFreed(op) || _PyMem_IsPtrFreed(Py_TYPE(op))) {
3437db96d56Sopenharmony_ci        return 1;
3447db96d56Sopenharmony_ci    }
3457db96d56Sopenharmony_ci    /* ignore op->ob_ref: its value can have be modified
3467db96d56Sopenharmony_ci       by Py_INCREF() and Py_DECREF(). */
3477db96d56Sopenharmony_ci#ifdef Py_TRACE_REFS
3487db96d56Sopenharmony_ci    if (op->_ob_next != NULL && _PyMem_IsPtrFreed(op->_ob_next)) {
3497db96d56Sopenharmony_ci        return 1;
3507db96d56Sopenharmony_ci    }
3517db96d56Sopenharmony_ci    if (op->_ob_prev != NULL && _PyMem_IsPtrFreed(op->_ob_prev)) {
3527db96d56Sopenharmony_ci         return 1;
3537db96d56Sopenharmony_ci     }
3547db96d56Sopenharmony_ci#endif
3557db96d56Sopenharmony_ci    return 0;
3567db96d56Sopenharmony_ci}
3577db96d56Sopenharmony_ci
3587db96d56Sopenharmony_ci
3597db96d56Sopenharmony_ci/* For debugging convenience.  See Misc/gdbinit for some useful gdb hooks */
3607db96d56Sopenharmony_civoid
3617db96d56Sopenharmony_ci_PyObject_Dump(PyObject* op)
3627db96d56Sopenharmony_ci{
3637db96d56Sopenharmony_ci    if (_PyObject_IsFreed(op)) {
3647db96d56Sopenharmony_ci        /* It seems like the object memory has been freed:
3657db96d56Sopenharmony_ci           don't access it to prevent a segmentation fault. */
3667db96d56Sopenharmony_ci        fprintf(stderr, "<object at %p is freed>\n", op);
3677db96d56Sopenharmony_ci        fflush(stderr);
3687db96d56Sopenharmony_ci        return;
3697db96d56Sopenharmony_ci    }
3707db96d56Sopenharmony_ci
3717db96d56Sopenharmony_ci    /* first, write fields which are the least likely to crash */
3727db96d56Sopenharmony_ci    fprintf(stderr, "object address  : %p\n", (void *)op);
3737db96d56Sopenharmony_ci    /* XXX(twouters) cast refcount to long until %zd is
3747db96d56Sopenharmony_ci       universally available */
3757db96d56Sopenharmony_ci    fprintf(stderr, "object refcount : %ld\n", (long)Py_REFCNT(op));
3767db96d56Sopenharmony_ci    fflush(stderr);
3777db96d56Sopenharmony_ci
3787db96d56Sopenharmony_ci    PyTypeObject *type = Py_TYPE(op);
3797db96d56Sopenharmony_ci    fprintf(stderr, "object type     : %p\n", type);
3807db96d56Sopenharmony_ci    fprintf(stderr, "object type name: %s\n",
3817db96d56Sopenharmony_ci            type==NULL ? "NULL" : type->tp_name);
3827db96d56Sopenharmony_ci
3837db96d56Sopenharmony_ci    /* the most dangerous part */
3847db96d56Sopenharmony_ci    fprintf(stderr, "object repr     : ");
3857db96d56Sopenharmony_ci    fflush(stderr);
3867db96d56Sopenharmony_ci
3877db96d56Sopenharmony_ci    PyGILState_STATE gil = PyGILState_Ensure();
3887db96d56Sopenharmony_ci    PyObject *error_type, *error_value, *error_traceback;
3897db96d56Sopenharmony_ci    PyErr_Fetch(&error_type, &error_value, &error_traceback);
3907db96d56Sopenharmony_ci
3917db96d56Sopenharmony_ci    (void)PyObject_Print(op, stderr, 0);
3927db96d56Sopenharmony_ci    fflush(stderr);
3937db96d56Sopenharmony_ci
3947db96d56Sopenharmony_ci    PyErr_Restore(error_type, error_value, error_traceback);
3957db96d56Sopenharmony_ci    PyGILState_Release(gil);
3967db96d56Sopenharmony_ci
3977db96d56Sopenharmony_ci    fprintf(stderr, "\n");
3987db96d56Sopenharmony_ci    fflush(stderr);
3997db96d56Sopenharmony_ci}
4007db96d56Sopenharmony_ci
4017db96d56Sopenharmony_ciPyObject *
4027db96d56Sopenharmony_ciPyObject_Repr(PyObject *v)
4037db96d56Sopenharmony_ci{
4047db96d56Sopenharmony_ci    PyObject *res;
4057db96d56Sopenharmony_ci    if (PyErr_CheckSignals())
4067db96d56Sopenharmony_ci        return NULL;
4077db96d56Sopenharmony_ci#ifdef USE_STACKCHECK
4087db96d56Sopenharmony_ci    if (PyOS_CheckStack()) {
4097db96d56Sopenharmony_ci        PyErr_SetString(PyExc_MemoryError, "stack overflow");
4107db96d56Sopenharmony_ci        return NULL;
4117db96d56Sopenharmony_ci    }
4127db96d56Sopenharmony_ci#endif
4137db96d56Sopenharmony_ci    if (v == NULL)
4147db96d56Sopenharmony_ci        return PyUnicode_FromString("<NULL>");
4157db96d56Sopenharmony_ci    if (Py_TYPE(v)->tp_repr == NULL)
4167db96d56Sopenharmony_ci        return PyUnicode_FromFormat("<%s object at %p>",
4177db96d56Sopenharmony_ci                                    Py_TYPE(v)->tp_name, v);
4187db96d56Sopenharmony_ci
4197db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
4207db96d56Sopenharmony_ci#ifdef Py_DEBUG
4217db96d56Sopenharmony_ci    /* PyObject_Repr() must not be called with an exception set,
4227db96d56Sopenharmony_ci       because it can clear it (directly or indirectly) and so the
4237db96d56Sopenharmony_ci       caller loses its exception */
4247db96d56Sopenharmony_ci    assert(!_PyErr_Occurred(tstate));
4257db96d56Sopenharmony_ci#endif
4267db96d56Sopenharmony_ci
4277db96d56Sopenharmony_ci    /* It is possible for a type to have a tp_repr representation that loops
4287db96d56Sopenharmony_ci       infinitely. */
4297db96d56Sopenharmony_ci    if (_Py_EnterRecursiveCallTstate(tstate,
4307db96d56Sopenharmony_ci                                     " while getting the repr of an object")) {
4317db96d56Sopenharmony_ci        return NULL;
4327db96d56Sopenharmony_ci    }
4337db96d56Sopenharmony_ci    res = (*Py_TYPE(v)->tp_repr)(v);
4347db96d56Sopenharmony_ci    _Py_LeaveRecursiveCallTstate(tstate);
4357db96d56Sopenharmony_ci
4367db96d56Sopenharmony_ci    if (res == NULL) {
4377db96d56Sopenharmony_ci        return NULL;
4387db96d56Sopenharmony_ci    }
4397db96d56Sopenharmony_ci    if (!PyUnicode_Check(res)) {
4407db96d56Sopenharmony_ci        _PyErr_Format(tstate, PyExc_TypeError,
4417db96d56Sopenharmony_ci                      "__repr__ returned non-string (type %.200s)",
4427db96d56Sopenharmony_ci                      Py_TYPE(res)->tp_name);
4437db96d56Sopenharmony_ci        Py_DECREF(res);
4447db96d56Sopenharmony_ci        return NULL;
4457db96d56Sopenharmony_ci    }
4467db96d56Sopenharmony_ci#ifndef Py_DEBUG
4477db96d56Sopenharmony_ci    if (PyUnicode_READY(res) < 0) {
4487db96d56Sopenharmony_ci        return NULL;
4497db96d56Sopenharmony_ci    }
4507db96d56Sopenharmony_ci#endif
4517db96d56Sopenharmony_ci    return res;
4527db96d56Sopenharmony_ci}
4537db96d56Sopenharmony_ci
4547db96d56Sopenharmony_ciPyObject *
4557db96d56Sopenharmony_ciPyObject_Str(PyObject *v)
4567db96d56Sopenharmony_ci{
4577db96d56Sopenharmony_ci    PyObject *res;
4587db96d56Sopenharmony_ci    if (PyErr_CheckSignals())
4597db96d56Sopenharmony_ci        return NULL;
4607db96d56Sopenharmony_ci#ifdef USE_STACKCHECK
4617db96d56Sopenharmony_ci    if (PyOS_CheckStack()) {
4627db96d56Sopenharmony_ci        PyErr_SetString(PyExc_MemoryError, "stack overflow");
4637db96d56Sopenharmony_ci        return NULL;
4647db96d56Sopenharmony_ci    }
4657db96d56Sopenharmony_ci#endif
4667db96d56Sopenharmony_ci    if (v == NULL)
4677db96d56Sopenharmony_ci        return PyUnicode_FromString("<NULL>");
4687db96d56Sopenharmony_ci    if (PyUnicode_CheckExact(v)) {
4697db96d56Sopenharmony_ci#ifndef Py_DEBUG
4707db96d56Sopenharmony_ci        if (PyUnicode_READY(v) < 0)
4717db96d56Sopenharmony_ci            return NULL;
4727db96d56Sopenharmony_ci#endif
4737db96d56Sopenharmony_ci        Py_INCREF(v);
4747db96d56Sopenharmony_ci        return v;
4757db96d56Sopenharmony_ci    }
4767db96d56Sopenharmony_ci    if (Py_TYPE(v)->tp_str == NULL)
4777db96d56Sopenharmony_ci        return PyObject_Repr(v);
4787db96d56Sopenharmony_ci
4797db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
4807db96d56Sopenharmony_ci#ifdef Py_DEBUG
4817db96d56Sopenharmony_ci    /* PyObject_Str() must not be called with an exception set,
4827db96d56Sopenharmony_ci       because it can clear it (directly or indirectly) and so the
4837db96d56Sopenharmony_ci       caller loses its exception */
4847db96d56Sopenharmony_ci    assert(!_PyErr_Occurred(tstate));
4857db96d56Sopenharmony_ci#endif
4867db96d56Sopenharmony_ci
4877db96d56Sopenharmony_ci    /* It is possible for a type to have a tp_str representation that loops
4887db96d56Sopenharmony_ci       infinitely. */
4897db96d56Sopenharmony_ci    if (_Py_EnterRecursiveCallTstate(tstate, " while getting the str of an object")) {
4907db96d56Sopenharmony_ci        return NULL;
4917db96d56Sopenharmony_ci    }
4927db96d56Sopenharmony_ci    res = (*Py_TYPE(v)->tp_str)(v);
4937db96d56Sopenharmony_ci    _Py_LeaveRecursiveCallTstate(tstate);
4947db96d56Sopenharmony_ci
4957db96d56Sopenharmony_ci    if (res == NULL) {
4967db96d56Sopenharmony_ci        return NULL;
4977db96d56Sopenharmony_ci    }
4987db96d56Sopenharmony_ci    if (!PyUnicode_Check(res)) {
4997db96d56Sopenharmony_ci        _PyErr_Format(tstate, PyExc_TypeError,
5007db96d56Sopenharmony_ci                      "__str__ returned non-string (type %.200s)",
5017db96d56Sopenharmony_ci                      Py_TYPE(res)->tp_name);
5027db96d56Sopenharmony_ci        Py_DECREF(res);
5037db96d56Sopenharmony_ci        return NULL;
5047db96d56Sopenharmony_ci    }
5057db96d56Sopenharmony_ci#ifndef Py_DEBUG
5067db96d56Sopenharmony_ci    if (PyUnicode_READY(res) < 0) {
5077db96d56Sopenharmony_ci        return NULL;
5087db96d56Sopenharmony_ci    }
5097db96d56Sopenharmony_ci#endif
5107db96d56Sopenharmony_ci    assert(_PyUnicode_CheckConsistency(res, 1));
5117db96d56Sopenharmony_ci    return res;
5127db96d56Sopenharmony_ci}
5137db96d56Sopenharmony_ci
5147db96d56Sopenharmony_ciPyObject *
5157db96d56Sopenharmony_ciPyObject_ASCII(PyObject *v)
5167db96d56Sopenharmony_ci{
5177db96d56Sopenharmony_ci    PyObject *repr, *ascii, *res;
5187db96d56Sopenharmony_ci
5197db96d56Sopenharmony_ci    repr = PyObject_Repr(v);
5207db96d56Sopenharmony_ci    if (repr == NULL)
5217db96d56Sopenharmony_ci        return NULL;
5227db96d56Sopenharmony_ci
5237db96d56Sopenharmony_ci    if (PyUnicode_IS_ASCII(repr))
5247db96d56Sopenharmony_ci        return repr;
5257db96d56Sopenharmony_ci
5267db96d56Sopenharmony_ci    /* repr is guaranteed to be a PyUnicode object by PyObject_Repr */
5277db96d56Sopenharmony_ci    ascii = _PyUnicode_AsASCIIString(repr, "backslashreplace");
5287db96d56Sopenharmony_ci    Py_DECREF(repr);
5297db96d56Sopenharmony_ci    if (ascii == NULL)
5307db96d56Sopenharmony_ci        return NULL;
5317db96d56Sopenharmony_ci
5327db96d56Sopenharmony_ci    res = PyUnicode_DecodeASCII(
5337db96d56Sopenharmony_ci        PyBytes_AS_STRING(ascii),
5347db96d56Sopenharmony_ci        PyBytes_GET_SIZE(ascii),
5357db96d56Sopenharmony_ci        NULL);
5367db96d56Sopenharmony_ci
5377db96d56Sopenharmony_ci    Py_DECREF(ascii);
5387db96d56Sopenharmony_ci    return res;
5397db96d56Sopenharmony_ci}
5407db96d56Sopenharmony_ci
5417db96d56Sopenharmony_ciPyObject *
5427db96d56Sopenharmony_ciPyObject_Bytes(PyObject *v)
5437db96d56Sopenharmony_ci{
5447db96d56Sopenharmony_ci    PyObject *result, *func;
5457db96d56Sopenharmony_ci
5467db96d56Sopenharmony_ci    if (v == NULL)
5477db96d56Sopenharmony_ci        return PyBytes_FromString("<NULL>");
5487db96d56Sopenharmony_ci
5497db96d56Sopenharmony_ci    if (PyBytes_CheckExact(v)) {
5507db96d56Sopenharmony_ci        Py_INCREF(v);
5517db96d56Sopenharmony_ci        return v;
5527db96d56Sopenharmony_ci    }
5537db96d56Sopenharmony_ci
5547db96d56Sopenharmony_ci    func = _PyObject_LookupSpecial(v, &_Py_ID(__bytes__));
5557db96d56Sopenharmony_ci    if (func != NULL) {
5567db96d56Sopenharmony_ci        result = _PyObject_CallNoArgs(func);
5577db96d56Sopenharmony_ci        Py_DECREF(func);
5587db96d56Sopenharmony_ci        if (result == NULL)
5597db96d56Sopenharmony_ci            return NULL;
5607db96d56Sopenharmony_ci        if (!PyBytes_Check(result)) {
5617db96d56Sopenharmony_ci            PyErr_Format(PyExc_TypeError,
5627db96d56Sopenharmony_ci                         "__bytes__ returned non-bytes (type %.200s)",
5637db96d56Sopenharmony_ci                         Py_TYPE(result)->tp_name);
5647db96d56Sopenharmony_ci            Py_DECREF(result);
5657db96d56Sopenharmony_ci            return NULL;
5667db96d56Sopenharmony_ci        }
5677db96d56Sopenharmony_ci        return result;
5687db96d56Sopenharmony_ci    }
5697db96d56Sopenharmony_ci    else if (PyErr_Occurred())
5707db96d56Sopenharmony_ci        return NULL;
5717db96d56Sopenharmony_ci    return PyBytes_FromObject(v);
5727db96d56Sopenharmony_ci}
5737db96d56Sopenharmony_ci
5747db96d56Sopenharmony_ci
5757db96d56Sopenharmony_ci/*
5767db96d56Sopenharmony_cidef _PyObject_FunctionStr(x):
5777db96d56Sopenharmony_ci    try:
5787db96d56Sopenharmony_ci        qualname = x.__qualname__
5797db96d56Sopenharmony_ci    except AttributeError:
5807db96d56Sopenharmony_ci        return str(x)
5817db96d56Sopenharmony_ci    try:
5827db96d56Sopenharmony_ci        mod = x.__module__
5837db96d56Sopenharmony_ci        if mod is not None and mod != 'builtins':
5847db96d56Sopenharmony_ci            return f"{x.__module__}.{qualname}()"
5857db96d56Sopenharmony_ci    except AttributeError:
5867db96d56Sopenharmony_ci        pass
5877db96d56Sopenharmony_ci    return qualname
5887db96d56Sopenharmony_ci*/
5897db96d56Sopenharmony_ciPyObject *
5907db96d56Sopenharmony_ci_PyObject_FunctionStr(PyObject *x)
5917db96d56Sopenharmony_ci{
5927db96d56Sopenharmony_ci    assert(!PyErr_Occurred());
5937db96d56Sopenharmony_ci    PyObject *qualname;
5947db96d56Sopenharmony_ci    int ret = _PyObject_LookupAttr(x, &_Py_ID(__qualname__), &qualname);
5957db96d56Sopenharmony_ci    if (qualname == NULL) {
5967db96d56Sopenharmony_ci        if (ret < 0) {
5977db96d56Sopenharmony_ci            return NULL;
5987db96d56Sopenharmony_ci        }
5997db96d56Sopenharmony_ci        return PyObject_Str(x);
6007db96d56Sopenharmony_ci    }
6017db96d56Sopenharmony_ci    PyObject *module;
6027db96d56Sopenharmony_ci    PyObject *result = NULL;
6037db96d56Sopenharmony_ci    ret = _PyObject_LookupAttr(x, &_Py_ID(__module__), &module);
6047db96d56Sopenharmony_ci    if (module != NULL && module != Py_None) {
6057db96d56Sopenharmony_ci        ret = PyObject_RichCompareBool(module, &_Py_ID(builtins), Py_NE);
6067db96d56Sopenharmony_ci        if (ret < 0) {
6077db96d56Sopenharmony_ci            // error
6087db96d56Sopenharmony_ci            goto done;
6097db96d56Sopenharmony_ci        }
6107db96d56Sopenharmony_ci        if (ret > 0) {
6117db96d56Sopenharmony_ci            result = PyUnicode_FromFormat("%S.%S()", module, qualname);
6127db96d56Sopenharmony_ci            goto done;
6137db96d56Sopenharmony_ci        }
6147db96d56Sopenharmony_ci    }
6157db96d56Sopenharmony_ci    else if (ret < 0) {
6167db96d56Sopenharmony_ci        goto done;
6177db96d56Sopenharmony_ci    }
6187db96d56Sopenharmony_ci    result = PyUnicode_FromFormat("%S()", qualname);
6197db96d56Sopenharmony_cidone:
6207db96d56Sopenharmony_ci    Py_DECREF(qualname);
6217db96d56Sopenharmony_ci    Py_XDECREF(module);
6227db96d56Sopenharmony_ci    return result;
6237db96d56Sopenharmony_ci}
6247db96d56Sopenharmony_ci
6257db96d56Sopenharmony_ci/* For Python 3.0.1 and later, the old three-way comparison has been
6267db96d56Sopenharmony_ci   completely removed in favour of rich comparisons.  PyObject_Compare() and
6277db96d56Sopenharmony_ci   PyObject_Cmp() are gone, and the builtin cmp function no longer exists.
6287db96d56Sopenharmony_ci   The old tp_compare slot has been renamed to tp_as_async, and should no
6297db96d56Sopenharmony_ci   longer be used.  Use tp_richcompare instead.
6307db96d56Sopenharmony_ci
6317db96d56Sopenharmony_ci   See (*) below for practical amendments.
6327db96d56Sopenharmony_ci
6337db96d56Sopenharmony_ci   tp_richcompare gets called with a first argument of the appropriate type
6347db96d56Sopenharmony_ci   and a second object of an arbitrary type.  We never do any kind of
6357db96d56Sopenharmony_ci   coercion.
6367db96d56Sopenharmony_ci
6377db96d56Sopenharmony_ci   The tp_richcompare slot should return an object, as follows:
6387db96d56Sopenharmony_ci
6397db96d56Sopenharmony_ci    NULL if an exception occurred
6407db96d56Sopenharmony_ci    NotImplemented if the requested comparison is not implemented
6417db96d56Sopenharmony_ci    any other false value if the requested comparison is false
6427db96d56Sopenharmony_ci    any other true value if the requested comparison is true
6437db96d56Sopenharmony_ci
6447db96d56Sopenharmony_ci  The PyObject_RichCompare[Bool]() wrappers raise TypeError when they get
6457db96d56Sopenharmony_ci  NotImplemented.
6467db96d56Sopenharmony_ci
6477db96d56Sopenharmony_ci  (*) Practical amendments:
6487db96d56Sopenharmony_ci
6497db96d56Sopenharmony_ci  - If rich comparison returns NotImplemented, == and != are decided by
6507db96d56Sopenharmony_ci    comparing the object pointer (i.e. falling back to the base object
6517db96d56Sopenharmony_ci    implementation).
6527db96d56Sopenharmony_ci
6537db96d56Sopenharmony_ci*/
6547db96d56Sopenharmony_ci
6557db96d56Sopenharmony_ci/* Map rich comparison operators to their swapped version, e.g. LT <--> GT */
6567db96d56Sopenharmony_ciint _Py_SwappedOp[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE};
6577db96d56Sopenharmony_ci
6587db96d56Sopenharmony_cistatic const char * const opstrings[] = {"<", "<=", "==", "!=", ">", ">="};
6597db96d56Sopenharmony_ci
6607db96d56Sopenharmony_ci/* Perform a rich comparison, raising TypeError when the requested comparison
6617db96d56Sopenharmony_ci   operator is not supported. */
6627db96d56Sopenharmony_cistatic PyObject *
6637db96d56Sopenharmony_cido_richcompare(PyThreadState *tstate, PyObject *v, PyObject *w, int op)
6647db96d56Sopenharmony_ci{
6657db96d56Sopenharmony_ci    richcmpfunc f;
6667db96d56Sopenharmony_ci    PyObject *res;
6677db96d56Sopenharmony_ci    int checked_reverse_op = 0;
6687db96d56Sopenharmony_ci
6697db96d56Sopenharmony_ci    if (!Py_IS_TYPE(v, Py_TYPE(w)) &&
6707db96d56Sopenharmony_ci        PyType_IsSubtype(Py_TYPE(w), Py_TYPE(v)) &&
6717db96d56Sopenharmony_ci        (f = Py_TYPE(w)->tp_richcompare) != NULL) {
6727db96d56Sopenharmony_ci        checked_reverse_op = 1;
6737db96d56Sopenharmony_ci        res = (*f)(w, v, _Py_SwappedOp[op]);
6747db96d56Sopenharmony_ci        if (res != Py_NotImplemented)
6757db96d56Sopenharmony_ci            return res;
6767db96d56Sopenharmony_ci        Py_DECREF(res);
6777db96d56Sopenharmony_ci    }
6787db96d56Sopenharmony_ci    if ((f = Py_TYPE(v)->tp_richcompare) != NULL) {
6797db96d56Sopenharmony_ci        res = (*f)(v, w, op);
6807db96d56Sopenharmony_ci        if (res != Py_NotImplemented)
6817db96d56Sopenharmony_ci            return res;
6827db96d56Sopenharmony_ci        Py_DECREF(res);
6837db96d56Sopenharmony_ci    }
6847db96d56Sopenharmony_ci    if (!checked_reverse_op && (f = Py_TYPE(w)->tp_richcompare) != NULL) {
6857db96d56Sopenharmony_ci        res = (*f)(w, v, _Py_SwappedOp[op]);
6867db96d56Sopenharmony_ci        if (res != Py_NotImplemented)
6877db96d56Sopenharmony_ci            return res;
6887db96d56Sopenharmony_ci        Py_DECREF(res);
6897db96d56Sopenharmony_ci    }
6907db96d56Sopenharmony_ci    /* If neither object implements it, provide a sensible default
6917db96d56Sopenharmony_ci       for == and !=, but raise an exception for ordering. */
6927db96d56Sopenharmony_ci    switch (op) {
6937db96d56Sopenharmony_ci    case Py_EQ:
6947db96d56Sopenharmony_ci        res = (v == w) ? Py_True : Py_False;
6957db96d56Sopenharmony_ci        break;
6967db96d56Sopenharmony_ci    case Py_NE:
6977db96d56Sopenharmony_ci        res = (v != w) ? Py_True : Py_False;
6987db96d56Sopenharmony_ci        break;
6997db96d56Sopenharmony_ci    default:
7007db96d56Sopenharmony_ci        _PyErr_Format(tstate, PyExc_TypeError,
7017db96d56Sopenharmony_ci                      "'%s' not supported between instances of '%.100s' and '%.100s'",
7027db96d56Sopenharmony_ci                      opstrings[op],
7037db96d56Sopenharmony_ci                      Py_TYPE(v)->tp_name,
7047db96d56Sopenharmony_ci                      Py_TYPE(w)->tp_name);
7057db96d56Sopenharmony_ci        return NULL;
7067db96d56Sopenharmony_ci    }
7077db96d56Sopenharmony_ci    Py_INCREF(res);
7087db96d56Sopenharmony_ci    return res;
7097db96d56Sopenharmony_ci}
7107db96d56Sopenharmony_ci
7117db96d56Sopenharmony_ci/* Perform a rich comparison with object result.  This wraps do_richcompare()
7127db96d56Sopenharmony_ci   with a check for NULL arguments and a recursion check. */
7137db96d56Sopenharmony_ci
7147db96d56Sopenharmony_ciPyObject *
7157db96d56Sopenharmony_ciPyObject_RichCompare(PyObject *v, PyObject *w, int op)
7167db96d56Sopenharmony_ci{
7177db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
7187db96d56Sopenharmony_ci
7197db96d56Sopenharmony_ci    assert(Py_LT <= op && op <= Py_GE);
7207db96d56Sopenharmony_ci    if (v == NULL || w == NULL) {
7217db96d56Sopenharmony_ci        if (!_PyErr_Occurred(tstate)) {
7227db96d56Sopenharmony_ci            PyErr_BadInternalCall();
7237db96d56Sopenharmony_ci        }
7247db96d56Sopenharmony_ci        return NULL;
7257db96d56Sopenharmony_ci    }
7267db96d56Sopenharmony_ci    if (_Py_EnterRecursiveCallTstate(tstate, " in comparison")) {
7277db96d56Sopenharmony_ci        return NULL;
7287db96d56Sopenharmony_ci    }
7297db96d56Sopenharmony_ci    PyObject *res = do_richcompare(tstate, v, w, op);
7307db96d56Sopenharmony_ci    _Py_LeaveRecursiveCallTstate(tstate);
7317db96d56Sopenharmony_ci    return res;
7327db96d56Sopenharmony_ci}
7337db96d56Sopenharmony_ci
7347db96d56Sopenharmony_ci/* Perform a rich comparison with integer result.  This wraps
7357db96d56Sopenharmony_ci   PyObject_RichCompare(), returning -1 for error, 0 for false, 1 for true. */
7367db96d56Sopenharmony_ciint
7377db96d56Sopenharmony_ciPyObject_RichCompareBool(PyObject *v, PyObject *w, int op)
7387db96d56Sopenharmony_ci{
7397db96d56Sopenharmony_ci    PyObject *res;
7407db96d56Sopenharmony_ci    int ok;
7417db96d56Sopenharmony_ci
7427db96d56Sopenharmony_ci    /* Quick result when objects are the same.
7437db96d56Sopenharmony_ci       Guarantees that identity implies equality. */
7447db96d56Sopenharmony_ci    if (v == w) {
7457db96d56Sopenharmony_ci        if (op == Py_EQ)
7467db96d56Sopenharmony_ci            return 1;
7477db96d56Sopenharmony_ci        else if (op == Py_NE)
7487db96d56Sopenharmony_ci            return 0;
7497db96d56Sopenharmony_ci    }
7507db96d56Sopenharmony_ci
7517db96d56Sopenharmony_ci    res = PyObject_RichCompare(v, w, op);
7527db96d56Sopenharmony_ci    if (res == NULL)
7537db96d56Sopenharmony_ci        return -1;
7547db96d56Sopenharmony_ci    if (PyBool_Check(res))
7557db96d56Sopenharmony_ci        ok = (res == Py_True);
7567db96d56Sopenharmony_ci    else
7577db96d56Sopenharmony_ci        ok = PyObject_IsTrue(res);
7587db96d56Sopenharmony_ci    Py_DECREF(res);
7597db96d56Sopenharmony_ci    return ok;
7607db96d56Sopenharmony_ci}
7617db96d56Sopenharmony_ci
7627db96d56Sopenharmony_ciPy_hash_t
7637db96d56Sopenharmony_ciPyObject_HashNotImplemented(PyObject *v)
7647db96d56Sopenharmony_ci{
7657db96d56Sopenharmony_ci    PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'",
7667db96d56Sopenharmony_ci                 Py_TYPE(v)->tp_name);
7677db96d56Sopenharmony_ci    return -1;
7687db96d56Sopenharmony_ci}
7697db96d56Sopenharmony_ci
7707db96d56Sopenharmony_ciPy_hash_t
7717db96d56Sopenharmony_ciPyObject_Hash(PyObject *v)
7727db96d56Sopenharmony_ci{
7737db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(v);
7747db96d56Sopenharmony_ci    if (tp->tp_hash != NULL)
7757db96d56Sopenharmony_ci        return (*tp->tp_hash)(v);
7767db96d56Sopenharmony_ci    /* To keep to the general practice that inheriting
7777db96d56Sopenharmony_ci     * solely from object in C code should work without
7787db96d56Sopenharmony_ci     * an explicit call to PyType_Ready, we implicitly call
7797db96d56Sopenharmony_ci     * PyType_Ready here and then check the tp_hash slot again
7807db96d56Sopenharmony_ci     */
7817db96d56Sopenharmony_ci    if (tp->tp_dict == NULL) {
7827db96d56Sopenharmony_ci        if (PyType_Ready(tp) < 0)
7837db96d56Sopenharmony_ci            return -1;
7847db96d56Sopenharmony_ci        if (tp->tp_hash != NULL)
7857db96d56Sopenharmony_ci            return (*tp->tp_hash)(v);
7867db96d56Sopenharmony_ci    }
7877db96d56Sopenharmony_ci    /* Otherwise, the object can't be hashed */
7887db96d56Sopenharmony_ci    return PyObject_HashNotImplemented(v);
7897db96d56Sopenharmony_ci}
7907db96d56Sopenharmony_ci
7917db96d56Sopenharmony_ciPyObject *
7927db96d56Sopenharmony_ciPyObject_GetAttrString(PyObject *v, const char *name)
7937db96d56Sopenharmony_ci{
7947db96d56Sopenharmony_ci    PyObject *w, *res;
7957db96d56Sopenharmony_ci
7967db96d56Sopenharmony_ci    if (Py_TYPE(v)->tp_getattr != NULL)
7977db96d56Sopenharmony_ci        return (*Py_TYPE(v)->tp_getattr)(v, (char*)name);
7987db96d56Sopenharmony_ci    w = PyUnicode_FromString(name);
7997db96d56Sopenharmony_ci    if (w == NULL)
8007db96d56Sopenharmony_ci        return NULL;
8017db96d56Sopenharmony_ci    res = PyObject_GetAttr(v, w);
8027db96d56Sopenharmony_ci    Py_DECREF(w);
8037db96d56Sopenharmony_ci    return res;
8047db96d56Sopenharmony_ci}
8057db96d56Sopenharmony_ci
8067db96d56Sopenharmony_ciint
8077db96d56Sopenharmony_ciPyObject_HasAttrString(PyObject *v, const char *name)
8087db96d56Sopenharmony_ci{
8097db96d56Sopenharmony_ci    PyObject *res = PyObject_GetAttrString(v, name);
8107db96d56Sopenharmony_ci    if (res != NULL) {
8117db96d56Sopenharmony_ci        Py_DECREF(res);
8127db96d56Sopenharmony_ci        return 1;
8137db96d56Sopenharmony_ci    }
8147db96d56Sopenharmony_ci    PyErr_Clear();
8157db96d56Sopenharmony_ci    return 0;
8167db96d56Sopenharmony_ci}
8177db96d56Sopenharmony_ci
8187db96d56Sopenharmony_ciint
8197db96d56Sopenharmony_ciPyObject_SetAttrString(PyObject *v, const char *name, PyObject *w)
8207db96d56Sopenharmony_ci{
8217db96d56Sopenharmony_ci    PyObject *s;
8227db96d56Sopenharmony_ci    int res;
8237db96d56Sopenharmony_ci
8247db96d56Sopenharmony_ci    if (Py_TYPE(v)->tp_setattr != NULL)
8257db96d56Sopenharmony_ci        return (*Py_TYPE(v)->tp_setattr)(v, (char*)name, w);
8267db96d56Sopenharmony_ci    s = PyUnicode_InternFromString(name);
8277db96d56Sopenharmony_ci    if (s == NULL)
8287db96d56Sopenharmony_ci        return -1;
8297db96d56Sopenharmony_ci    res = PyObject_SetAttr(v, s, w);
8307db96d56Sopenharmony_ci    Py_XDECREF(s);
8317db96d56Sopenharmony_ci    return res;
8327db96d56Sopenharmony_ci}
8337db96d56Sopenharmony_ci
8347db96d56Sopenharmony_ciint
8357db96d56Sopenharmony_ci_PyObject_IsAbstract(PyObject *obj)
8367db96d56Sopenharmony_ci{
8377db96d56Sopenharmony_ci    int res;
8387db96d56Sopenharmony_ci    PyObject* isabstract;
8397db96d56Sopenharmony_ci
8407db96d56Sopenharmony_ci    if (obj == NULL)
8417db96d56Sopenharmony_ci        return 0;
8427db96d56Sopenharmony_ci
8437db96d56Sopenharmony_ci    res = _PyObject_LookupAttr(obj, &_Py_ID(__isabstractmethod__), &isabstract);
8447db96d56Sopenharmony_ci    if (res > 0) {
8457db96d56Sopenharmony_ci        res = PyObject_IsTrue(isabstract);
8467db96d56Sopenharmony_ci        Py_DECREF(isabstract);
8477db96d56Sopenharmony_ci    }
8487db96d56Sopenharmony_ci    return res;
8497db96d56Sopenharmony_ci}
8507db96d56Sopenharmony_ci
8517db96d56Sopenharmony_ciPyObject *
8527db96d56Sopenharmony_ci_PyObject_GetAttrId(PyObject *v, _Py_Identifier *name)
8537db96d56Sopenharmony_ci{
8547db96d56Sopenharmony_ci    PyObject *result;
8557db96d56Sopenharmony_ci    PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
8567db96d56Sopenharmony_ci    if (!oname)
8577db96d56Sopenharmony_ci        return NULL;
8587db96d56Sopenharmony_ci    result = PyObject_GetAttr(v, oname);
8597db96d56Sopenharmony_ci    return result;
8607db96d56Sopenharmony_ci}
8617db96d56Sopenharmony_ci
8627db96d56Sopenharmony_ciint
8637db96d56Sopenharmony_ci_PyObject_SetAttrId(PyObject *v, _Py_Identifier *name, PyObject *w)
8647db96d56Sopenharmony_ci{
8657db96d56Sopenharmony_ci    int result;
8667db96d56Sopenharmony_ci    PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
8677db96d56Sopenharmony_ci    if (!oname)
8687db96d56Sopenharmony_ci        return -1;
8697db96d56Sopenharmony_ci    result = PyObject_SetAttr(v, oname, w);
8707db96d56Sopenharmony_ci    return result;
8717db96d56Sopenharmony_ci}
8727db96d56Sopenharmony_ci
8737db96d56Sopenharmony_cistatic inline int
8747db96d56Sopenharmony_ciset_attribute_error_context(PyObject* v, PyObject* name)
8757db96d56Sopenharmony_ci{
8767db96d56Sopenharmony_ci    assert(PyErr_Occurred());
8777db96d56Sopenharmony_ci    if (!PyErr_ExceptionMatches(PyExc_AttributeError)){
8787db96d56Sopenharmony_ci        return 0;
8797db96d56Sopenharmony_ci    }
8807db96d56Sopenharmony_ci    // Intercept AttributeError exceptions and augment them to offer suggestions later.
8817db96d56Sopenharmony_ci    PyObject *type, *value, *traceback;
8827db96d56Sopenharmony_ci    PyErr_Fetch(&type, &value, &traceback);
8837db96d56Sopenharmony_ci    PyErr_NormalizeException(&type, &value, &traceback);
8847db96d56Sopenharmony_ci    // Check if the normalized exception is indeed an AttributeError
8857db96d56Sopenharmony_ci    if (!PyErr_GivenExceptionMatches(value, PyExc_AttributeError)) {
8867db96d56Sopenharmony_ci        goto restore;
8877db96d56Sopenharmony_ci    }
8887db96d56Sopenharmony_ci    PyAttributeErrorObject* the_exc = (PyAttributeErrorObject*) value;
8897db96d56Sopenharmony_ci    // Check if this exception was already augmented
8907db96d56Sopenharmony_ci    if (the_exc->name || the_exc->obj) {
8917db96d56Sopenharmony_ci        goto restore;
8927db96d56Sopenharmony_ci    }
8937db96d56Sopenharmony_ci    // Augment the exception with the name and object
8947db96d56Sopenharmony_ci    if (PyObject_SetAttr(value, &_Py_ID(name), name) ||
8957db96d56Sopenharmony_ci        PyObject_SetAttr(value, &_Py_ID(obj), v)) {
8967db96d56Sopenharmony_ci        return 1;
8977db96d56Sopenharmony_ci    }
8987db96d56Sopenharmony_cirestore:
8997db96d56Sopenharmony_ci    PyErr_Restore(type, value, traceback);
9007db96d56Sopenharmony_ci    return 0;
9017db96d56Sopenharmony_ci}
9027db96d56Sopenharmony_ci
9037db96d56Sopenharmony_ciPyObject *
9047db96d56Sopenharmony_ciPyObject_GetAttr(PyObject *v, PyObject *name)
9057db96d56Sopenharmony_ci{
9067db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(v);
9077db96d56Sopenharmony_ci    if (!PyUnicode_Check(name)) {
9087db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
9097db96d56Sopenharmony_ci                     "attribute name must be string, not '%.200s'",
9107db96d56Sopenharmony_ci                     Py_TYPE(name)->tp_name);
9117db96d56Sopenharmony_ci        return NULL;
9127db96d56Sopenharmony_ci    }
9137db96d56Sopenharmony_ci
9147db96d56Sopenharmony_ci    PyObject* result = NULL;
9157db96d56Sopenharmony_ci    if (tp->tp_getattro != NULL) {
9167db96d56Sopenharmony_ci        result = (*tp->tp_getattro)(v, name);
9177db96d56Sopenharmony_ci    }
9187db96d56Sopenharmony_ci    else if (tp->tp_getattr != NULL) {
9197db96d56Sopenharmony_ci        const char *name_str = PyUnicode_AsUTF8(name);
9207db96d56Sopenharmony_ci        if (name_str == NULL) {
9217db96d56Sopenharmony_ci            return NULL;
9227db96d56Sopenharmony_ci        }
9237db96d56Sopenharmony_ci        result = (*tp->tp_getattr)(v, (char *)name_str);
9247db96d56Sopenharmony_ci    }
9257db96d56Sopenharmony_ci    else {
9267db96d56Sopenharmony_ci        PyErr_Format(PyExc_AttributeError,
9277db96d56Sopenharmony_ci                    "'%.50s' object has no attribute '%U'",
9287db96d56Sopenharmony_ci                    tp->tp_name, name);
9297db96d56Sopenharmony_ci    }
9307db96d56Sopenharmony_ci
9317db96d56Sopenharmony_ci    if (result == NULL) {
9327db96d56Sopenharmony_ci        set_attribute_error_context(v, name);
9337db96d56Sopenharmony_ci    }
9347db96d56Sopenharmony_ci    return result;
9357db96d56Sopenharmony_ci}
9367db96d56Sopenharmony_ci
9377db96d56Sopenharmony_ciint
9387db96d56Sopenharmony_ci_PyObject_LookupAttr(PyObject *v, PyObject *name, PyObject **result)
9397db96d56Sopenharmony_ci{
9407db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(v);
9417db96d56Sopenharmony_ci
9427db96d56Sopenharmony_ci    if (!PyUnicode_Check(name)) {
9437db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
9447db96d56Sopenharmony_ci                     "attribute name must be string, not '%.200s'",
9457db96d56Sopenharmony_ci                     Py_TYPE(name)->tp_name);
9467db96d56Sopenharmony_ci        *result = NULL;
9477db96d56Sopenharmony_ci        return -1;
9487db96d56Sopenharmony_ci    }
9497db96d56Sopenharmony_ci
9507db96d56Sopenharmony_ci    if (tp->tp_getattro == PyObject_GenericGetAttr) {
9517db96d56Sopenharmony_ci        *result = _PyObject_GenericGetAttrWithDict(v, name, NULL, 1);
9527db96d56Sopenharmony_ci        if (*result != NULL) {
9537db96d56Sopenharmony_ci            return 1;
9547db96d56Sopenharmony_ci        }
9557db96d56Sopenharmony_ci        if (PyErr_Occurred()) {
9567db96d56Sopenharmony_ci            return -1;
9577db96d56Sopenharmony_ci        }
9587db96d56Sopenharmony_ci        return 0;
9597db96d56Sopenharmony_ci    }
9607db96d56Sopenharmony_ci    if (tp->tp_getattro != NULL) {
9617db96d56Sopenharmony_ci        *result = (*tp->tp_getattro)(v, name);
9627db96d56Sopenharmony_ci    }
9637db96d56Sopenharmony_ci    else if (tp->tp_getattr != NULL) {
9647db96d56Sopenharmony_ci        const char *name_str = PyUnicode_AsUTF8(name);
9657db96d56Sopenharmony_ci        if (name_str == NULL) {
9667db96d56Sopenharmony_ci            *result = NULL;
9677db96d56Sopenharmony_ci            return -1;
9687db96d56Sopenharmony_ci        }
9697db96d56Sopenharmony_ci        *result = (*tp->tp_getattr)(v, (char *)name_str);
9707db96d56Sopenharmony_ci    }
9717db96d56Sopenharmony_ci    else {
9727db96d56Sopenharmony_ci        *result = NULL;
9737db96d56Sopenharmony_ci        return 0;
9747db96d56Sopenharmony_ci    }
9757db96d56Sopenharmony_ci
9767db96d56Sopenharmony_ci    if (*result != NULL) {
9777db96d56Sopenharmony_ci        return 1;
9787db96d56Sopenharmony_ci    }
9797db96d56Sopenharmony_ci    if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
9807db96d56Sopenharmony_ci        return -1;
9817db96d56Sopenharmony_ci    }
9827db96d56Sopenharmony_ci    PyErr_Clear();
9837db96d56Sopenharmony_ci    return 0;
9847db96d56Sopenharmony_ci}
9857db96d56Sopenharmony_ci
9867db96d56Sopenharmony_ciint
9877db96d56Sopenharmony_ci_PyObject_LookupAttrId(PyObject *v, _Py_Identifier *name, PyObject **result)
9887db96d56Sopenharmony_ci{
9897db96d56Sopenharmony_ci    PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
9907db96d56Sopenharmony_ci    if (!oname) {
9917db96d56Sopenharmony_ci        *result = NULL;
9927db96d56Sopenharmony_ci        return -1;
9937db96d56Sopenharmony_ci    }
9947db96d56Sopenharmony_ci    return  _PyObject_LookupAttr(v, oname, result);
9957db96d56Sopenharmony_ci}
9967db96d56Sopenharmony_ci
9977db96d56Sopenharmony_ciint
9987db96d56Sopenharmony_ciPyObject_HasAttr(PyObject *v, PyObject *name)
9997db96d56Sopenharmony_ci{
10007db96d56Sopenharmony_ci    PyObject *res;
10017db96d56Sopenharmony_ci    if (_PyObject_LookupAttr(v, name, &res) < 0) {
10027db96d56Sopenharmony_ci        PyErr_Clear();
10037db96d56Sopenharmony_ci        return 0;
10047db96d56Sopenharmony_ci    }
10057db96d56Sopenharmony_ci    if (res == NULL) {
10067db96d56Sopenharmony_ci        return 0;
10077db96d56Sopenharmony_ci    }
10087db96d56Sopenharmony_ci    Py_DECREF(res);
10097db96d56Sopenharmony_ci    return 1;
10107db96d56Sopenharmony_ci}
10117db96d56Sopenharmony_ci
10127db96d56Sopenharmony_ciint
10137db96d56Sopenharmony_ciPyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
10147db96d56Sopenharmony_ci{
10157db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(v);
10167db96d56Sopenharmony_ci    int err;
10177db96d56Sopenharmony_ci
10187db96d56Sopenharmony_ci    if (!PyUnicode_Check(name)) {
10197db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
10207db96d56Sopenharmony_ci                     "attribute name must be string, not '%.200s'",
10217db96d56Sopenharmony_ci                     Py_TYPE(name)->tp_name);
10227db96d56Sopenharmony_ci        return -1;
10237db96d56Sopenharmony_ci    }
10247db96d56Sopenharmony_ci    Py_INCREF(name);
10257db96d56Sopenharmony_ci
10267db96d56Sopenharmony_ci    PyUnicode_InternInPlace(&name);
10277db96d56Sopenharmony_ci    if (tp->tp_setattro != NULL) {
10287db96d56Sopenharmony_ci        err = (*tp->tp_setattro)(v, name, value);
10297db96d56Sopenharmony_ci        Py_DECREF(name);
10307db96d56Sopenharmony_ci        return err;
10317db96d56Sopenharmony_ci    }
10327db96d56Sopenharmony_ci    if (tp->tp_setattr != NULL) {
10337db96d56Sopenharmony_ci        const char *name_str = PyUnicode_AsUTF8(name);
10347db96d56Sopenharmony_ci        if (name_str == NULL) {
10357db96d56Sopenharmony_ci            Py_DECREF(name);
10367db96d56Sopenharmony_ci            return -1;
10377db96d56Sopenharmony_ci        }
10387db96d56Sopenharmony_ci        err = (*tp->tp_setattr)(v, (char *)name_str, value);
10397db96d56Sopenharmony_ci        Py_DECREF(name);
10407db96d56Sopenharmony_ci        return err;
10417db96d56Sopenharmony_ci    }
10427db96d56Sopenharmony_ci    Py_DECREF(name);
10437db96d56Sopenharmony_ci    _PyObject_ASSERT(name, Py_REFCNT(name) >= 1);
10447db96d56Sopenharmony_ci    if (tp->tp_getattr == NULL && tp->tp_getattro == NULL)
10457db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
10467db96d56Sopenharmony_ci                     "'%.100s' object has no attributes "
10477db96d56Sopenharmony_ci                     "(%s .%U)",
10487db96d56Sopenharmony_ci                     tp->tp_name,
10497db96d56Sopenharmony_ci                     value==NULL ? "del" : "assign to",
10507db96d56Sopenharmony_ci                     name);
10517db96d56Sopenharmony_ci    else
10527db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
10537db96d56Sopenharmony_ci                     "'%.100s' object has only read-only attributes "
10547db96d56Sopenharmony_ci                     "(%s .%U)",
10557db96d56Sopenharmony_ci                     tp->tp_name,
10567db96d56Sopenharmony_ci                     value==NULL ? "del" : "assign to",
10577db96d56Sopenharmony_ci                     name);
10587db96d56Sopenharmony_ci    return -1;
10597db96d56Sopenharmony_ci}
10607db96d56Sopenharmony_ci
10617db96d56Sopenharmony_ciPyObject **
10627db96d56Sopenharmony_ci_PyObject_DictPointer(PyObject *obj)
10637db96d56Sopenharmony_ci{
10647db96d56Sopenharmony_ci    Py_ssize_t dictoffset;
10657db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(obj);
10667db96d56Sopenharmony_ci
10677db96d56Sopenharmony_ci    if (tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) {
10687db96d56Sopenharmony_ci        return _PyObject_ManagedDictPointer(obj);
10697db96d56Sopenharmony_ci    }
10707db96d56Sopenharmony_ci    dictoffset = tp->tp_dictoffset;
10717db96d56Sopenharmony_ci    if (dictoffset == 0)
10727db96d56Sopenharmony_ci        return NULL;
10737db96d56Sopenharmony_ci    if (dictoffset < 0) {
10747db96d56Sopenharmony_ci        Py_ssize_t tsize = Py_SIZE(obj);
10757db96d56Sopenharmony_ci        if (tsize < 0) {
10767db96d56Sopenharmony_ci            tsize = -tsize;
10777db96d56Sopenharmony_ci        }
10787db96d56Sopenharmony_ci        size_t size = _PyObject_VAR_SIZE(tp, tsize);
10797db96d56Sopenharmony_ci        assert(size <= (size_t)PY_SSIZE_T_MAX);
10807db96d56Sopenharmony_ci        dictoffset += (Py_ssize_t)size;
10817db96d56Sopenharmony_ci
10827db96d56Sopenharmony_ci        _PyObject_ASSERT(obj, dictoffset > 0);
10837db96d56Sopenharmony_ci        _PyObject_ASSERT(obj, dictoffset % SIZEOF_VOID_P == 0);
10847db96d56Sopenharmony_ci    }
10857db96d56Sopenharmony_ci    return (PyObject **) ((char *)obj + dictoffset);
10867db96d56Sopenharmony_ci}
10877db96d56Sopenharmony_ci
10887db96d56Sopenharmony_ci/* Helper to get a pointer to an object's __dict__ slot, if any.
10897db96d56Sopenharmony_ci * Creates the dict from inline attributes if necessary.
10907db96d56Sopenharmony_ci * Does not set an exception.
10917db96d56Sopenharmony_ci *
10927db96d56Sopenharmony_ci * Note that the tp_dictoffset docs used to recommend this function,
10937db96d56Sopenharmony_ci * so it should be treated as part of the public API.
10947db96d56Sopenharmony_ci */
10957db96d56Sopenharmony_ciPyObject **
10967db96d56Sopenharmony_ci_PyObject_GetDictPtr(PyObject *obj)
10977db96d56Sopenharmony_ci{
10987db96d56Sopenharmony_ci    if ((Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) {
10997db96d56Sopenharmony_ci        return _PyObject_DictPointer(obj);
11007db96d56Sopenharmony_ci    }
11017db96d56Sopenharmony_ci    PyObject **dict_ptr = _PyObject_ManagedDictPointer(obj);
11027db96d56Sopenharmony_ci    PyDictValues **values_ptr = _PyObject_ValuesPointer(obj);
11037db96d56Sopenharmony_ci    if (*values_ptr == NULL) {
11047db96d56Sopenharmony_ci        return dict_ptr;
11057db96d56Sopenharmony_ci    }
11067db96d56Sopenharmony_ci    assert(*dict_ptr == NULL);
11077db96d56Sopenharmony_ci    PyObject *dict = _PyObject_MakeDictFromInstanceAttributes(obj, *values_ptr);
11087db96d56Sopenharmony_ci    if (dict == NULL) {
11097db96d56Sopenharmony_ci        PyErr_Clear();
11107db96d56Sopenharmony_ci        return NULL;
11117db96d56Sopenharmony_ci    }
11127db96d56Sopenharmony_ci    *values_ptr = NULL;
11137db96d56Sopenharmony_ci    *dict_ptr = dict;
11147db96d56Sopenharmony_ci    return dict_ptr;
11157db96d56Sopenharmony_ci}
11167db96d56Sopenharmony_ci
11177db96d56Sopenharmony_ciPyObject *
11187db96d56Sopenharmony_ciPyObject_SelfIter(PyObject *obj)
11197db96d56Sopenharmony_ci{
11207db96d56Sopenharmony_ci    Py_INCREF(obj);
11217db96d56Sopenharmony_ci    return obj;
11227db96d56Sopenharmony_ci}
11237db96d56Sopenharmony_ci
11247db96d56Sopenharmony_ci/* Helper used when the __next__ method is removed from a type:
11257db96d56Sopenharmony_ci   tp_iternext is never NULL and can be safely called without checking
11267db96d56Sopenharmony_ci   on every iteration.
11277db96d56Sopenharmony_ci */
11287db96d56Sopenharmony_ci
11297db96d56Sopenharmony_ciPyObject *
11307db96d56Sopenharmony_ci_PyObject_NextNotImplemented(PyObject *self)
11317db96d56Sopenharmony_ci{
11327db96d56Sopenharmony_ci    PyErr_Format(PyExc_TypeError,
11337db96d56Sopenharmony_ci                 "'%.200s' object is not iterable",
11347db96d56Sopenharmony_ci                 Py_TYPE(self)->tp_name);
11357db96d56Sopenharmony_ci    return NULL;
11367db96d56Sopenharmony_ci}
11377db96d56Sopenharmony_ci
11387db96d56Sopenharmony_ci
11397db96d56Sopenharmony_ci/* Specialized version of _PyObject_GenericGetAttrWithDict
11407db96d56Sopenharmony_ci   specifically for the LOAD_METHOD opcode.
11417db96d56Sopenharmony_ci
11427db96d56Sopenharmony_ci   Return 1 if a method is found, 0 if it's a regular attribute
11437db96d56Sopenharmony_ci   from __dict__ or something returned by using a descriptor
11447db96d56Sopenharmony_ci   protocol.
11457db96d56Sopenharmony_ci
11467db96d56Sopenharmony_ci   `method` will point to the resolved attribute or NULL.  In the
11477db96d56Sopenharmony_ci   latter case, an error will be set.
11487db96d56Sopenharmony_ci*/
11497db96d56Sopenharmony_ciint
11507db96d56Sopenharmony_ci_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method)
11517db96d56Sopenharmony_ci{
11527db96d56Sopenharmony_ci    int meth_found = 0;
11537db96d56Sopenharmony_ci
11547db96d56Sopenharmony_ci    assert(*method == NULL);
11557db96d56Sopenharmony_ci
11567db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(obj);
11577db96d56Sopenharmony_ci    if (!_PyType_IsReady(tp)) {
11587db96d56Sopenharmony_ci        if (PyType_Ready(tp) < 0) {
11597db96d56Sopenharmony_ci            return 0;
11607db96d56Sopenharmony_ci        }
11617db96d56Sopenharmony_ci    }
11627db96d56Sopenharmony_ci
11637db96d56Sopenharmony_ci    if (tp->tp_getattro != PyObject_GenericGetAttr || !PyUnicode_CheckExact(name)) {
11647db96d56Sopenharmony_ci        *method = PyObject_GetAttr(obj, name);
11657db96d56Sopenharmony_ci        return 0;
11667db96d56Sopenharmony_ci    }
11677db96d56Sopenharmony_ci
11687db96d56Sopenharmony_ci    PyObject *descr = _PyType_Lookup(tp, name);
11697db96d56Sopenharmony_ci    descrgetfunc f = NULL;
11707db96d56Sopenharmony_ci    if (descr != NULL) {
11717db96d56Sopenharmony_ci        Py_INCREF(descr);
11727db96d56Sopenharmony_ci        if (_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) {
11737db96d56Sopenharmony_ci            meth_found = 1;
11747db96d56Sopenharmony_ci        } else {
11757db96d56Sopenharmony_ci            f = Py_TYPE(descr)->tp_descr_get;
11767db96d56Sopenharmony_ci            if (f != NULL && PyDescr_IsData(descr)) {
11777db96d56Sopenharmony_ci                *method = f(descr, obj, (PyObject *)Py_TYPE(obj));
11787db96d56Sopenharmony_ci                Py_DECREF(descr);
11797db96d56Sopenharmony_ci                return 0;
11807db96d56Sopenharmony_ci            }
11817db96d56Sopenharmony_ci        }
11827db96d56Sopenharmony_ci    }
11837db96d56Sopenharmony_ci    PyDictValues *values;
11847db96d56Sopenharmony_ci    if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) &&
11857db96d56Sopenharmony_ci        (values = *_PyObject_ValuesPointer(obj)))
11867db96d56Sopenharmony_ci    {
11877db96d56Sopenharmony_ci        assert(*_PyObject_DictPointer(obj) == NULL);
11887db96d56Sopenharmony_ci        PyObject *attr = _PyObject_GetInstanceAttribute(obj, values, name);
11897db96d56Sopenharmony_ci        if (attr != NULL) {
11907db96d56Sopenharmony_ci            *method = attr;
11917db96d56Sopenharmony_ci            Py_XDECREF(descr);
11927db96d56Sopenharmony_ci            return 0;
11937db96d56Sopenharmony_ci        }
11947db96d56Sopenharmony_ci    }
11957db96d56Sopenharmony_ci    else {
11967db96d56Sopenharmony_ci        PyObject **dictptr = _PyObject_DictPointer(obj);
11977db96d56Sopenharmony_ci        PyObject *dict;
11987db96d56Sopenharmony_ci        if (dictptr != NULL && (dict = *dictptr) != NULL) {
11997db96d56Sopenharmony_ci            Py_INCREF(dict);
12007db96d56Sopenharmony_ci            PyObject *attr = PyDict_GetItemWithError(dict, name);
12017db96d56Sopenharmony_ci            if (attr != NULL) {
12027db96d56Sopenharmony_ci                *method = Py_NewRef(attr);
12037db96d56Sopenharmony_ci                Py_DECREF(dict);
12047db96d56Sopenharmony_ci                Py_XDECREF(descr);
12057db96d56Sopenharmony_ci                return 0;
12067db96d56Sopenharmony_ci            }
12077db96d56Sopenharmony_ci            Py_DECREF(dict);
12087db96d56Sopenharmony_ci
12097db96d56Sopenharmony_ci            if (PyErr_Occurred()) {
12107db96d56Sopenharmony_ci                Py_XDECREF(descr);
12117db96d56Sopenharmony_ci                return 0;
12127db96d56Sopenharmony_ci            }
12137db96d56Sopenharmony_ci        }
12147db96d56Sopenharmony_ci    }
12157db96d56Sopenharmony_ci
12167db96d56Sopenharmony_ci    if (meth_found) {
12177db96d56Sopenharmony_ci        *method = descr;
12187db96d56Sopenharmony_ci        return 1;
12197db96d56Sopenharmony_ci    }
12207db96d56Sopenharmony_ci
12217db96d56Sopenharmony_ci    if (f != NULL) {
12227db96d56Sopenharmony_ci        *method = f(descr, obj, (PyObject *)Py_TYPE(obj));
12237db96d56Sopenharmony_ci        Py_DECREF(descr);
12247db96d56Sopenharmony_ci        return 0;
12257db96d56Sopenharmony_ci    }
12267db96d56Sopenharmony_ci
12277db96d56Sopenharmony_ci    if (descr != NULL) {
12287db96d56Sopenharmony_ci        *method = descr;
12297db96d56Sopenharmony_ci        return 0;
12307db96d56Sopenharmony_ci    }
12317db96d56Sopenharmony_ci
12327db96d56Sopenharmony_ci    PyErr_Format(PyExc_AttributeError,
12337db96d56Sopenharmony_ci                 "'%.50s' object has no attribute '%U'",
12347db96d56Sopenharmony_ci                 tp->tp_name, name);
12357db96d56Sopenharmony_ci
12367db96d56Sopenharmony_ci    set_attribute_error_context(obj, name);
12377db96d56Sopenharmony_ci    return 0;
12387db96d56Sopenharmony_ci}
12397db96d56Sopenharmony_ci
12407db96d56Sopenharmony_ci/* Generic GetAttr functions - put these in your tp_[gs]etattro slot. */
12417db96d56Sopenharmony_ci
12427db96d56Sopenharmony_ciPyObject *
12437db96d56Sopenharmony_ci_PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name,
12447db96d56Sopenharmony_ci                                 PyObject *dict, int suppress)
12457db96d56Sopenharmony_ci{
12467db96d56Sopenharmony_ci    /* Make sure the logic of _PyObject_GetMethod is in sync with
12477db96d56Sopenharmony_ci       this method.
12487db96d56Sopenharmony_ci
12497db96d56Sopenharmony_ci       When suppress=1, this function suppresses AttributeError.
12507db96d56Sopenharmony_ci    */
12517db96d56Sopenharmony_ci
12527db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(obj);
12537db96d56Sopenharmony_ci    PyObject *descr = NULL;
12547db96d56Sopenharmony_ci    PyObject *res = NULL;
12557db96d56Sopenharmony_ci    descrgetfunc f;
12567db96d56Sopenharmony_ci    PyObject **dictptr;
12577db96d56Sopenharmony_ci
12587db96d56Sopenharmony_ci    if (!PyUnicode_Check(name)){
12597db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
12607db96d56Sopenharmony_ci                     "attribute name must be string, not '%.200s'",
12617db96d56Sopenharmony_ci                     Py_TYPE(name)->tp_name);
12627db96d56Sopenharmony_ci        return NULL;
12637db96d56Sopenharmony_ci    }
12647db96d56Sopenharmony_ci    Py_INCREF(name);
12657db96d56Sopenharmony_ci
12667db96d56Sopenharmony_ci    if (tp->tp_dict == NULL) {
12677db96d56Sopenharmony_ci        if (PyType_Ready(tp) < 0)
12687db96d56Sopenharmony_ci            goto done;
12697db96d56Sopenharmony_ci    }
12707db96d56Sopenharmony_ci
12717db96d56Sopenharmony_ci    descr = _PyType_Lookup(tp, name);
12727db96d56Sopenharmony_ci
12737db96d56Sopenharmony_ci    f = NULL;
12747db96d56Sopenharmony_ci    if (descr != NULL) {
12757db96d56Sopenharmony_ci        Py_INCREF(descr);
12767db96d56Sopenharmony_ci        f = Py_TYPE(descr)->tp_descr_get;
12777db96d56Sopenharmony_ci        if (f != NULL && PyDescr_IsData(descr)) {
12787db96d56Sopenharmony_ci            res = f(descr, obj, (PyObject *)Py_TYPE(obj));
12797db96d56Sopenharmony_ci            if (res == NULL && suppress &&
12807db96d56Sopenharmony_ci                    PyErr_ExceptionMatches(PyExc_AttributeError)) {
12817db96d56Sopenharmony_ci                PyErr_Clear();
12827db96d56Sopenharmony_ci            }
12837db96d56Sopenharmony_ci            goto done;
12847db96d56Sopenharmony_ci        }
12857db96d56Sopenharmony_ci    }
12867db96d56Sopenharmony_ci    if (dict == NULL) {
12877db96d56Sopenharmony_ci        if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) &&
12887db96d56Sopenharmony_ci            *_PyObject_ValuesPointer(obj))
12897db96d56Sopenharmony_ci        {
12907db96d56Sopenharmony_ci            PyDictValues **values_ptr = _PyObject_ValuesPointer(obj);
12917db96d56Sopenharmony_ci            if (PyUnicode_CheckExact(name)) {
12927db96d56Sopenharmony_ci                assert(*_PyObject_DictPointer(obj) == NULL);
12937db96d56Sopenharmony_ci                res = _PyObject_GetInstanceAttribute(obj, *values_ptr, name);
12947db96d56Sopenharmony_ci                if (res != NULL) {
12957db96d56Sopenharmony_ci                    goto done;
12967db96d56Sopenharmony_ci                }
12977db96d56Sopenharmony_ci            }
12987db96d56Sopenharmony_ci            else {
12997db96d56Sopenharmony_ci                dictptr = _PyObject_DictPointer(obj);
13007db96d56Sopenharmony_ci                assert(dictptr != NULL && *dictptr == NULL);
13017db96d56Sopenharmony_ci                *dictptr = dict = _PyObject_MakeDictFromInstanceAttributes(obj, *values_ptr);
13027db96d56Sopenharmony_ci                if (dict == NULL) {
13037db96d56Sopenharmony_ci                    res = NULL;
13047db96d56Sopenharmony_ci                    goto done;
13057db96d56Sopenharmony_ci                }
13067db96d56Sopenharmony_ci                *values_ptr = NULL;
13077db96d56Sopenharmony_ci            }
13087db96d56Sopenharmony_ci        }
13097db96d56Sopenharmony_ci        else {
13107db96d56Sopenharmony_ci            dictptr = _PyObject_DictPointer(obj);
13117db96d56Sopenharmony_ci            if (dictptr) {
13127db96d56Sopenharmony_ci                dict = *dictptr;
13137db96d56Sopenharmony_ci            }
13147db96d56Sopenharmony_ci        }
13157db96d56Sopenharmony_ci    }
13167db96d56Sopenharmony_ci    if (dict != NULL) {
13177db96d56Sopenharmony_ci        Py_INCREF(dict);
13187db96d56Sopenharmony_ci        res = PyDict_GetItemWithError(dict, name);
13197db96d56Sopenharmony_ci        if (res != NULL) {
13207db96d56Sopenharmony_ci            Py_INCREF(res);
13217db96d56Sopenharmony_ci            Py_DECREF(dict);
13227db96d56Sopenharmony_ci            goto done;
13237db96d56Sopenharmony_ci        }
13247db96d56Sopenharmony_ci        else {
13257db96d56Sopenharmony_ci            Py_DECREF(dict);
13267db96d56Sopenharmony_ci            if (PyErr_Occurred()) {
13277db96d56Sopenharmony_ci                if (suppress && PyErr_ExceptionMatches(PyExc_AttributeError)) {
13287db96d56Sopenharmony_ci                    PyErr_Clear();
13297db96d56Sopenharmony_ci                }
13307db96d56Sopenharmony_ci                else {
13317db96d56Sopenharmony_ci                    goto done;
13327db96d56Sopenharmony_ci                }
13337db96d56Sopenharmony_ci            }
13347db96d56Sopenharmony_ci        }
13357db96d56Sopenharmony_ci    }
13367db96d56Sopenharmony_ci
13377db96d56Sopenharmony_ci    if (f != NULL) {
13387db96d56Sopenharmony_ci        res = f(descr, obj, (PyObject *)Py_TYPE(obj));
13397db96d56Sopenharmony_ci        if (res == NULL && suppress &&
13407db96d56Sopenharmony_ci                PyErr_ExceptionMatches(PyExc_AttributeError)) {
13417db96d56Sopenharmony_ci            PyErr_Clear();
13427db96d56Sopenharmony_ci        }
13437db96d56Sopenharmony_ci        goto done;
13447db96d56Sopenharmony_ci    }
13457db96d56Sopenharmony_ci
13467db96d56Sopenharmony_ci    if (descr != NULL) {
13477db96d56Sopenharmony_ci        res = descr;
13487db96d56Sopenharmony_ci        descr = NULL;
13497db96d56Sopenharmony_ci        goto done;
13507db96d56Sopenharmony_ci    }
13517db96d56Sopenharmony_ci
13527db96d56Sopenharmony_ci    if (!suppress) {
13537db96d56Sopenharmony_ci        PyErr_Format(PyExc_AttributeError,
13547db96d56Sopenharmony_ci                     "'%.50s' object has no attribute '%U'",
13557db96d56Sopenharmony_ci                     tp->tp_name, name);
13567db96d56Sopenharmony_ci
13577db96d56Sopenharmony_ci        set_attribute_error_context(obj, name);
13587db96d56Sopenharmony_ci    }
13597db96d56Sopenharmony_ci  done:
13607db96d56Sopenharmony_ci    Py_XDECREF(descr);
13617db96d56Sopenharmony_ci    Py_DECREF(name);
13627db96d56Sopenharmony_ci    return res;
13637db96d56Sopenharmony_ci}
13647db96d56Sopenharmony_ci
13657db96d56Sopenharmony_ciPyObject *
13667db96d56Sopenharmony_ciPyObject_GenericGetAttr(PyObject *obj, PyObject *name)
13677db96d56Sopenharmony_ci{
13687db96d56Sopenharmony_ci    return _PyObject_GenericGetAttrWithDict(obj, name, NULL, 0);
13697db96d56Sopenharmony_ci}
13707db96d56Sopenharmony_ci
13717db96d56Sopenharmony_ciint
13727db96d56Sopenharmony_ci_PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name,
13737db96d56Sopenharmony_ci                                 PyObject *value, PyObject *dict)
13747db96d56Sopenharmony_ci{
13757db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(obj);
13767db96d56Sopenharmony_ci    PyObject *descr;
13777db96d56Sopenharmony_ci    descrsetfunc f;
13787db96d56Sopenharmony_ci    int res = -1;
13797db96d56Sopenharmony_ci
13807db96d56Sopenharmony_ci    if (!PyUnicode_Check(name)){
13817db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
13827db96d56Sopenharmony_ci                     "attribute name must be string, not '%.200s'",
13837db96d56Sopenharmony_ci                     Py_TYPE(name)->tp_name);
13847db96d56Sopenharmony_ci        return -1;
13857db96d56Sopenharmony_ci    }
13867db96d56Sopenharmony_ci
13877db96d56Sopenharmony_ci    if (tp->tp_dict == NULL && PyType_Ready(tp) < 0)
13887db96d56Sopenharmony_ci        return -1;
13897db96d56Sopenharmony_ci
13907db96d56Sopenharmony_ci    Py_INCREF(name);
13917db96d56Sopenharmony_ci    Py_INCREF(tp);
13927db96d56Sopenharmony_ci    descr = _PyType_Lookup(tp, name);
13937db96d56Sopenharmony_ci
13947db96d56Sopenharmony_ci    if (descr != NULL) {
13957db96d56Sopenharmony_ci        Py_INCREF(descr);
13967db96d56Sopenharmony_ci        f = Py_TYPE(descr)->tp_descr_set;
13977db96d56Sopenharmony_ci        if (f != NULL) {
13987db96d56Sopenharmony_ci            res = f(descr, obj, value);
13997db96d56Sopenharmony_ci            goto done;
14007db96d56Sopenharmony_ci        }
14017db96d56Sopenharmony_ci    }
14027db96d56Sopenharmony_ci
14037db96d56Sopenharmony_ci    if (dict == NULL) {
14047db96d56Sopenharmony_ci        if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) && *_PyObject_ValuesPointer(obj)) {
14057db96d56Sopenharmony_ci            res = _PyObject_StoreInstanceAttribute(obj, *_PyObject_ValuesPointer(obj), name, value);
14067db96d56Sopenharmony_ci        }
14077db96d56Sopenharmony_ci        else {
14087db96d56Sopenharmony_ci            PyObject **dictptr = _PyObject_DictPointer(obj);
14097db96d56Sopenharmony_ci            if (dictptr == NULL) {
14107db96d56Sopenharmony_ci                if (descr == NULL) {
14117db96d56Sopenharmony_ci                    PyErr_Format(PyExc_AttributeError,
14127db96d56Sopenharmony_ci                                "'%.100s' object has no attribute '%U'",
14137db96d56Sopenharmony_ci                                tp->tp_name, name);
14147db96d56Sopenharmony_ci                }
14157db96d56Sopenharmony_ci                else {
14167db96d56Sopenharmony_ci                    PyErr_Format(PyExc_AttributeError,
14177db96d56Sopenharmony_ci                                "'%.50s' object attribute '%U' is read-only",
14187db96d56Sopenharmony_ci                                tp->tp_name, name);
14197db96d56Sopenharmony_ci                }
14207db96d56Sopenharmony_ci                goto done;
14217db96d56Sopenharmony_ci            }
14227db96d56Sopenharmony_ci            else {
14237db96d56Sopenharmony_ci                res = _PyObjectDict_SetItem(tp, dictptr, name, value);
14247db96d56Sopenharmony_ci            }
14257db96d56Sopenharmony_ci        }
14267db96d56Sopenharmony_ci    }
14277db96d56Sopenharmony_ci    else {
14287db96d56Sopenharmony_ci        Py_INCREF(dict);
14297db96d56Sopenharmony_ci        if (value == NULL)
14307db96d56Sopenharmony_ci            res = PyDict_DelItem(dict, name);
14317db96d56Sopenharmony_ci        else
14327db96d56Sopenharmony_ci            res = PyDict_SetItem(dict, name, value);
14337db96d56Sopenharmony_ci        Py_DECREF(dict);
14347db96d56Sopenharmony_ci    }
14357db96d56Sopenharmony_ci    if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
14367db96d56Sopenharmony_ci        if (PyType_IsSubtype(tp, &PyType_Type)) {
14377db96d56Sopenharmony_ci            PyErr_Format(PyExc_AttributeError,
14387db96d56Sopenharmony_ci                         "type object '%.50s' has no attribute '%U'",
14397db96d56Sopenharmony_ci                         ((PyTypeObject*)obj)->tp_name, name);
14407db96d56Sopenharmony_ci        }
14417db96d56Sopenharmony_ci        else {
14427db96d56Sopenharmony_ci            PyErr_Format(PyExc_AttributeError,
14437db96d56Sopenharmony_ci                         "'%.100s' object has no attribute '%U'",
14447db96d56Sopenharmony_ci                         tp->tp_name, name);
14457db96d56Sopenharmony_ci        }
14467db96d56Sopenharmony_ci    }
14477db96d56Sopenharmony_ci  done:
14487db96d56Sopenharmony_ci    Py_XDECREF(descr);
14497db96d56Sopenharmony_ci    Py_DECREF(tp);
14507db96d56Sopenharmony_ci    Py_DECREF(name);
14517db96d56Sopenharmony_ci    return res;
14527db96d56Sopenharmony_ci}
14537db96d56Sopenharmony_ci
14547db96d56Sopenharmony_ciint
14557db96d56Sopenharmony_ciPyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
14567db96d56Sopenharmony_ci{
14577db96d56Sopenharmony_ci    return _PyObject_GenericSetAttrWithDict(obj, name, value, NULL);
14587db96d56Sopenharmony_ci}
14597db96d56Sopenharmony_ci
14607db96d56Sopenharmony_ciint
14617db96d56Sopenharmony_ciPyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context)
14627db96d56Sopenharmony_ci{
14637db96d56Sopenharmony_ci    PyObject **dictptr = _PyObject_GetDictPtr(obj);
14647db96d56Sopenharmony_ci    if (dictptr == NULL) {
14657db96d56Sopenharmony_ci        if (_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_MANAGED_DICT) &&
14667db96d56Sopenharmony_ci            *_PyObject_ValuesPointer(obj) != NULL)
14677db96d56Sopenharmony_ci        {
14687db96d56Sopenharmony_ci            /* Was unable to convert to dict */
14697db96d56Sopenharmony_ci            PyErr_NoMemory();
14707db96d56Sopenharmony_ci        }
14717db96d56Sopenharmony_ci        else {
14727db96d56Sopenharmony_ci            PyErr_SetString(PyExc_AttributeError,
14737db96d56Sopenharmony_ci                            "This object has no __dict__");
14747db96d56Sopenharmony_ci        }
14757db96d56Sopenharmony_ci        return -1;
14767db96d56Sopenharmony_ci    }
14777db96d56Sopenharmony_ci    if (value == NULL) {
14787db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError, "cannot delete __dict__");
14797db96d56Sopenharmony_ci        return -1;
14807db96d56Sopenharmony_ci    }
14817db96d56Sopenharmony_ci    if (!PyDict_Check(value)) {
14827db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
14837db96d56Sopenharmony_ci                     "__dict__ must be set to a dictionary, "
14847db96d56Sopenharmony_ci                     "not a '%.200s'", Py_TYPE(value)->tp_name);
14857db96d56Sopenharmony_ci        return -1;
14867db96d56Sopenharmony_ci    }
14877db96d56Sopenharmony_ci    Py_INCREF(value);
14887db96d56Sopenharmony_ci    Py_XSETREF(*dictptr, value);
14897db96d56Sopenharmony_ci    return 0;
14907db96d56Sopenharmony_ci}
14917db96d56Sopenharmony_ci
14927db96d56Sopenharmony_ci
14937db96d56Sopenharmony_ci/* Test a value used as condition, e.g., in a while or if statement.
14947db96d56Sopenharmony_ci   Return -1 if an error occurred */
14957db96d56Sopenharmony_ci
14967db96d56Sopenharmony_ciint
14977db96d56Sopenharmony_ciPyObject_IsTrue(PyObject *v)
14987db96d56Sopenharmony_ci{
14997db96d56Sopenharmony_ci    Py_ssize_t res;
15007db96d56Sopenharmony_ci    if (v == Py_True)
15017db96d56Sopenharmony_ci        return 1;
15027db96d56Sopenharmony_ci    if (v == Py_False)
15037db96d56Sopenharmony_ci        return 0;
15047db96d56Sopenharmony_ci    if (v == Py_None)
15057db96d56Sopenharmony_ci        return 0;
15067db96d56Sopenharmony_ci    else if (Py_TYPE(v)->tp_as_number != NULL &&
15077db96d56Sopenharmony_ci             Py_TYPE(v)->tp_as_number->nb_bool != NULL)
15087db96d56Sopenharmony_ci        res = (*Py_TYPE(v)->tp_as_number->nb_bool)(v);
15097db96d56Sopenharmony_ci    else if (Py_TYPE(v)->tp_as_mapping != NULL &&
15107db96d56Sopenharmony_ci             Py_TYPE(v)->tp_as_mapping->mp_length != NULL)
15117db96d56Sopenharmony_ci        res = (*Py_TYPE(v)->tp_as_mapping->mp_length)(v);
15127db96d56Sopenharmony_ci    else if (Py_TYPE(v)->tp_as_sequence != NULL &&
15137db96d56Sopenharmony_ci             Py_TYPE(v)->tp_as_sequence->sq_length != NULL)
15147db96d56Sopenharmony_ci        res = (*Py_TYPE(v)->tp_as_sequence->sq_length)(v);
15157db96d56Sopenharmony_ci    else
15167db96d56Sopenharmony_ci        return 1;
15177db96d56Sopenharmony_ci    /* if it is negative, it should be either -1 or -2 */
15187db96d56Sopenharmony_ci    return (res > 0) ? 1 : Py_SAFE_DOWNCAST(res, Py_ssize_t, int);
15197db96d56Sopenharmony_ci}
15207db96d56Sopenharmony_ci
15217db96d56Sopenharmony_ci/* equivalent of 'not v'
15227db96d56Sopenharmony_ci   Return -1 if an error occurred */
15237db96d56Sopenharmony_ci
15247db96d56Sopenharmony_ciint
15257db96d56Sopenharmony_ciPyObject_Not(PyObject *v)
15267db96d56Sopenharmony_ci{
15277db96d56Sopenharmony_ci    int res;
15287db96d56Sopenharmony_ci    res = PyObject_IsTrue(v);
15297db96d56Sopenharmony_ci    if (res < 0)
15307db96d56Sopenharmony_ci        return res;
15317db96d56Sopenharmony_ci    return res == 0;
15327db96d56Sopenharmony_ci}
15337db96d56Sopenharmony_ci
15347db96d56Sopenharmony_ci/* Test whether an object can be called */
15357db96d56Sopenharmony_ci
15367db96d56Sopenharmony_ciint
15377db96d56Sopenharmony_ciPyCallable_Check(PyObject *x)
15387db96d56Sopenharmony_ci{
15397db96d56Sopenharmony_ci    if (x == NULL)
15407db96d56Sopenharmony_ci        return 0;
15417db96d56Sopenharmony_ci    return Py_TYPE(x)->tp_call != NULL;
15427db96d56Sopenharmony_ci}
15437db96d56Sopenharmony_ci
15447db96d56Sopenharmony_ci
15457db96d56Sopenharmony_ci/* Helper for PyObject_Dir without arguments: returns the local scope. */
15467db96d56Sopenharmony_cistatic PyObject *
15477db96d56Sopenharmony_ci_dir_locals(void)
15487db96d56Sopenharmony_ci{
15497db96d56Sopenharmony_ci    PyObject *names;
15507db96d56Sopenharmony_ci    PyObject *locals;
15517db96d56Sopenharmony_ci
15527db96d56Sopenharmony_ci    locals = PyEval_GetLocals();
15537db96d56Sopenharmony_ci    if (locals == NULL)
15547db96d56Sopenharmony_ci        return NULL;
15557db96d56Sopenharmony_ci
15567db96d56Sopenharmony_ci    names = PyMapping_Keys(locals);
15577db96d56Sopenharmony_ci    if (!names)
15587db96d56Sopenharmony_ci        return NULL;
15597db96d56Sopenharmony_ci    if (!PyList_Check(names)) {
15607db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
15617db96d56Sopenharmony_ci            "dir(): expected keys() of locals to be a list, "
15627db96d56Sopenharmony_ci            "not '%.200s'", Py_TYPE(names)->tp_name);
15637db96d56Sopenharmony_ci        Py_DECREF(names);
15647db96d56Sopenharmony_ci        return NULL;
15657db96d56Sopenharmony_ci    }
15667db96d56Sopenharmony_ci    if (PyList_Sort(names)) {
15677db96d56Sopenharmony_ci        Py_DECREF(names);
15687db96d56Sopenharmony_ci        return NULL;
15697db96d56Sopenharmony_ci    }
15707db96d56Sopenharmony_ci    /* the locals don't need to be DECREF'd */
15717db96d56Sopenharmony_ci    return names;
15727db96d56Sopenharmony_ci}
15737db96d56Sopenharmony_ci
15747db96d56Sopenharmony_ci/* Helper for PyObject_Dir: object introspection. */
15757db96d56Sopenharmony_cistatic PyObject *
15767db96d56Sopenharmony_ci_dir_object(PyObject *obj)
15777db96d56Sopenharmony_ci{
15787db96d56Sopenharmony_ci    PyObject *result, *sorted;
15797db96d56Sopenharmony_ci    PyObject *dirfunc = _PyObject_LookupSpecial(obj, &_Py_ID(__dir__));
15807db96d56Sopenharmony_ci
15817db96d56Sopenharmony_ci    assert(obj != NULL);
15827db96d56Sopenharmony_ci    if (dirfunc == NULL) {
15837db96d56Sopenharmony_ci        if (!PyErr_Occurred())
15847db96d56Sopenharmony_ci            PyErr_SetString(PyExc_TypeError, "object does not provide __dir__");
15857db96d56Sopenharmony_ci        return NULL;
15867db96d56Sopenharmony_ci    }
15877db96d56Sopenharmony_ci    /* use __dir__ */
15887db96d56Sopenharmony_ci    result = _PyObject_CallNoArgs(dirfunc);
15897db96d56Sopenharmony_ci    Py_DECREF(dirfunc);
15907db96d56Sopenharmony_ci    if (result == NULL)
15917db96d56Sopenharmony_ci        return NULL;
15927db96d56Sopenharmony_ci    /* return sorted(result) */
15937db96d56Sopenharmony_ci    sorted = PySequence_List(result);
15947db96d56Sopenharmony_ci    Py_DECREF(result);
15957db96d56Sopenharmony_ci    if (sorted == NULL)
15967db96d56Sopenharmony_ci        return NULL;
15977db96d56Sopenharmony_ci    if (PyList_Sort(sorted)) {
15987db96d56Sopenharmony_ci        Py_DECREF(sorted);
15997db96d56Sopenharmony_ci        return NULL;
16007db96d56Sopenharmony_ci    }
16017db96d56Sopenharmony_ci    return sorted;
16027db96d56Sopenharmony_ci}
16037db96d56Sopenharmony_ci
16047db96d56Sopenharmony_ci/* Implementation of dir() -- if obj is NULL, returns the names in the current
16057db96d56Sopenharmony_ci   (local) scope.  Otherwise, performs introspection of the object: returns a
16067db96d56Sopenharmony_ci   sorted list of attribute names (supposedly) accessible from the object
16077db96d56Sopenharmony_ci*/
16087db96d56Sopenharmony_ciPyObject *
16097db96d56Sopenharmony_ciPyObject_Dir(PyObject *obj)
16107db96d56Sopenharmony_ci{
16117db96d56Sopenharmony_ci    return (obj == NULL) ? _dir_locals() : _dir_object(obj);
16127db96d56Sopenharmony_ci}
16137db96d56Sopenharmony_ci
16147db96d56Sopenharmony_ci/*
16157db96d56Sopenharmony_ciNone is a non-NULL undefined value.
16167db96d56Sopenharmony_ciThere is (and should be!) no way to create other objects of this type,
16177db96d56Sopenharmony_ciso there is exactly one (which is indestructible, by the way).
16187db96d56Sopenharmony_ci*/
16197db96d56Sopenharmony_ci
16207db96d56Sopenharmony_ci/* ARGSUSED */
16217db96d56Sopenharmony_cistatic PyObject *
16227db96d56Sopenharmony_cinone_repr(PyObject *op)
16237db96d56Sopenharmony_ci{
16247db96d56Sopenharmony_ci    return PyUnicode_FromString("None");
16257db96d56Sopenharmony_ci}
16267db96d56Sopenharmony_ci
16277db96d56Sopenharmony_cistatic void _Py_NO_RETURN
16287db96d56Sopenharmony_cinone_dealloc(PyObject* Py_UNUSED(ignore))
16297db96d56Sopenharmony_ci{
16307db96d56Sopenharmony_ci    _Py_FatalRefcountError("deallocating None");
16317db96d56Sopenharmony_ci}
16327db96d56Sopenharmony_ci
16337db96d56Sopenharmony_cistatic PyObject *
16347db96d56Sopenharmony_cinone_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
16357db96d56Sopenharmony_ci{
16367db96d56Sopenharmony_ci    if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) {
16377db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError, "NoneType takes no arguments");
16387db96d56Sopenharmony_ci        return NULL;
16397db96d56Sopenharmony_ci    }
16407db96d56Sopenharmony_ci    Py_RETURN_NONE;
16417db96d56Sopenharmony_ci}
16427db96d56Sopenharmony_ci
16437db96d56Sopenharmony_cistatic int
16447db96d56Sopenharmony_cinone_bool(PyObject *v)
16457db96d56Sopenharmony_ci{
16467db96d56Sopenharmony_ci    return 0;
16477db96d56Sopenharmony_ci}
16487db96d56Sopenharmony_ci
16497db96d56Sopenharmony_cistatic PyNumberMethods none_as_number = {
16507db96d56Sopenharmony_ci    0,                          /* nb_add */
16517db96d56Sopenharmony_ci    0,                          /* nb_subtract */
16527db96d56Sopenharmony_ci    0,                          /* nb_multiply */
16537db96d56Sopenharmony_ci    0,                          /* nb_remainder */
16547db96d56Sopenharmony_ci    0,                          /* nb_divmod */
16557db96d56Sopenharmony_ci    0,                          /* nb_power */
16567db96d56Sopenharmony_ci    0,                          /* nb_negative */
16577db96d56Sopenharmony_ci    0,                          /* nb_positive */
16587db96d56Sopenharmony_ci    0,                          /* nb_absolute */
16597db96d56Sopenharmony_ci    (inquiry)none_bool,         /* nb_bool */
16607db96d56Sopenharmony_ci    0,                          /* nb_invert */
16617db96d56Sopenharmony_ci    0,                          /* nb_lshift */
16627db96d56Sopenharmony_ci    0,                          /* nb_rshift */
16637db96d56Sopenharmony_ci    0,                          /* nb_and */
16647db96d56Sopenharmony_ci    0,                          /* nb_xor */
16657db96d56Sopenharmony_ci    0,                          /* nb_or */
16667db96d56Sopenharmony_ci    0,                          /* nb_int */
16677db96d56Sopenharmony_ci    0,                          /* nb_reserved */
16687db96d56Sopenharmony_ci    0,                          /* nb_float */
16697db96d56Sopenharmony_ci    0,                          /* nb_inplace_add */
16707db96d56Sopenharmony_ci    0,                          /* nb_inplace_subtract */
16717db96d56Sopenharmony_ci    0,                          /* nb_inplace_multiply */
16727db96d56Sopenharmony_ci    0,                          /* nb_inplace_remainder */
16737db96d56Sopenharmony_ci    0,                          /* nb_inplace_power */
16747db96d56Sopenharmony_ci    0,                          /* nb_inplace_lshift */
16757db96d56Sopenharmony_ci    0,                          /* nb_inplace_rshift */
16767db96d56Sopenharmony_ci    0,                          /* nb_inplace_and */
16777db96d56Sopenharmony_ci    0,                          /* nb_inplace_xor */
16787db96d56Sopenharmony_ci    0,                          /* nb_inplace_or */
16797db96d56Sopenharmony_ci    0,                          /* nb_floor_divide */
16807db96d56Sopenharmony_ci    0,                          /* nb_true_divide */
16817db96d56Sopenharmony_ci    0,                          /* nb_inplace_floor_divide */
16827db96d56Sopenharmony_ci    0,                          /* nb_inplace_true_divide */
16837db96d56Sopenharmony_ci    0,                          /* nb_index */
16847db96d56Sopenharmony_ci};
16857db96d56Sopenharmony_ci
16867db96d56Sopenharmony_ciPyTypeObject _PyNone_Type = {
16877db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
16887db96d56Sopenharmony_ci    "NoneType",
16897db96d56Sopenharmony_ci    0,
16907db96d56Sopenharmony_ci    0,
16917db96d56Sopenharmony_ci    none_dealloc,       /*tp_dealloc*/ /*never called*/
16927db96d56Sopenharmony_ci    0,                  /*tp_vectorcall_offset*/
16937db96d56Sopenharmony_ci    0,                  /*tp_getattr*/
16947db96d56Sopenharmony_ci    0,                  /*tp_setattr*/
16957db96d56Sopenharmony_ci    0,                  /*tp_as_async*/
16967db96d56Sopenharmony_ci    none_repr,          /*tp_repr*/
16977db96d56Sopenharmony_ci    &none_as_number,    /*tp_as_number*/
16987db96d56Sopenharmony_ci    0,                  /*tp_as_sequence*/
16997db96d56Sopenharmony_ci    0,                  /*tp_as_mapping*/
17007db96d56Sopenharmony_ci    0,                  /*tp_hash */
17017db96d56Sopenharmony_ci    0,                  /*tp_call */
17027db96d56Sopenharmony_ci    0,                  /*tp_str */
17037db96d56Sopenharmony_ci    0,                  /*tp_getattro */
17047db96d56Sopenharmony_ci    0,                  /*tp_setattro */
17057db96d56Sopenharmony_ci    0,                  /*tp_as_buffer */
17067db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT, /*tp_flags */
17077db96d56Sopenharmony_ci    0,                  /*tp_doc */
17087db96d56Sopenharmony_ci    0,                  /*tp_traverse */
17097db96d56Sopenharmony_ci    0,                  /*tp_clear */
17107db96d56Sopenharmony_ci    0,                  /*tp_richcompare */
17117db96d56Sopenharmony_ci    0,                  /*tp_weaklistoffset */
17127db96d56Sopenharmony_ci    0,                  /*tp_iter */
17137db96d56Sopenharmony_ci    0,                  /*tp_iternext */
17147db96d56Sopenharmony_ci    0,                  /*tp_methods */
17157db96d56Sopenharmony_ci    0,                  /*tp_members */
17167db96d56Sopenharmony_ci    0,                  /*tp_getset */
17177db96d56Sopenharmony_ci    0,                  /*tp_base */
17187db96d56Sopenharmony_ci    0,                  /*tp_dict */
17197db96d56Sopenharmony_ci    0,                  /*tp_descr_get */
17207db96d56Sopenharmony_ci    0,                  /*tp_descr_set */
17217db96d56Sopenharmony_ci    0,                  /*tp_dictoffset */
17227db96d56Sopenharmony_ci    0,                  /*tp_init */
17237db96d56Sopenharmony_ci    0,                  /*tp_alloc */
17247db96d56Sopenharmony_ci    none_new,           /*tp_new */
17257db96d56Sopenharmony_ci};
17267db96d56Sopenharmony_ci
17277db96d56Sopenharmony_ciPyObject _Py_NoneStruct = {
17287db96d56Sopenharmony_ci  _PyObject_EXTRA_INIT
17297db96d56Sopenharmony_ci  1, &_PyNone_Type
17307db96d56Sopenharmony_ci};
17317db96d56Sopenharmony_ci
17327db96d56Sopenharmony_ci/* NotImplemented is an object that can be used to signal that an
17337db96d56Sopenharmony_ci   operation is not implemented for the given type combination. */
17347db96d56Sopenharmony_ci
17357db96d56Sopenharmony_cistatic PyObject *
17367db96d56Sopenharmony_ciNotImplemented_repr(PyObject *op)
17377db96d56Sopenharmony_ci{
17387db96d56Sopenharmony_ci    return PyUnicode_FromString("NotImplemented");
17397db96d56Sopenharmony_ci}
17407db96d56Sopenharmony_ci
17417db96d56Sopenharmony_cistatic PyObject *
17427db96d56Sopenharmony_ciNotImplemented_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
17437db96d56Sopenharmony_ci{
17447db96d56Sopenharmony_ci    return PyUnicode_FromString("NotImplemented");
17457db96d56Sopenharmony_ci}
17467db96d56Sopenharmony_ci
17477db96d56Sopenharmony_cistatic PyMethodDef notimplemented_methods[] = {
17487db96d56Sopenharmony_ci    {"__reduce__", NotImplemented_reduce, METH_NOARGS, NULL},
17497db96d56Sopenharmony_ci    {NULL, NULL}
17507db96d56Sopenharmony_ci};
17517db96d56Sopenharmony_ci
17527db96d56Sopenharmony_cistatic PyObject *
17537db96d56Sopenharmony_cinotimplemented_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
17547db96d56Sopenharmony_ci{
17557db96d56Sopenharmony_ci    if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) {
17567db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError, "NotImplementedType takes no arguments");
17577db96d56Sopenharmony_ci        return NULL;
17587db96d56Sopenharmony_ci    }
17597db96d56Sopenharmony_ci    Py_RETURN_NOTIMPLEMENTED;
17607db96d56Sopenharmony_ci}
17617db96d56Sopenharmony_ci
17627db96d56Sopenharmony_cistatic void _Py_NO_RETURN
17637db96d56Sopenharmony_cinotimplemented_dealloc(PyObject* ignore)
17647db96d56Sopenharmony_ci{
17657db96d56Sopenharmony_ci    /* This should never get called, but we also don't want to SEGV if
17667db96d56Sopenharmony_ci     * we accidentally decref NotImplemented out of existence.
17677db96d56Sopenharmony_ci     */
17687db96d56Sopenharmony_ci    Py_FatalError("deallocating NotImplemented");
17697db96d56Sopenharmony_ci}
17707db96d56Sopenharmony_ci
17717db96d56Sopenharmony_cistatic int
17727db96d56Sopenharmony_cinotimplemented_bool(PyObject *v)
17737db96d56Sopenharmony_ci{
17747db96d56Sopenharmony_ci    if (PyErr_WarnEx(PyExc_DeprecationWarning,
17757db96d56Sopenharmony_ci                     "NotImplemented should not be used in a boolean context",
17767db96d56Sopenharmony_ci                     1) < 0)
17777db96d56Sopenharmony_ci    {
17787db96d56Sopenharmony_ci        return -1;
17797db96d56Sopenharmony_ci    }
17807db96d56Sopenharmony_ci    return 1;
17817db96d56Sopenharmony_ci}
17827db96d56Sopenharmony_ci
17837db96d56Sopenharmony_cistatic PyNumberMethods notimplemented_as_number = {
17847db96d56Sopenharmony_ci    .nb_bool = notimplemented_bool,
17857db96d56Sopenharmony_ci};
17867db96d56Sopenharmony_ci
17877db96d56Sopenharmony_ciPyTypeObject _PyNotImplemented_Type = {
17887db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
17897db96d56Sopenharmony_ci    "NotImplementedType",
17907db96d56Sopenharmony_ci    0,
17917db96d56Sopenharmony_ci    0,
17927db96d56Sopenharmony_ci    notimplemented_dealloc,       /*tp_dealloc*/ /*never called*/
17937db96d56Sopenharmony_ci    0,                  /*tp_vectorcall_offset*/
17947db96d56Sopenharmony_ci    0,                  /*tp_getattr*/
17957db96d56Sopenharmony_ci    0,                  /*tp_setattr*/
17967db96d56Sopenharmony_ci    0,                  /*tp_as_async*/
17977db96d56Sopenharmony_ci    NotImplemented_repr,        /*tp_repr*/
17987db96d56Sopenharmony_ci    &notimplemented_as_number,  /*tp_as_number*/
17997db96d56Sopenharmony_ci    0,                  /*tp_as_sequence*/
18007db96d56Sopenharmony_ci    0,                  /*tp_as_mapping*/
18017db96d56Sopenharmony_ci    0,                  /*tp_hash */
18027db96d56Sopenharmony_ci    0,                  /*tp_call */
18037db96d56Sopenharmony_ci    0,                  /*tp_str */
18047db96d56Sopenharmony_ci    0,                  /*tp_getattro */
18057db96d56Sopenharmony_ci    0,                  /*tp_setattro */
18067db96d56Sopenharmony_ci    0,                  /*tp_as_buffer */
18077db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT, /*tp_flags */
18087db96d56Sopenharmony_ci    0,                  /*tp_doc */
18097db96d56Sopenharmony_ci    0,                  /*tp_traverse */
18107db96d56Sopenharmony_ci    0,                  /*tp_clear */
18117db96d56Sopenharmony_ci    0,                  /*tp_richcompare */
18127db96d56Sopenharmony_ci    0,                  /*tp_weaklistoffset */
18137db96d56Sopenharmony_ci    0,                  /*tp_iter */
18147db96d56Sopenharmony_ci    0,                  /*tp_iternext */
18157db96d56Sopenharmony_ci    notimplemented_methods, /*tp_methods */
18167db96d56Sopenharmony_ci    0,                  /*tp_members */
18177db96d56Sopenharmony_ci    0,                  /*tp_getset */
18187db96d56Sopenharmony_ci    0,                  /*tp_base */
18197db96d56Sopenharmony_ci    0,                  /*tp_dict */
18207db96d56Sopenharmony_ci    0,                  /*tp_descr_get */
18217db96d56Sopenharmony_ci    0,                  /*tp_descr_set */
18227db96d56Sopenharmony_ci    0,                  /*tp_dictoffset */
18237db96d56Sopenharmony_ci    0,                  /*tp_init */
18247db96d56Sopenharmony_ci    0,                  /*tp_alloc */
18257db96d56Sopenharmony_ci    notimplemented_new, /*tp_new */
18267db96d56Sopenharmony_ci};
18277db96d56Sopenharmony_ci
18287db96d56Sopenharmony_ciPyObject _Py_NotImplementedStruct = {
18297db96d56Sopenharmony_ci    _PyObject_EXTRA_INIT
18307db96d56Sopenharmony_ci    1, &_PyNotImplemented_Type
18317db96d56Sopenharmony_ci};
18327db96d56Sopenharmony_ci
18337db96d56Sopenharmony_ciPyStatus
18347db96d56Sopenharmony_ci_PyTypes_InitState(PyInterpreterState *interp)
18357db96d56Sopenharmony_ci{
18367db96d56Sopenharmony_ci    if (!_Py_IsMainInterpreter(interp)) {
18377db96d56Sopenharmony_ci        return _PyStatus_OK();
18387db96d56Sopenharmony_ci    }
18397db96d56Sopenharmony_ci
18407db96d56Sopenharmony_ci    PyStatus status = _PyTypes_InitSlotDefs();
18417db96d56Sopenharmony_ci    if (_PyStatus_EXCEPTION(status)) {
18427db96d56Sopenharmony_ci        return status;
18437db96d56Sopenharmony_ci    }
18447db96d56Sopenharmony_ci
18457db96d56Sopenharmony_ci    return _PyStatus_OK();
18467db96d56Sopenharmony_ci}
18477db96d56Sopenharmony_ci
18487db96d56Sopenharmony_ci
18497db96d56Sopenharmony_ci
18507db96d56Sopenharmony_ci#ifdef MS_WINDOWS
18517db96d56Sopenharmony_ciextern PyTypeObject PyHKEY_Type;
18527db96d56Sopenharmony_ci#endif
18537db96d56Sopenharmony_ciextern PyTypeObject _Py_GenericAliasIterType;
18547db96d56Sopenharmony_ciextern PyTypeObject _PyMemoryIter_Type;
18557db96d56Sopenharmony_ci
18567db96d56Sopenharmony_cistatic PyTypeObject* static_types[] = {
18577db96d56Sopenharmony_ci    // The two most important base types: must be initialized first and
18587db96d56Sopenharmony_ci    // deallocated last.
18597db96d56Sopenharmony_ci    &PyBaseObject_Type,
18607db96d56Sopenharmony_ci    &PyType_Type,
18617db96d56Sopenharmony_ci
18627db96d56Sopenharmony_ci    // Static types with base=&PyBaseObject_Type
18637db96d56Sopenharmony_ci    &PyAsyncGen_Type,
18647db96d56Sopenharmony_ci    &PyByteArrayIter_Type,
18657db96d56Sopenharmony_ci    &PyByteArray_Type,
18667db96d56Sopenharmony_ci    &PyBytesIter_Type,
18677db96d56Sopenharmony_ci    &PyBytes_Type,
18687db96d56Sopenharmony_ci    &PyCFunction_Type,
18697db96d56Sopenharmony_ci    &PyCallIter_Type,
18707db96d56Sopenharmony_ci    &PyCapsule_Type,
18717db96d56Sopenharmony_ci    &PyCell_Type,
18727db96d56Sopenharmony_ci    &PyClassMethodDescr_Type,
18737db96d56Sopenharmony_ci    &PyClassMethod_Type,
18747db96d56Sopenharmony_ci    &PyCode_Type,
18757db96d56Sopenharmony_ci    &PyComplex_Type,
18767db96d56Sopenharmony_ci    &PyContextToken_Type,
18777db96d56Sopenharmony_ci    &PyContextVar_Type,
18787db96d56Sopenharmony_ci    &PyContext_Type,
18797db96d56Sopenharmony_ci    &PyCoro_Type,
18807db96d56Sopenharmony_ci    &PyDictItems_Type,
18817db96d56Sopenharmony_ci    &PyDictIterItem_Type,
18827db96d56Sopenharmony_ci    &PyDictIterKey_Type,
18837db96d56Sopenharmony_ci    &PyDictIterValue_Type,
18847db96d56Sopenharmony_ci    &PyDictKeys_Type,
18857db96d56Sopenharmony_ci    &PyDictProxy_Type,
18867db96d56Sopenharmony_ci    &PyDictRevIterItem_Type,
18877db96d56Sopenharmony_ci    &PyDictRevIterKey_Type,
18887db96d56Sopenharmony_ci    &PyDictRevIterValue_Type,
18897db96d56Sopenharmony_ci    &PyDictValues_Type,
18907db96d56Sopenharmony_ci    &PyDict_Type,
18917db96d56Sopenharmony_ci    &PyEllipsis_Type,
18927db96d56Sopenharmony_ci    &PyEnum_Type,
18937db96d56Sopenharmony_ci    &PyFilter_Type,
18947db96d56Sopenharmony_ci    &PyFloat_Type,
18957db96d56Sopenharmony_ci    &PyFrame_Type,
18967db96d56Sopenharmony_ci    &PyFrozenSet_Type,
18977db96d56Sopenharmony_ci    &PyFunction_Type,
18987db96d56Sopenharmony_ci    &PyGen_Type,
18997db96d56Sopenharmony_ci    &PyGetSetDescr_Type,
19007db96d56Sopenharmony_ci#ifdef MS_WINDOWS
19017db96d56Sopenharmony_ci    &PyHKEY_Type,
19027db96d56Sopenharmony_ci#endif
19037db96d56Sopenharmony_ci    &PyInstanceMethod_Type,
19047db96d56Sopenharmony_ci    &PyListIter_Type,
19057db96d56Sopenharmony_ci    &PyListRevIter_Type,
19067db96d56Sopenharmony_ci    &PyList_Type,
19077db96d56Sopenharmony_ci    &PyLongRangeIter_Type,
19087db96d56Sopenharmony_ci    &PyLong_Type,
19097db96d56Sopenharmony_ci    &PyMap_Type,
19107db96d56Sopenharmony_ci    &PyMemberDescr_Type,
19117db96d56Sopenharmony_ci    &PyMemoryView_Type,
19127db96d56Sopenharmony_ci    &PyMethodDescr_Type,
19137db96d56Sopenharmony_ci    &PyMethod_Type,
19147db96d56Sopenharmony_ci    &PyModuleDef_Type,
19157db96d56Sopenharmony_ci    &PyModule_Type,
19167db96d56Sopenharmony_ci    &PyODictIter_Type,
19177db96d56Sopenharmony_ci    &PyPickleBuffer_Type,
19187db96d56Sopenharmony_ci    &PyProperty_Type,
19197db96d56Sopenharmony_ci    &PyRangeIter_Type,
19207db96d56Sopenharmony_ci    &PyRange_Type,
19217db96d56Sopenharmony_ci    &PyReversed_Type,
19227db96d56Sopenharmony_ci    &PySTEntry_Type,
19237db96d56Sopenharmony_ci    &PySeqIter_Type,
19247db96d56Sopenharmony_ci    &PySetIter_Type,
19257db96d56Sopenharmony_ci    &PySet_Type,
19267db96d56Sopenharmony_ci    &PySlice_Type,
19277db96d56Sopenharmony_ci    &PyStaticMethod_Type,
19287db96d56Sopenharmony_ci    &PyStdPrinter_Type,
19297db96d56Sopenharmony_ci    &PySuper_Type,
19307db96d56Sopenharmony_ci    &PyTraceBack_Type,
19317db96d56Sopenharmony_ci    &PyTupleIter_Type,
19327db96d56Sopenharmony_ci    &PyTuple_Type,
19337db96d56Sopenharmony_ci    &PyUnicodeIter_Type,
19347db96d56Sopenharmony_ci    &PyUnicode_Type,
19357db96d56Sopenharmony_ci    &PyWrapperDescr_Type,
19367db96d56Sopenharmony_ci    &PyZip_Type,
19377db96d56Sopenharmony_ci    &Py_GenericAliasType,
19387db96d56Sopenharmony_ci    &_PyAnextAwaitable_Type,
19397db96d56Sopenharmony_ci    &_PyAsyncGenASend_Type,
19407db96d56Sopenharmony_ci    &_PyAsyncGenAThrow_Type,
19417db96d56Sopenharmony_ci    &_PyAsyncGenWrappedValue_Type,
19427db96d56Sopenharmony_ci    &_PyContextTokenMissing_Type,
19437db96d56Sopenharmony_ci    &_PyCoroWrapper_Type,
19447db96d56Sopenharmony_ci    &_Py_GenericAliasIterType,
19457db96d56Sopenharmony_ci    &_PyHamtItems_Type,
19467db96d56Sopenharmony_ci    &_PyHamtKeys_Type,
19477db96d56Sopenharmony_ci    &_PyHamtValues_Type,
19487db96d56Sopenharmony_ci    &_PyHamt_ArrayNode_Type,
19497db96d56Sopenharmony_ci    &_PyHamt_BitmapNode_Type,
19507db96d56Sopenharmony_ci    &_PyHamt_CollisionNode_Type,
19517db96d56Sopenharmony_ci    &_PyHamt_Type,
19527db96d56Sopenharmony_ci    &_PyInterpreterID_Type,
19537db96d56Sopenharmony_ci    &_PyManagedBuffer_Type,
19547db96d56Sopenharmony_ci    &_PyMemoryIter_Type,
19557db96d56Sopenharmony_ci    &_PyMethodWrapper_Type,
19567db96d56Sopenharmony_ci    &_PyNamespace_Type,
19577db96d56Sopenharmony_ci    &_PyNone_Type,
19587db96d56Sopenharmony_ci    &_PyNotImplemented_Type,
19597db96d56Sopenharmony_ci    &_PyUnicodeASCIIIter_Type,
19607db96d56Sopenharmony_ci    &_PyUnion_Type,
19617db96d56Sopenharmony_ci    &_PyWeakref_CallableProxyType,
19627db96d56Sopenharmony_ci    &_PyWeakref_ProxyType,
19637db96d56Sopenharmony_ci    &_PyWeakref_RefType,
19647db96d56Sopenharmony_ci
19657db96d56Sopenharmony_ci    // subclasses: _PyTypes_FiniTypes() deallocates them before their base
19667db96d56Sopenharmony_ci    // class
19677db96d56Sopenharmony_ci    &PyBool_Type,         // base=&PyLong_Type
19687db96d56Sopenharmony_ci    &PyCMethod_Type,      // base=&PyCFunction_Type
19697db96d56Sopenharmony_ci    &PyODictItems_Type,   // base=&PyDictItems_Type
19707db96d56Sopenharmony_ci    &PyODictKeys_Type,    // base=&PyDictKeys_Type
19717db96d56Sopenharmony_ci    &PyODictValues_Type,  // base=&PyDictValues_Type
19727db96d56Sopenharmony_ci    &PyODict_Type,        // base=&PyDict_Type
19737db96d56Sopenharmony_ci};
19747db96d56Sopenharmony_ci
19757db96d56Sopenharmony_ci
19767db96d56Sopenharmony_ciPyStatus
19777db96d56Sopenharmony_ci_PyTypes_InitTypes(PyInterpreterState *interp)
19787db96d56Sopenharmony_ci{
19797db96d56Sopenharmony_ci    if (!_Py_IsMainInterpreter(interp)) {
19807db96d56Sopenharmony_ci        return _PyStatus_OK();
19817db96d56Sopenharmony_ci    }
19827db96d56Sopenharmony_ci
19837db96d56Sopenharmony_ci    // All other static types (unless initialized elsewhere)
19847db96d56Sopenharmony_ci    for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
19857db96d56Sopenharmony_ci        PyTypeObject *type = static_types[i];
19867db96d56Sopenharmony_ci        if (PyType_Ready(type) < 0) {
19877db96d56Sopenharmony_ci            return _PyStatus_ERR("Can't initialize types");
19887db96d56Sopenharmony_ci        }
19897db96d56Sopenharmony_ci        if (type == &PyType_Type) {
19907db96d56Sopenharmony_ci            // Sanitify checks of the two most important types
19917db96d56Sopenharmony_ci            assert(PyBaseObject_Type.tp_base == NULL);
19927db96d56Sopenharmony_ci            assert(PyType_Type.tp_base == &PyBaseObject_Type);
19937db96d56Sopenharmony_ci        }
19947db96d56Sopenharmony_ci    }
19957db96d56Sopenharmony_ci
19967db96d56Sopenharmony_ci    return _PyStatus_OK();
19977db96d56Sopenharmony_ci}
19987db96d56Sopenharmony_ci
19997db96d56Sopenharmony_ci
20007db96d56Sopenharmony_ci// Best-effort function clearing static types.
20017db96d56Sopenharmony_ci//
20027db96d56Sopenharmony_ci// Don't deallocate a type if it still has subclasses. If a Py_Finalize()
20037db96d56Sopenharmony_ci// sub-function is interrupted by CTRL+C or fails with MemoryError, some
20047db96d56Sopenharmony_ci// subclasses are not cleared properly. Leave the static type unchanged in this
20057db96d56Sopenharmony_ci// case.
20067db96d56Sopenharmony_civoid
20077db96d56Sopenharmony_ci_PyTypes_FiniTypes(PyInterpreterState *interp)
20087db96d56Sopenharmony_ci{
20097db96d56Sopenharmony_ci    if (!_Py_IsMainInterpreter(interp)) {
20107db96d56Sopenharmony_ci        return;
20117db96d56Sopenharmony_ci    }
20127db96d56Sopenharmony_ci
20137db96d56Sopenharmony_ci    // Deallocate types in the reverse order to deallocate subclasses before
20147db96d56Sopenharmony_ci    // their base classes.
20157db96d56Sopenharmony_ci    for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types)-1; i>=0; i--) {
20167db96d56Sopenharmony_ci        PyTypeObject *type = static_types[i];
20177db96d56Sopenharmony_ci        _PyStaticType_Dealloc(type);
20187db96d56Sopenharmony_ci    }
20197db96d56Sopenharmony_ci}
20207db96d56Sopenharmony_ci
20217db96d56Sopenharmony_ci
20227db96d56Sopenharmony_civoid
20237db96d56Sopenharmony_ci_Py_NewReference(PyObject *op)
20247db96d56Sopenharmony_ci{
20257db96d56Sopenharmony_ci    if (_Py_tracemalloc_config.tracing) {
20267db96d56Sopenharmony_ci        _PyTraceMalloc_NewReference(op);
20277db96d56Sopenharmony_ci    }
20287db96d56Sopenharmony_ci#ifdef Py_REF_DEBUG
20297db96d56Sopenharmony_ci    _Py_RefTotal++;
20307db96d56Sopenharmony_ci#endif
20317db96d56Sopenharmony_ci    Py_SET_REFCNT(op, 1);
20327db96d56Sopenharmony_ci#ifdef Py_TRACE_REFS
20337db96d56Sopenharmony_ci    _Py_AddToAllObjects(op, 1);
20347db96d56Sopenharmony_ci#endif
20357db96d56Sopenharmony_ci}
20367db96d56Sopenharmony_ci
20377db96d56Sopenharmony_ci
20387db96d56Sopenharmony_ci#ifdef Py_TRACE_REFS
20397db96d56Sopenharmony_civoid
20407db96d56Sopenharmony_ci_Py_ForgetReference(PyObject *op)
20417db96d56Sopenharmony_ci{
20427db96d56Sopenharmony_ci    if (Py_REFCNT(op) < 0) {
20437db96d56Sopenharmony_ci        _PyObject_ASSERT_FAILED_MSG(op, "negative refcnt");
20447db96d56Sopenharmony_ci    }
20457db96d56Sopenharmony_ci
20467db96d56Sopenharmony_ci    if (op == &refchain ||
20477db96d56Sopenharmony_ci        op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op)
20487db96d56Sopenharmony_ci    {
20497db96d56Sopenharmony_ci        _PyObject_ASSERT_FAILED_MSG(op, "invalid object chain");
20507db96d56Sopenharmony_ci    }
20517db96d56Sopenharmony_ci
20527db96d56Sopenharmony_ci#ifdef SLOW_UNREF_CHECK
20537db96d56Sopenharmony_ci    PyObject *p;
20547db96d56Sopenharmony_ci    for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
20557db96d56Sopenharmony_ci        if (p == op) {
20567db96d56Sopenharmony_ci            break;
20577db96d56Sopenharmony_ci        }
20587db96d56Sopenharmony_ci    }
20597db96d56Sopenharmony_ci    if (p == &refchain) {
20607db96d56Sopenharmony_ci        /* Not found */
20617db96d56Sopenharmony_ci        _PyObject_ASSERT_FAILED_MSG(op,
20627db96d56Sopenharmony_ci                                    "object not found in the objects list");
20637db96d56Sopenharmony_ci    }
20647db96d56Sopenharmony_ci#endif
20657db96d56Sopenharmony_ci
20667db96d56Sopenharmony_ci    op->_ob_next->_ob_prev = op->_ob_prev;
20677db96d56Sopenharmony_ci    op->_ob_prev->_ob_next = op->_ob_next;
20687db96d56Sopenharmony_ci    op->_ob_next = op->_ob_prev = NULL;
20697db96d56Sopenharmony_ci}
20707db96d56Sopenharmony_ci
20717db96d56Sopenharmony_ci/* Print all live objects.  Because PyObject_Print is called, the
20727db96d56Sopenharmony_ci * interpreter must be in a healthy state.
20737db96d56Sopenharmony_ci */
20747db96d56Sopenharmony_civoid
20757db96d56Sopenharmony_ci_Py_PrintReferences(FILE *fp)
20767db96d56Sopenharmony_ci{
20777db96d56Sopenharmony_ci    PyObject *op;
20787db96d56Sopenharmony_ci    fprintf(fp, "Remaining objects:\n");
20797db96d56Sopenharmony_ci    for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
20807db96d56Sopenharmony_ci        fprintf(fp, "%p [%zd] ", (void *)op, Py_REFCNT(op));
20817db96d56Sopenharmony_ci        if (PyObject_Print(op, fp, 0) != 0) {
20827db96d56Sopenharmony_ci            PyErr_Clear();
20837db96d56Sopenharmony_ci        }
20847db96d56Sopenharmony_ci        putc('\n', fp);
20857db96d56Sopenharmony_ci    }
20867db96d56Sopenharmony_ci}
20877db96d56Sopenharmony_ci
20887db96d56Sopenharmony_ci/* Print the addresses of all live objects.  Unlike _Py_PrintReferences, this
20897db96d56Sopenharmony_ci * doesn't make any calls to the Python C API, so is always safe to call.
20907db96d56Sopenharmony_ci */
20917db96d56Sopenharmony_civoid
20927db96d56Sopenharmony_ci_Py_PrintReferenceAddresses(FILE *fp)
20937db96d56Sopenharmony_ci{
20947db96d56Sopenharmony_ci    PyObject *op;
20957db96d56Sopenharmony_ci    fprintf(fp, "Remaining object addresses:\n");
20967db96d56Sopenharmony_ci    for (op = refchain._ob_next; op != &refchain; op = op->_ob_next)
20977db96d56Sopenharmony_ci        fprintf(fp, "%p [%zd] %s\n", (void *)op,
20987db96d56Sopenharmony_ci            Py_REFCNT(op), Py_TYPE(op)->tp_name);
20997db96d56Sopenharmony_ci}
21007db96d56Sopenharmony_ci
21017db96d56Sopenharmony_ciPyObject *
21027db96d56Sopenharmony_ci_Py_GetObjects(PyObject *self, PyObject *args)
21037db96d56Sopenharmony_ci{
21047db96d56Sopenharmony_ci    int i, n;
21057db96d56Sopenharmony_ci    PyObject *t = NULL;
21067db96d56Sopenharmony_ci    PyObject *res, *op;
21077db96d56Sopenharmony_ci
21087db96d56Sopenharmony_ci    if (!PyArg_ParseTuple(args, "i|O", &n, &t))
21097db96d56Sopenharmony_ci        return NULL;
21107db96d56Sopenharmony_ci    op = refchain._ob_next;
21117db96d56Sopenharmony_ci    res = PyList_New(0);
21127db96d56Sopenharmony_ci    if (res == NULL)
21137db96d56Sopenharmony_ci        return NULL;
21147db96d56Sopenharmony_ci    for (i = 0; (n == 0 || i < n) && op != &refchain; i++) {
21157db96d56Sopenharmony_ci        while (op == self || op == args || op == res || op == t ||
21167db96d56Sopenharmony_ci               (t != NULL && !Py_IS_TYPE(op, (PyTypeObject *) t))) {
21177db96d56Sopenharmony_ci            op = op->_ob_next;
21187db96d56Sopenharmony_ci            if (op == &refchain)
21197db96d56Sopenharmony_ci                return res;
21207db96d56Sopenharmony_ci        }
21217db96d56Sopenharmony_ci        if (PyList_Append(res, op) < 0) {
21227db96d56Sopenharmony_ci            Py_DECREF(res);
21237db96d56Sopenharmony_ci            return NULL;
21247db96d56Sopenharmony_ci        }
21257db96d56Sopenharmony_ci        op = op->_ob_next;
21267db96d56Sopenharmony_ci    }
21277db96d56Sopenharmony_ci    return res;
21287db96d56Sopenharmony_ci}
21297db96d56Sopenharmony_ci
21307db96d56Sopenharmony_ci#endif
21317db96d56Sopenharmony_ci
21327db96d56Sopenharmony_ci
21337db96d56Sopenharmony_ci/* Hack to force loading of abstract.o */
21347db96d56Sopenharmony_ciPy_ssize_t (*_Py_abstract_hack)(PyObject *) = PyObject_Size;
21357db96d56Sopenharmony_ci
21367db96d56Sopenharmony_ci
21377db96d56Sopenharmony_civoid
21387db96d56Sopenharmony_ci_PyObject_DebugTypeStats(FILE *out)
21397db96d56Sopenharmony_ci{
21407db96d56Sopenharmony_ci    _PyDict_DebugMallocStats(out);
21417db96d56Sopenharmony_ci    _PyFloat_DebugMallocStats(out);
21427db96d56Sopenharmony_ci    _PyList_DebugMallocStats(out);
21437db96d56Sopenharmony_ci    _PyTuple_DebugMallocStats(out);
21447db96d56Sopenharmony_ci}
21457db96d56Sopenharmony_ci
21467db96d56Sopenharmony_ci/* These methods are used to control infinite recursion in repr, str, print,
21477db96d56Sopenharmony_ci   etc.  Container objects that may recursively contain themselves,
21487db96d56Sopenharmony_ci   e.g. builtin dictionaries and lists, should use Py_ReprEnter() and
21497db96d56Sopenharmony_ci   Py_ReprLeave() to avoid infinite recursion.
21507db96d56Sopenharmony_ci
21517db96d56Sopenharmony_ci   Py_ReprEnter() returns 0 the first time it is called for a particular
21527db96d56Sopenharmony_ci   object and 1 every time thereafter.  It returns -1 if an exception
21537db96d56Sopenharmony_ci   occurred.  Py_ReprLeave() has no return value.
21547db96d56Sopenharmony_ci
21557db96d56Sopenharmony_ci   See dictobject.c and listobject.c for examples of use.
21567db96d56Sopenharmony_ci*/
21577db96d56Sopenharmony_ci
21587db96d56Sopenharmony_ciint
21597db96d56Sopenharmony_ciPy_ReprEnter(PyObject *obj)
21607db96d56Sopenharmony_ci{
21617db96d56Sopenharmony_ci    PyObject *dict;
21627db96d56Sopenharmony_ci    PyObject *list;
21637db96d56Sopenharmony_ci    Py_ssize_t i;
21647db96d56Sopenharmony_ci
21657db96d56Sopenharmony_ci    dict = PyThreadState_GetDict();
21667db96d56Sopenharmony_ci    /* Ignore a missing thread-state, so that this function can be called
21677db96d56Sopenharmony_ci       early on startup. */
21687db96d56Sopenharmony_ci    if (dict == NULL)
21697db96d56Sopenharmony_ci        return 0;
21707db96d56Sopenharmony_ci    list = PyDict_GetItemWithError(dict, &_Py_ID(Py_Repr));
21717db96d56Sopenharmony_ci    if (list == NULL) {
21727db96d56Sopenharmony_ci        if (PyErr_Occurred()) {
21737db96d56Sopenharmony_ci            return -1;
21747db96d56Sopenharmony_ci        }
21757db96d56Sopenharmony_ci        list = PyList_New(0);
21767db96d56Sopenharmony_ci        if (list == NULL)
21777db96d56Sopenharmony_ci            return -1;
21787db96d56Sopenharmony_ci        if (PyDict_SetItem(dict, &_Py_ID(Py_Repr), list) < 0)
21797db96d56Sopenharmony_ci            return -1;
21807db96d56Sopenharmony_ci        Py_DECREF(list);
21817db96d56Sopenharmony_ci    }
21827db96d56Sopenharmony_ci    i = PyList_GET_SIZE(list);
21837db96d56Sopenharmony_ci    while (--i >= 0) {
21847db96d56Sopenharmony_ci        if (PyList_GET_ITEM(list, i) == obj)
21857db96d56Sopenharmony_ci            return 1;
21867db96d56Sopenharmony_ci    }
21877db96d56Sopenharmony_ci    if (PyList_Append(list, obj) < 0)
21887db96d56Sopenharmony_ci        return -1;
21897db96d56Sopenharmony_ci    return 0;
21907db96d56Sopenharmony_ci}
21917db96d56Sopenharmony_ci
21927db96d56Sopenharmony_civoid
21937db96d56Sopenharmony_ciPy_ReprLeave(PyObject *obj)
21947db96d56Sopenharmony_ci{
21957db96d56Sopenharmony_ci    PyObject *dict;
21967db96d56Sopenharmony_ci    PyObject *list;
21977db96d56Sopenharmony_ci    Py_ssize_t i;
21987db96d56Sopenharmony_ci    PyObject *error_type, *error_value, *error_traceback;
21997db96d56Sopenharmony_ci
22007db96d56Sopenharmony_ci    PyErr_Fetch(&error_type, &error_value, &error_traceback);
22017db96d56Sopenharmony_ci
22027db96d56Sopenharmony_ci    dict = PyThreadState_GetDict();
22037db96d56Sopenharmony_ci    if (dict == NULL)
22047db96d56Sopenharmony_ci        goto finally;
22057db96d56Sopenharmony_ci
22067db96d56Sopenharmony_ci    list = PyDict_GetItemWithError(dict, &_Py_ID(Py_Repr));
22077db96d56Sopenharmony_ci    if (list == NULL || !PyList_Check(list))
22087db96d56Sopenharmony_ci        goto finally;
22097db96d56Sopenharmony_ci
22107db96d56Sopenharmony_ci    i = PyList_GET_SIZE(list);
22117db96d56Sopenharmony_ci    /* Count backwards because we always expect obj to be list[-1] */
22127db96d56Sopenharmony_ci    while (--i >= 0) {
22137db96d56Sopenharmony_ci        if (PyList_GET_ITEM(list, i) == obj) {
22147db96d56Sopenharmony_ci            PyList_SetSlice(list, i, i + 1, NULL);
22157db96d56Sopenharmony_ci            break;
22167db96d56Sopenharmony_ci        }
22177db96d56Sopenharmony_ci    }
22187db96d56Sopenharmony_ci
22197db96d56Sopenharmony_cifinally:
22207db96d56Sopenharmony_ci    /* ignore exceptions because there is no way to report them. */
22217db96d56Sopenharmony_ci    PyErr_Restore(error_type, error_value, error_traceback);
22227db96d56Sopenharmony_ci}
22237db96d56Sopenharmony_ci
22247db96d56Sopenharmony_ci/* Trashcan support. */
22257db96d56Sopenharmony_ci
22267db96d56Sopenharmony_ci#define _PyTrash_UNWIND_LEVEL 50
22277db96d56Sopenharmony_ci
22287db96d56Sopenharmony_ci/* Add op to the gcstate->trash_delete_later list.  Called when the current
22297db96d56Sopenharmony_ci * call-stack depth gets large.  op must be a currently untracked gc'ed
22307db96d56Sopenharmony_ci * object, with refcount 0.  Py_DECREF must already have been called on it.
22317db96d56Sopenharmony_ci */
22327db96d56Sopenharmony_cistatic void
22337db96d56Sopenharmony_ci_PyTrash_thread_deposit_object(PyObject *op)
22347db96d56Sopenharmony_ci{
22357db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
22367db96d56Sopenharmony_ci    _PyObject_ASSERT(op, _PyObject_IS_GC(op));
22377db96d56Sopenharmony_ci    _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op));
22387db96d56Sopenharmony_ci    _PyObject_ASSERT(op, Py_REFCNT(op) == 0);
22397db96d56Sopenharmony_ci    _PyGCHead_SET_PREV(_Py_AS_GC(op), tstate->trash_delete_later);
22407db96d56Sopenharmony_ci    tstate->trash_delete_later = op;
22417db96d56Sopenharmony_ci}
22427db96d56Sopenharmony_ci
22437db96d56Sopenharmony_ci/* Deallocate all the objects in the gcstate->trash_delete_later list.
22447db96d56Sopenharmony_ci * Called when the call-stack unwinds again. */
22457db96d56Sopenharmony_cistatic void
22467db96d56Sopenharmony_ci_PyTrash_thread_destroy_chain(void)
22477db96d56Sopenharmony_ci{
22487db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
22497db96d56Sopenharmony_ci    /* We need to increase trash_delete_nesting here, otherwise,
22507db96d56Sopenharmony_ci       _PyTrash_thread_destroy_chain will be called recursively
22517db96d56Sopenharmony_ci       and then possibly crash.  An example that may crash without
22527db96d56Sopenharmony_ci       increase:
22537db96d56Sopenharmony_ci           N = 500000  # need to be large enough
22547db96d56Sopenharmony_ci           ob = object()
22557db96d56Sopenharmony_ci           tups = [(ob,) for i in range(N)]
22567db96d56Sopenharmony_ci           for i in range(49):
22577db96d56Sopenharmony_ci               tups = [(tup,) for tup in tups]
22587db96d56Sopenharmony_ci           del tups
22597db96d56Sopenharmony_ci    */
22607db96d56Sopenharmony_ci    assert(tstate->trash_delete_nesting == 0);
22617db96d56Sopenharmony_ci    ++tstate->trash_delete_nesting;
22627db96d56Sopenharmony_ci    while (tstate->trash_delete_later) {
22637db96d56Sopenharmony_ci        PyObject *op = tstate->trash_delete_later;
22647db96d56Sopenharmony_ci        destructor dealloc = Py_TYPE(op)->tp_dealloc;
22657db96d56Sopenharmony_ci
22667db96d56Sopenharmony_ci        tstate->trash_delete_later =
22677db96d56Sopenharmony_ci            (PyObject*) _PyGCHead_PREV(_Py_AS_GC(op));
22687db96d56Sopenharmony_ci
22697db96d56Sopenharmony_ci        /* Call the deallocator directly.  This used to try to
22707db96d56Sopenharmony_ci         * fool Py_DECREF into calling it indirectly, but
22717db96d56Sopenharmony_ci         * Py_DECREF was already called on this object, and in
22727db96d56Sopenharmony_ci         * assorted non-release builds calling Py_DECREF again ends
22737db96d56Sopenharmony_ci         * up distorting allocation statistics.
22747db96d56Sopenharmony_ci         */
22757db96d56Sopenharmony_ci        _PyObject_ASSERT(op, Py_REFCNT(op) == 0);
22767db96d56Sopenharmony_ci        (*dealloc)(op);
22777db96d56Sopenharmony_ci        assert(tstate->trash_delete_nesting == 1);
22787db96d56Sopenharmony_ci    }
22797db96d56Sopenharmony_ci    --tstate->trash_delete_nesting;
22807db96d56Sopenharmony_ci}
22817db96d56Sopenharmony_ci
22827db96d56Sopenharmony_ci
22837db96d56Sopenharmony_ciint
22847db96d56Sopenharmony_ci_PyTrash_begin(PyThreadState *tstate, PyObject *op)
22857db96d56Sopenharmony_ci{
22867db96d56Sopenharmony_ci    if (tstate->trash_delete_nesting >= _PyTrash_UNWIND_LEVEL) {
22877db96d56Sopenharmony_ci        /* Store the object (to be deallocated later) and jump past
22887db96d56Sopenharmony_ci         * Py_TRASHCAN_END, skipping the body of the deallocator */
22897db96d56Sopenharmony_ci        _PyTrash_thread_deposit_object(op);
22907db96d56Sopenharmony_ci        return 1;
22917db96d56Sopenharmony_ci    }
22927db96d56Sopenharmony_ci    ++tstate->trash_delete_nesting;
22937db96d56Sopenharmony_ci    return 0;
22947db96d56Sopenharmony_ci}
22957db96d56Sopenharmony_ci
22967db96d56Sopenharmony_ci
22977db96d56Sopenharmony_civoid
22987db96d56Sopenharmony_ci_PyTrash_end(PyThreadState *tstate)
22997db96d56Sopenharmony_ci{
23007db96d56Sopenharmony_ci    --tstate->trash_delete_nesting;
23017db96d56Sopenharmony_ci    if (tstate->trash_delete_later && tstate->trash_delete_nesting <= 0) {
23027db96d56Sopenharmony_ci        _PyTrash_thread_destroy_chain();
23037db96d56Sopenharmony_ci    }
23047db96d56Sopenharmony_ci}
23057db96d56Sopenharmony_ci
23067db96d56Sopenharmony_ci
23077db96d56Sopenharmony_ci/* bpo-40170: It's only be used in Py_TRASHCAN_BEGIN macro to hide
23087db96d56Sopenharmony_ci   implementation details. */
23097db96d56Sopenharmony_ciint
23107db96d56Sopenharmony_ci_PyTrash_cond(PyObject *op, destructor dealloc)
23117db96d56Sopenharmony_ci{
23127db96d56Sopenharmony_ci    return Py_TYPE(op)->tp_dealloc == dealloc;
23137db96d56Sopenharmony_ci}
23147db96d56Sopenharmony_ci
23157db96d56Sopenharmony_ci
23167db96d56Sopenharmony_civoid _Py_NO_RETURN
23177db96d56Sopenharmony_ci_PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg,
23187db96d56Sopenharmony_ci                       const char *file, int line, const char *function)
23197db96d56Sopenharmony_ci{
23207db96d56Sopenharmony_ci    fprintf(stderr, "%s:%d: ", file, line);
23217db96d56Sopenharmony_ci    if (function) {
23227db96d56Sopenharmony_ci        fprintf(stderr, "%s: ", function);
23237db96d56Sopenharmony_ci    }
23247db96d56Sopenharmony_ci    fflush(stderr);
23257db96d56Sopenharmony_ci
23267db96d56Sopenharmony_ci    if (expr) {
23277db96d56Sopenharmony_ci        fprintf(stderr, "Assertion \"%s\" failed", expr);
23287db96d56Sopenharmony_ci    }
23297db96d56Sopenharmony_ci    else {
23307db96d56Sopenharmony_ci        fprintf(stderr, "Assertion failed");
23317db96d56Sopenharmony_ci    }
23327db96d56Sopenharmony_ci    fflush(stderr);
23337db96d56Sopenharmony_ci
23347db96d56Sopenharmony_ci    if (msg) {
23357db96d56Sopenharmony_ci        fprintf(stderr, ": %s", msg);
23367db96d56Sopenharmony_ci    }
23377db96d56Sopenharmony_ci    fprintf(stderr, "\n");
23387db96d56Sopenharmony_ci    fflush(stderr);
23397db96d56Sopenharmony_ci
23407db96d56Sopenharmony_ci    if (_PyObject_IsFreed(obj)) {
23417db96d56Sopenharmony_ci        /* It seems like the object memory has been freed:
23427db96d56Sopenharmony_ci           don't access it to prevent a segmentation fault. */
23437db96d56Sopenharmony_ci        fprintf(stderr, "<object at %p is freed>\n", obj);
23447db96d56Sopenharmony_ci        fflush(stderr);
23457db96d56Sopenharmony_ci    }
23467db96d56Sopenharmony_ci    else {
23477db96d56Sopenharmony_ci        /* Display the traceback where the object has been allocated.
23487db96d56Sopenharmony_ci           Do it before dumping repr(obj), since repr() is more likely
23497db96d56Sopenharmony_ci           to crash than dumping the traceback. */
23507db96d56Sopenharmony_ci        void *ptr;
23517db96d56Sopenharmony_ci        PyTypeObject *type = Py_TYPE(obj);
23527db96d56Sopenharmony_ci        if (_PyType_IS_GC(type)) {
23537db96d56Sopenharmony_ci            ptr = (void *)((char *)obj - sizeof(PyGC_Head));
23547db96d56Sopenharmony_ci        }
23557db96d56Sopenharmony_ci        else {
23567db96d56Sopenharmony_ci            ptr = (void *)obj;
23577db96d56Sopenharmony_ci        }
23587db96d56Sopenharmony_ci        _PyMem_DumpTraceback(fileno(stderr), ptr);
23597db96d56Sopenharmony_ci
23607db96d56Sopenharmony_ci        /* This might succeed or fail, but we're about to abort, so at least
23617db96d56Sopenharmony_ci           try to provide any extra info we can: */
23627db96d56Sopenharmony_ci        _PyObject_Dump(obj);
23637db96d56Sopenharmony_ci
23647db96d56Sopenharmony_ci        fprintf(stderr, "\n");
23657db96d56Sopenharmony_ci        fflush(stderr);
23667db96d56Sopenharmony_ci    }
23677db96d56Sopenharmony_ci
23687db96d56Sopenharmony_ci    Py_FatalError("_PyObject_AssertFailed");
23697db96d56Sopenharmony_ci}
23707db96d56Sopenharmony_ci
23717db96d56Sopenharmony_ci
23727db96d56Sopenharmony_civoid
23737db96d56Sopenharmony_ci_Py_Dealloc(PyObject *op)
23747db96d56Sopenharmony_ci{
23757db96d56Sopenharmony_ci    PyTypeObject *type = Py_TYPE(op);
23767db96d56Sopenharmony_ci    destructor dealloc = type->tp_dealloc;
23777db96d56Sopenharmony_ci#ifdef Py_DEBUG
23787db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
23797db96d56Sopenharmony_ci    PyObject *old_exc_type = tstate->curexc_type;
23807db96d56Sopenharmony_ci    // Keep the old exception type alive to prevent undefined behavior
23817db96d56Sopenharmony_ci    // on (tstate->curexc_type != old_exc_type) below
23827db96d56Sopenharmony_ci    Py_XINCREF(old_exc_type);
23837db96d56Sopenharmony_ci    // Make sure that type->tp_name remains valid
23847db96d56Sopenharmony_ci    Py_INCREF(type);
23857db96d56Sopenharmony_ci#endif
23867db96d56Sopenharmony_ci
23877db96d56Sopenharmony_ci#ifdef Py_TRACE_REFS
23887db96d56Sopenharmony_ci    _Py_ForgetReference(op);
23897db96d56Sopenharmony_ci#endif
23907db96d56Sopenharmony_ci    (*dealloc)(op);
23917db96d56Sopenharmony_ci
23927db96d56Sopenharmony_ci#ifdef Py_DEBUG
23937db96d56Sopenharmony_ci    // gh-89373: The tp_dealloc function must leave the current exception
23947db96d56Sopenharmony_ci    // unchanged.
23957db96d56Sopenharmony_ci    if (tstate->curexc_type != old_exc_type) {
23967db96d56Sopenharmony_ci        const char *err;
23977db96d56Sopenharmony_ci        if (old_exc_type == NULL) {
23987db96d56Sopenharmony_ci            err = "Deallocator of type '%s' raised an exception";
23997db96d56Sopenharmony_ci        }
24007db96d56Sopenharmony_ci        else if (tstate->curexc_type == NULL) {
24017db96d56Sopenharmony_ci            err = "Deallocator of type '%s' cleared the current exception";
24027db96d56Sopenharmony_ci        }
24037db96d56Sopenharmony_ci        else {
24047db96d56Sopenharmony_ci            // It can happen if dealloc() normalized the current exception.
24057db96d56Sopenharmony_ci            // A deallocator function must not change the current exception,
24067db96d56Sopenharmony_ci            // not even normalize it.
24077db96d56Sopenharmony_ci            err = "Deallocator of type '%s' overrode the current exception";
24087db96d56Sopenharmony_ci        }
24097db96d56Sopenharmony_ci        _Py_FatalErrorFormat(__func__, err, type->tp_name);
24107db96d56Sopenharmony_ci    }
24117db96d56Sopenharmony_ci    Py_XDECREF(old_exc_type);
24127db96d56Sopenharmony_ci    Py_DECREF(type);
24137db96d56Sopenharmony_ci#endif
24147db96d56Sopenharmony_ci}
24157db96d56Sopenharmony_ci
24167db96d56Sopenharmony_ci
24177db96d56Sopenharmony_ciPyObject **
24187db96d56Sopenharmony_ciPyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
24197db96d56Sopenharmony_ci{
24207db96d56Sopenharmony_ci    return _PyObject_GET_WEAKREFS_LISTPTR(op);
24217db96d56Sopenharmony_ci}
24227db96d56Sopenharmony_ci
24237db96d56Sopenharmony_ci
24247db96d56Sopenharmony_ci#undef Py_NewRef
24257db96d56Sopenharmony_ci#undef Py_XNewRef
24267db96d56Sopenharmony_ci
24277db96d56Sopenharmony_ci// Export Py_NewRef() and Py_XNewRef() as regular functions for the stable ABI.
24287db96d56Sopenharmony_ciPyObject*
24297db96d56Sopenharmony_ciPy_NewRef(PyObject *obj)
24307db96d56Sopenharmony_ci{
24317db96d56Sopenharmony_ci    return _Py_NewRef(obj);
24327db96d56Sopenharmony_ci}
24337db96d56Sopenharmony_ci
24347db96d56Sopenharmony_ciPyObject*
24357db96d56Sopenharmony_ciPy_XNewRef(PyObject *obj)
24367db96d56Sopenharmony_ci{
24377db96d56Sopenharmony_ci    return _Py_XNewRef(obj);
24387db96d56Sopenharmony_ci}
24397db96d56Sopenharmony_ci
24407db96d56Sopenharmony_ci#undef Py_Is
24417db96d56Sopenharmony_ci#undef Py_IsNone
24427db96d56Sopenharmony_ci#undef Py_IsTrue
24437db96d56Sopenharmony_ci#undef Py_IsFalse
24447db96d56Sopenharmony_ci
24457db96d56Sopenharmony_ci// Export Py_Is(), Py_IsNone(), Py_IsTrue(), Py_IsFalse() as regular functions
24467db96d56Sopenharmony_ci// for the stable ABI.
24477db96d56Sopenharmony_ciint Py_Is(PyObject *x, PyObject *y)
24487db96d56Sopenharmony_ci{
24497db96d56Sopenharmony_ci    return (x == y);
24507db96d56Sopenharmony_ci}
24517db96d56Sopenharmony_ci
24527db96d56Sopenharmony_ciint Py_IsNone(PyObject *x)
24537db96d56Sopenharmony_ci{
24547db96d56Sopenharmony_ci    return Py_Is(x, Py_None);
24557db96d56Sopenharmony_ci}
24567db96d56Sopenharmony_ci
24577db96d56Sopenharmony_ciint Py_IsTrue(PyObject *x)
24587db96d56Sopenharmony_ci{
24597db96d56Sopenharmony_ci    return Py_Is(x, Py_True);
24607db96d56Sopenharmony_ci}
24617db96d56Sopenharmony_ci
24627db96d56Sopenharmony_ciint Py_IsFalse(PyObject *x)
24637db96d56Sopenharmony_ci{
24647db96d56Sopenharmony_ci    return Py_Is(x, Py_False);
24657db96d56Sopenharmony_ci}
24667db96d56Sopenharmony_ci
24677db96d56Sopenharmony_ci#ifdef __cplusplus
24687db96d56Sopenharmony_ci}
24697db96d56Sopenharmony_ci#endif
2470