LCOV - code coverage report
Current view: | top level - Objects - object.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 459 | 930 | 49.4 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 46 | 88 | 52.3 %
|  |  | Branches: | 237 | 515 | 46.0 %

               Branch data     Line data    Source code
           1                 :            :
           2                 :            : /* Generic object operations; and implementation of None */
           3                 :            :
           4                 :            : #include "Python.h"
           5                 :            : #include "pycore_call.h"          // _PyObject_CallNoArgs()
           6                 :            : #include "pycore_ceval.h"         // _Py_EnterRecursiveCallTstate()
           7                 :            : #include "pycore_context.h"       // _PyContextTokenMissing_Type
           8                 :            : #include "pycore_dict.h"          // _PyObject_MakeDictFromInstanceAttributes()
           9                 :            : #include "pycore_floatobject.h"   // _PyFloat_DebugMallocStats()
          10                 :            : #include "pycore_initconfig.h"    // _PyStatus_EXCEPTION()
          11                 :            : #include "pycore_namespace.h"     // _PyNamespace_Type
          12                 :            : #include "pycore_object.h"        // _PyType_CheckConsistency(), _Py_FatalRefcountError()
          13                 :            : #include "pycore_pyerrors.h"      // _PyErr_Occurred()
          14                 :            : #include "pycore_pymem.h"         // _PyMem_IsPtrFreed()
          15                 :            : #include "pycore_pystate.h"       // _PyThreadState_GET()
          16                 :            : #include "pycore_symtable.h"      // PySTEntry_Type
          17                 :            : #include "pycore_unionobject.h"   // _PyUnion_Type
          18                 :            : #include "pycore_interpreteridobject.h"  // _PyInterpreterID_Type
          19                 :            :
          20                 :            : #ifdef Py_LIMITED_API
          21                 :            :    // Prevent recursive call _Py_IncRef() <=> Py_INCREF()
          22                 :            : #  error "Py_LIMITED_API macro must not be defined"
          23                 :            : #endif
          24                 :            :
          25                 :            : #ifdef __cplusplus
          26                 :            : extern "C" {
          27                 :            : #endif
          28                 :            :
          29                 :            : /* Defined in tracemalloc.c */
          30                 :            : extern void _PyMem_DumpTraceback(int fd, const void *ptr);
          31                 :            :
          32                 :            :
          33                 :            : int
          34                 :          0 : _PyObject_CheckConsistency(PyObject *op, int check_content)
          35                 :            : {
          36                 :            : #define CHECK(expr) \
          37                 :            :     do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0)
          38                 :            :
          39         [ #  # ]:          0 :     CHECK(!_PyObject_IsFreed(op));
          40         [ #  # ]:          0 :     CHECK(Py_REFCNT(op) >= 1);
          41                 :            :
          42                 :          0 :     _PyType_CheckConsistency(Py_TYPE(op));
          43                 :            :
          44         [ #  # ]:          0 :     if (PyUnicode_Check(op)) {
          45                 :          0 :         _PyUnicode_CheckConsistency(op, check_content);
          46                 :            :     }
          47         [ #  # ]:          0 :     else if (PyDict_Check(op)) {
          48                 :          0 :         _PyDict_CheckConsistency(op, check_content);
          49                 :            :     }
          50                 :          0 :     return 1;
          51                 :            :
          52                 :            : #undef CHECK
          53                 :            : }
          54                 :            :
          55                 :            :
          56                 :            : #ifdef Py_REF_DEBUG
          57                 :            : Py_ssize_t _Py_RefTotal;
          58                 :            :
          59                 :            : static inline void
          60                 :            : reftotal_increment(void)
          61                 :            : {
          62                 :            :     _Py_RefTotal++;
          63                 :            : }
          64                 :            :
          65                 :            : static inline void
          66                 :            : reftotal_decrement(void)
          67                 :            : {
          68                 :            :     _Py_RefTotal--;
          69                 :            : }
          70                 :            :
          71                 :            : void
          72                 :            : _Py_AddRefTotal(Py_ssize_t n)
          73                 :            : {
          74                 :            :     _Py_RefTotal += n;
          75                 :            : }
          76                 :            :
          77                 :            : Py_ssize_t
          78                 :            : _Py_GetRefTotal(void)
          79                 :            : {
          80                 :            :     return _Py_RefTotal;
          81                 :            : }
          82                 :            :
          83                 :            : void
          84                 :            : _PyDebug_PrintTotalRefs(void) {
          85                 :            :     fprintf(stderr,
          86                 :            :             "[%zd refs, %zd blocks]\n",
          87                 :            :             _Py_GetRefTotal(), _Py_GetAllocatedBlocks());
          88                 :            : }
          89                 :            : #endif /* Py_REF_DEBUG */
          90                 :            :
          91                 :            : /* Object allocation routines used by NEWOBJ and NEWVAROBJ macros.
          92                 :            :    These are used by the individual routines for object creation.
          93                 :            :    Do not call them otherwise, they do not initialize the object! */
          94                 :            :
          95                 :            : #ifdef Py_TRACE_REFS
          96                 :            : /* Head of circular doubly-linked list of all objects.  These are linked
          97                 :            :  * together via the _ob_prev and _ob_next members of a PyObject, which
          98                 :            :  * exist only in a Py_TRACE_REFS build.
          99                 :            :  */
         100                 :            : static PyObject refchain = {&refchain, &refchain};
         101                 :            :
         102                 :            : /* Insert op at the front of the list of all objects.  If force is true,
         103                 :            :  * op is added even if _ob_prev and _ob_next are non-NULL already.  If
         104                 :            :  * force is false amd _ob_prev or _ob_next are non-NULL, do nothing.
         105                 :            :  * force should be true if and only if op points to freshly allocated,
         106                 :            :  * uninitialized memory, or you've unlinked op from the list and are
         107                 :            :  * relinking it into the front.
         108                 :            :  * Note that objects are normally added to the list via _Py_NewReference,
         109                 :            :  * which is called by PyObject_Init.  Not all objects are initialized that
         110                 :            :  * way, though; exceptions include statically allocated type objects, and
         111                 :            :  * statically allocated singletons (like Py_True and Py_None).
         112                 :            :  */
         113                 :            : void
         114                 :            : _Py_AddToAllObjects(PyObject *op, int force)
         115                 :            : {
         116                 :            : #ifdef  Py_DEBUG
         117                 :            :     if (!force) {
         118                 :            :         /* If it's initialized memory, op must be in or out of
         119                 :            :          * the list unambiguously.
         120                 :            :          */
         121                 :            :         _PyObject_ASSERT(op, (op->_ob_prev == NULL) == (op->_ob_next == NULL));
         122                 :            :     }
         123                 :            : #endif
         124                 :            :     if (force || op->_ob_prev == NULL) {
         125                 :            :         op->_ob_next = refchain._ob_next;
         126                 :            :         op->_ob_prev = &refchain;
         127                 :            :         refchain._ob_next->_ob_prev = op;
         128                 :            :         refchain._ob_next = op;
         129                 :            :     }
         130                 :            : }
         131                 :            : #endif  /* Py_TRACE_REFS */
         132                 :            :
         133                 :            : #ifdef Py_REF_DEBUG
         134                 :            : /* Log a fatal error; doesn't return. */
         135                 :            : void
         136                 :            : _Py_NegativeRefcount(const char *filename, int lineno, PyObject *op)
         137                 :            : {
         138                 :            :     _PyObject_AssertFailed(op, NULL, "object has negative ref count",
         139                 :            :                            filename, lineno, __func__);
         140                 :            : }
         141                 :            :
         142                 :            : /* This is exposed strictly for use in Py_INCREF(). */
         143                 :            : PyAPI_FUNC(void)
         144                 :            : _Py_IncRefTotal_DO_NOT_USE_THIS(void)
         145                 :            : {
         146                 :            :     reftotal_increment();
         147                 :            : }
         148                 :            :
         149                 :            : /* This is exposed strictly for use in Py_DECREF(). */
         150                 :            : PyAPI_FUNC(void)
         151                 :            : _Py_DecRefTotal_DO_NOT_USE_THIS(void)
         152                 :            : {
         153                 :            :     reftotal_decrement();
         154                 :            : }
         155                 :            :
         156                 :            : void
         157                 :            : _Py_IncRefTotal(void)
         158                 :            : {
         159                 :            :     reftotal_increment();
         160                 :            : }
         161                 :            :
         162                 :            : void
         163                 :            : _Py_DecRefTotal(void)
         164                 :            : {
         165                 :            :     reftotal_decrement();
         166                 :            : }
         167                 :            :
         168                 :            : #endif /* Py_REF_DEBUG */
         169                 :            :
         170                 :            : void
         171                 :          0 : Py_IncRef(PyObject *o)
         172                 :            : {
         173                 :          0 :     Py_XINCREF(o);
         174                 :          0 : }
         175                 :            :
         176                 :            : void
         177                 :          0 : Py_DecRef(PyObject *o)
         178                 :            : {
         179                 :          0 :     Py_XDECREF(o);
         180                 :          0 : }
         181                 :            :
         182                 :            : void
         183                 :          0 : _Py_IncRef(PyObject *o)
         184                 :            : {
         185                 :            : #ifdef Py_REF_DEBUG
         186                 :            :     reftotal_increment();
         187                 :            : #endif
         188                 :          0 :     Py_INCREF(o);
         189                 :          0 : }
         190                 :            :
         191                 :            : void
         192                 :          0 : _Py_DecRef(PyObject *o)
         193                 :            : {
         194                 :            : #ifdef Py_REF_DEBUG
         195                 :            :     reftotal_decrement();
         196                 :            : #endif
         197                 :          0 :     Py_DECREF(o);
         198                 :          0 : }
         199                 :            :
         200                 :            : PyObject *
         201                 :          0 : PyObject_Init(PyObject *op, PyTypeObject *tp)
         202                 :            : {
         203         [ #  # ]:          0 :     if (op == NULL) {
         204                 :          0 :         return PyErr_NoMemory();
         205                 :            :     }
         206                 :            :
         207                 :          0 :     _PyObject_Init(op, tp);
         208                 :          0 :     return op;
         209                 :            : }
         210                 :            :
         211                 :            : PyVarObject *
         212                 :          0 : PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size)
         213                 :            : {
         214         [ #  # ]:          0 :     if (op == NULL) {
         215                 :          0 :         return (PyVarObject *) PyErr_NoMemory();
         216                 :            :     }
         217                 :            :
         218                 :          0 :     _PyObject_InitVar(op, tp, size);
         219                 :          0 :     return op;
         220                 :            : }
         221                 :            :
         222                 :            : PyObject *
         223                 :      32994 : _PyObject_New(PyTypeObject *tp)
         224                 :            : {
         225                 :      32994 :     PyObject *op = (PyObject *) PyObject_Malloc(_PyObject_SIZE(tp));
         226         [ -  + ]:      32994 :     if (op == NULL) {
         227                 :          0 :         return PyErr_NoMemory();
         228                 :            :     }
         229                 :      32994 :     _PyObject_Init(op, tp);
         230                 :      32994 :     return op;
         231                 :            : }
         232                 :            :
         233                 :            : PyVarObject *
         234                 :      29166 : _PyObject_NewVar(PyTypeObject *tp, Py_ssize_t nitems)
         235                 :            : {
         236                 :            :     PyVarObject *op;
         237                 :      29166 :     const size_t size = _PyObject_VAR_SIZE(tp, nitems);
         238                 :      29166 :     op = (PyVarObject *) PyObject_Malloc(size);
         239         [ -  + ]:      29166 :     if (op == NULL) {
         240                 :          0 :         return (PyVarObject *)PyErr_NoMemory();
         241                 :            :     }
         242                 :      29166 :     _PyObject_InitVar(op, tp, nitems);
         243                 :      29166 :     return op;
         244                 :            : }
         245                 :            :
         246                 :            : void
         247                 :     126230 : PyObject_CallFinalizer(PyObject *self)
         248                 :            : {
         249                 :     126230 :     PyTypeObject *tp = Py_TYPE(self);
         250                 :            :
         251         [ -  + ]:     126230 :     if (tp->tp_finalize == NULL)
         252                 :          0 :         return;
         253                 :            :     /* tp_finalize should only be called once. */
         254   [ +  +  +  + ]:     126230 :     if (_PyType_IS_GC(tp) && _PyGC_FINALIZED(self))
         255                 :         12 :         return;
         256                 :            :
         257                 :     126218 :     tp->tp_finalize(self);
         258         [ +  + ]:     126218 :     if (_PyType_IS_GC(tp)) {
         259                 :     126163 :         _PyGC_SET_FINALIZED(self);
         260                 :            :     }
         261                 :            : }
         262                 :            :
         263                 :            : int
         264                 :     126230 : PyObject_CallFinalizerFromDealloc(PyObject *self)
         265                 :            : {
         266         [ -  + ]:     126230 :     if (Py_REFCNT(self) != 0) {
         267                 :          0 :         _PyObject_ASSERT_FAILED_MSG(self,
         268                 :            :                                     "PyObject_CallFinalizerFromDealloc called "
         269                 :            :                                     "on object with a non-zero refcount");
         270                 :            :     }
         271                 :            :
         272                 :            :     /* Temporarily resurrect the object. */
         273                 :     126230 :     Py_SET_REFCNT(self, 1);
         274                 :            :
         275                 :     126230 :     PyObject_CallFinalizer(self);
         276                 :            :
         277                 :            :     _PyObject_ASSERT_WITH_MSG(self,
         278                 :            :                               Py_REFCNT(self) > 0,
         279                 :            :                               "refcount is too small");
         280                 :            :
         281                 :            :     /* Undo the temporary resurrection; can't use DECREF here, it would
         282                 :            :      * cause a recursive call. */
         283                 :     126230 :     Py_SET_REFCNT(self, Py_REFCNT(self) - 1);
         284         [ +  - ]:     126230 :     if (Py_REFCNT(self) == 0) {
         285                 :     126230 :         return 0;         /* this is the normal path out */
         286                 :            :     }
         287                 :            :
         288                 :            :     /* tp_finalize resurrected it!  Make it look like the original Py_DECREF
         289                 :            :      * never happened. */
         290                 :          0 :     Py_ssize_t refcnt = Py_REFCNT(self);
         291                 :          0 :     _Py_NewReferenceNoTotal(self);
         292                 :          0 :     Py_SET_REFCNT(self, refcnt);
         293                 :            :
         294                 :            :     _PyObject_ASSERT(self,
         295                 :            :                      (!_PyType_IS_GC(Py_TYPE(self))
         296                 :            :                       || _PyObject_GC_IS_TRACKED(self)));
         297                 :          0 :     return -1;
         298                 :            : }
         299                 :            :
         300                 :            : int
         301                 :          0 : PyObject_Print(PyObject *op, FILE *fp, int flags)
         302                 :            : {
         303                 :          0 :     int ret = 0;
         304         [ #  # ]:          0 :     if (PyErr_CheckSignals())
         305                 :          0 :         return -1;
         306                 :            : #ifdef USE_STACKCHECK
         307                 :            :     if (PyOS_CheckStack()) {
         308                 :            :         PyErr_SetString(PyExc_MemoryError, "stack overflow");
         309                 :            :         return -1;
         310                 :            :     }
         311                 :            : #endif
         312                 :          0 :     clearerr(fp); /* Clear any previous error condition */
         313         [ #  # ]:          0 :     if (op == NULL) {
         314                 :          0 :         Py_BEGIN_ALLOW_THREADS
         315                 :          0 :         fprintf(fp, "<nil>");
         316                 :          0 :         Py_END_ALLOW_THREADS
         317                 :            :     }
         318                 :            :     else {
         319         [ #  # ]:          0 :         if (Py_REFCNT(op) <= 0) {
         320                 :          0 :             Py_BEGIN_ALLOW_THREADS
         321                 :          0 :             fprintf(fp, "<refcnt %zd at %p>", Py_REFCNT(op), (void *)op);
         322                 :          0 :             Py_END_ALLOW_THREADS
         323                 :            :         }
         324                 :            :         else {
         325                 :            :             PyObject *s;
         326         [ #  # ]:          0 :             if (flags & Py_PRINT_RAW)
         327                 :          0 :                 s = PyObject_Str(op);
         328                 :            :             else
         329                 :          0 :                 s = PyObject_Repr(op);
         330         [ #  # ]:          0 :             if (s == NULL) {
         331                 :          0 :                 ret = -1;
         332                 :            :             }
         333                 :            :             else {
         334                 :            :                 assert(PyUnicode_Check(s));
         335                 :            :                 const char *t;
         336                 :            :                 Py_ssize_t len;
         337                 :          0 :                 t = PyUnicode_AsUTF8AndSize(s, &len);
         338         [ #  # ]:          0 :                 if (t == NULL) {
         339                 :          0 :                     ret = -1;
         340                 :            :                 }
         341                 :            :                 else {
         342                 :          0 :                     fwrite(t, 1, len, fp);
         343                 :            :                 }
         344                 :          0 :                 Py_DECREF(s);
         345                 :            :             }
         346                 :            :         }
         347                 :            :     }
         348         [ #  # ]:          0 :     if (ret == 0) {
         349         [ #  # ]:          0 :         if (ferror(fp)) {
         350                 :          0 :             PyErr_SetFromErrno(PyExc_OSError);
         351                 :          0 :             clearerr(fp);
         352                 :          0 :             ret = -1;
         353                 :            :         }
         354                 :            :     }
         355                 :          0 :     return ret;
         356                 :            : }
         357                 :            :
         358                 :            : /* For debugging convenience.  Set a breakpoint here and call it from your DLL */
         359                 :            : void
         360                 :          0 : _Py_BreakPoint(void)
         361                 :            : {
         362                 :          0 : }
         363                 :            :
         364                 :            :
         365                 :            : /* Heuristic checking if the object memory is uninitialized or deallocated.
         366                 :            :    Rely on the debug hooks on Python memory allocators:
         367                 :            :    see _PyMem_IsPtrFreed().
         368                 :            :
         369                 :            :    The function can be used to prevent segmentation fault on dereferencing
         370                 :            :    pointers like 0xDDDDDDDDDDDDDDDD. */
         371                 :            : int
         372                 :          0 : _PyObject_IsFreed(PyObject *op)
         373                 :            : {
         374   [ #  #  #  # ]:          0 :     if (_PyMem_IsPtrFreed(op) || _PyMem_IsPtrFreed(Py_TYPE(op))) {
         375                 :          0 :         return 1;
         376                 :            :     }
         377                 :            :     /* ignore op->ob_ref: its value can have be modified
         378                 :            :        by Py_INCREF() and Py_DECREF(). */
         379                 :            : #ifdef Py_TRACE_REFS
         380                 :            :     if (op->_ob_next != NULL && _PyMem_IsPtrFreed(op->_ob_next)) {
         381                 :            :         return 1;
         382                 :            :     }
         383                 :            :     if (op->_ob_prev != NULL && _PyMem_IsPtrFreed(op->_ob_prev)) {
         384                 :            :          return 1;
         385                 :            :      }
         386                 :            : #endif
         387                 :          0 :     return 0;
         388                 :            : }
         389                 :            :
         390                 :            :
         391                 :            : /* For debugging convenience.  See Misc/gdbinit for some useful gdb hooks */
         392                 :            : void
         393                 :          0 : _PyObject_Dump(PyObject* op)
         394                 :            : {
         395         [ #  # ]:          0 :     if (_PyObject_IsFreed(op)) {
         396                 :            :         /* It seems like the object memory has been freed:
         397                 :            :            don't access it to prevent a segmentation fault. */
         398                 :          0 :         fprintf(stderr, "<object at %p is freed>\n", op);
         399                 :          0 :         fflush(stderr);
         400                 :          0 :         return;
         401                 :            :     }
         402                 :            :
         403                 :            :     /* first, write fields which are the least likely to crash */
         404                 :          0 :     fprintf(stderr, "object address  : %p\n", (void *)op);
         405                 :          0 :     fprintf(stderr, "object refcount : %zd\n", Py_REFCNT(op));
         406                 :          0 :     fflush(stderr);
         407                 :            :
         408                 :          0 :     PyTypeObject *type = Py_TYPE(op);
         409                 :          0 :     fprintf(stderr, "object type     : %p\n", type);
         410         [ #  # ]:          0 :     fprintf(stderr, "object type name: %s\n",
         411                 :            :             type==NULL ? "NULL" : type->tp_name);
         412                 :            :
         413                 :            :     /* the most dangerous part */
         414                 :          0 :     fprintf(stderr, "object repr     : ");
         415                 :          0 :     fflush(stderr);
         416                 :            :
         417                 :          0 :     PyGILState_STATE gil = PyGILState_Ensure();
         418                 :          0 :     PyObject *exc = PyErr_GetRaisedException();
         419                 :            :
         420                 :          0 :     (void)PyObject_Print(op, stderr, 0);
         421                 :          0 :     fflush(stderr);
         422                 :            :
         423                 :          0 :     PyErr_SetRaisedException(exc);
         424                 :          0 :     PyGILState_Release(gil);
         425                 :            :
         426                 :          0 :     fprintf(stderr, "\n");
         427                 :          0 :     fflush(stderr);
         428                 :            : }
         429                 :            :
         430                 :            : PyObject *
         431                 :     170825 : PyObject_Repr(PyObject *v)
         432                 :            : {
         433                 :            :     PyObject *res;
         434         [ -  + ]:     170825 :     if (PyErr_CheckSignals())
         435                 :          0 :         return NULL;
         436                 :            : #ifdef USE_STACKCHECK
         437                 :            :     if (PyOS_CheckStack()) {
         438                 :            :         PyErr_SetString(PyExc_MemoryError, "stack overflow");
         439                 :            :         return NULL;
         440                 :            :     }
         441                 :            : #endif
         442         [ -  + ]:     170825 :     if (v == NULL)
         443                 :          0 :         return PyUnicode_FromString("<NULL>");
         444         [ -  + ]:     170825 :     if (Py_TYPE(v)->tp_repr == NULL)
         445                 :          0 :         return PyUnicode_FromFormat("<%s object at %p>",
         446                 :          0 :                                     Py_TYPE(v)->tp_name, v);
         447                 :            :
         448                 :     170825 :     PyThreadState *tstate = _PyThreadState_GET();
         449                 :            : #ifdef Py_DEBUG
         450                 :            :     /* PyObject_Repr() must not be called with an exception set,
         451                 :            :        because it can clear it (directly or indirectly) and so the
         452                 :            :        caller loses its exception */
         453                 :            :     assert(!_PyErr_Occurred(tstate));
         454                 :            : #endif
         455                 :            :
         456                 :            :     /* It is possible for a type to have a tp_repr representation that loops
         457                 :            :        infinitely. */
         458         [ -  + ]:     170825 :     if (_Py_EnterRecursiveCallTstate(tstate,
         459                 :            :                                      " while getting the repr of an object")) {
         460                 :          0 :         return NULL;
         461                 :            :     }
         462                 :     170825 :     res = (*Py_TYPE(v)->tp_repr)(v);
         463                 :     170825 :     _Py_LeaveRecursiveCallTstate(tstate);
         464                 :            :
         465         [ -  + ]:     170825 :     if (res == NULL) {
         466                 :          0 :         return NULL;
         467                 :            :     }
         468         [ -  + ]:     170825 :     if (!PyUnicode_Check(res)) {
         469                 :          0 :         _PyErr_Format(tstate, PyExc_TypeError,
         470                 :            :                       "__repr__ returned non-string (type %.200s)",
         471                 :          0 :                       Py_TYPE(res)->tp_name);
         472                 :          0 :         Py_DECREF(res);
         473                 :          0 :         return NULL;
         474                 :            :     }
         475                 :            : #ifndef Py_DEBUG
         476         [ -  + ]:     170825 :     if (PyUnicode_READY(res) < 0) {
         477                 :          0 :         return NULL;
         478                 :            :     }
         479                 :            : #endif
         480                 :     170825 :     return res;
         481                 :            : }
         482                 :            :
         483                 :            : PyObject *
         484                 :     303823 : PyObject_Str(PyObject *v)
         485                 :            : {
         486                 :            :     PyObject *res;
         487         [ -  + ]:     303823 :     if (PyErr_CheckSignals())
         488                 :          0 :         return NULL;
         489                 :            : #ifdef USE_STACKCHECK
         490                 :            :     if (PyOS_CheckStack()) {
         491                 :            :         PyErr_SetString(PyExc_MemoryError, "stack overflow");
         492                 :            :         return NULL;
         493                 :            :     }
         494                 :            : #endif
         495         [ -  + ]:     303823 :     if (v == NULL)
         496                 :          0 :         return PyUnicode_FromString("<NULL>");
         497         [ +  + ]:     303823 :     if (PyUnicode_CheckExact(v)) {
         498                 :            : #ifndef Py_DEBUG
         499         [ -  + ]:       5648 :         if (PyUnicode_READY(v) < 0)
         500                 :          0 :             return NULL;
         501                 :            : #endif
         502                 :       5648 :         return Py_NewRef(v);
         503                 :            :     }
         504         [ -  + ]:     298175 :     if (Py_TYPE(v)->tp_str == NULL)
         505                 :          0 :         return PyObject_Repr(v);
         506                 :            :
         507                 :     298175 :     PyThreadState *tstate = _PyThreadState_GET();
         508                 :            : #ifdef Py_DEBUG
         509                 :            :     /* PyObject_Str() must not be called with an exception set,
         510                 :            :        because it can clear it (directly or indirectly) and so the
         511                 :            :        caller loses its exception */
         512                 :            :     assert(!_PyErr_Occurred(tstate));
         513                 :            : #endif
         514                 :            :
         515                 :            :     /* It is possible for a type to have a tp_str representation that loops
         516                 :            :        infinitely. */
         517         [ -  + ]:     298175 :     if (_Py_EnterRecursiveCallTstate(tstate, " while getting the str of an object")) {
         518                 :          0 :         return NULL;
         519                 :            :     }
         520                 :     298175 :     res = (*Py_TYPE(v)->tp_str)(v);
         521                 :     298175 :     _Py_LeaveRecursiveCallTstate(tstate);
         522                 :            :
         523         [ -  + ]:     298175 :     if (res == NULL) {
         524                 :          0 :         return NULL;
         525                 :            :     }
         526         [ -  + ]:     298175 :     if (!PyUnicode_Check(res)) {
         527                 :          0 :         _PyErr_Format(tstate, PyExc_TypeError,
         528                 :            :                       "__str__ returned non-string (type %.200s)",
         529                 :          0 :                       Py_TYPE(res)->tp_name);
         530                 :          0 :         Py_DECREF(res);
         531                 :          0 :         return NULL;
         532                 :            :     }
         533                 :            : #ifndef Py_DEBUG
         534         [ -  + ]:     298175 :     if (PyUnicode_READY(res) < 0) {
         535                 :          0 :         return NULL;
         536                 :            :     }
         537                 :            : #endif
         538                 :            :     assert(_PyUnicode_CheckConsistency(res, 1));
         539                 :     298175 :     return res;
         540                 :            : }
         541                 :            :
         542                 :            : PyObject *
         543                 :          0 : PyObject_ASCII(PyObject *v)
         544                 :            : {
         545                 :            :     PyObject *repr, *ascii, *res;
         546                 :            :
         547                 :          0 :     repr = PyObject_Repr(v);
         548         [ #  # ]:          0 :     if (repr == NULL)
         549                 :          0 :         return NULL;
         550                 :            :
         551         [ #  # ]:          0 :     if (PyUnicode_IS_ASCII(repr))
         552                 :          0 :         return repr;
         553                 :            :
         554                 :            :     /* repr is guaranteed to be a PyUnicode object by PyObject_Repr */
         555                 :          0 :     ascii = _PyUnicode_AsASCIIString(repr, "backslashreplace");
         556                 :          0 :     Py_DECREF(repr);
         557         [ #  # ]:          0 :     if (ascii == NULL)
         558                 :          0 :         return NULL;
         559                 :            :
         560                 :          0 :     res = PyUnicode_DecodeASCII(
         561                 :          0 :         PyBytes_AS_STRING(ascii),
         562                 :            :         PyBytes_GET_SIZE(ascii),
         563                 :            :         NULL);
         564                 :            :
         565                 :          0 :     Py_DECREF(ascii);
         566                 :          0 :     return res;
         567                 :            : }
         568                 :            :
         569                 :            : PyObject *
         570                 :       1183 : PyObject_Bytes(PyObject *v)
         571                 :            : {
         572                 :            :     PyObject *result, *func;
         573                 :            :
         574         [ -  + ]:       1183 :     if (v == NULL)
         575                 :          0 :         return PyBytes_FromString("<NULL>");
         576                 :            :
         577         [ +  - ]:       1183 :     if (PyBytes_CheckExact(v)) {
         578                 :       1183 :         return Py_NewRef(v);
         579                 :            :     }
         580                 :            :
         581                 :          0 :     func = _PyObject_LookupSpecial(v, &_Py_ID(__bytes__));
         582         [ #  # ]:          0 :     if (func != NULL) {
         583                 :          0 :         result = _PyObject_CallNoArgs(func);
         584                 :          0 :         Py_DECREF(func);
         585         [ #  # ]:          0 :         if (result == NULL)
         586                 :          0 :             return NULL;
         587         [ #  # ]:          0 :         if (!PyBytes_Check(result)) {
         588                 :          0 :             PyErr_Format(PyExc_TypeError,
         589                 :            :                          "__bytes__ returned non-bytes (type %.200s)",
         590                 :          0 :                          Py_TYPE(result)->tp_name);
         591                 :          0 :             Py_DECREF(result);
         592                 :          0 :             return NULL;
         593                 :            :         }
         594                 :          0 :         return result;
         595                 :            :     }
         596         [ #  # ]:          0 :     else if (PyErr_Occurred())
         597                 :          0 :         return NULL;
         598                 :          0 :     return PyBytes_FromObject(v);
         599                 :            : }
         600                 :            :
         601                 :            :
         602                 :            : /*
         603                 :            : def _PyObject_FunctionStr(x):
         604                 :            :     try:
         605                 :            :         qualname = x.__qualname__
         606                 :            :     except AttributeError:
         607                 :            :         return str(x)
         608                 :            :     try:
         609                 :            :         mod = x.__module__
         610                 :            :         if mod is not None and mod != 'builtins':
         611                 :            :             return f"{x.__module__}.{qualname}()"
         612                 :            :     except AttributeError:
         613                 :            :         pass
         614                 :            :     return qualname
         615                 :            : */
         616                 :            : PyObject *
         617                 :         32 : _PyObject_FunctionStr(PyObject *x)
         618                 :            : {
         619                 :            :     assert(!PyErr_Occurred());
         620                 :            :     PyObject *qualname;
         621                 :         32 :     int ret = _PyObject_LookupAttr(x, &_Py_ID(__qualname__), &qualname);
         622         [ -  + ]:         32 :     if (qualname == NULL) {
         623         [ #  # ]:          0 :         if (ret < 0) {
         624                 :          0 :             return NULL;
         625                 :            :         }
         626                 :          0 :         return PyObject_Str(x);
         627                 :            :     }
         628                 :            :     PyObject *module;
         629                 :         32 :     PyObject *result = NULL;
         630                 :         32 :     ret = _PyObject_LookupAttr(x, &_Py_ID(__module__), &module);
         631   [ +  -  +  - ]:         32 :     if (module != NULL && module != Py_None) {
         632                 :         32 :         ret = PyObject_RichCompareBool(module, &_Py_ID(builtins), Py_NE);
         633         [ -  + ]:         32 :         if (ret < 0) {
         634                 :            :             // error
         635                 :          0 :             goto done;
         636                 :            :         }
         637         [ +  - ]:         32 :         if (ret > 0) {
         638                 :         32 :             result = PyUnicode_FromFormat("%S.%S()", module, qualname);
         639                 :         32 :             goto done;
         640                 :            :         }
         641                 :            :     }
         642         [ #  # ]:          0 :     else if (ret < 0) {
         643                 :          0 :         goto done;
         644                 :            :     }
         645                 :          0 :     result = PyUnicode_FromFormat("%S()", qualname);
         646                 :         32 : done:
         647                 :         32 :     Py_DECREF(qualname);
         648                 :         32 :     Py_XDECREF(module);
         649                 :         32 :     return result;
         650                 :            : }
         651                 :            :
         652                 :            : /* For Python 3.0.1 and later, the old three-way comparison has been
         653                 :            :    completely removed in favour of rich comparisons.  PyObject_Compare() and
         654                 :            :    PyObject_Cmp() are gone, and the builtin cmp function no longer exists.
         655                 :            :    The old tp_compare slot has been renamed to tp_as_async, and should no
         656                 :            :    longer be used.  Use tp_richcompare instead.
         657                 :            :
         658                 :            :    See (*) below for practical amendments.
         659                 :            :
         660                 :            :    tp_richcompare gets called with a first argument of the appropriate type
         661                 :            :    and a second object of an arbitrary type.  We never do any kind of
         662                 :            :    coercion.
         663                 :            :
         664                 :            :    The tp_richcompare slot should return an object, as follows:
         665                 :            :
         666                 :            :     NULL if an exception occurred
         667                 :            :     NotImplemented if the requested comparison is not implemented
         668                 :            :     any other false value if the requested comparison is false
         669                 :            :     any other true value if the requested comparison is true
         670                 :            :
         671                 :            :   The PyObject_RichCompare[Bool]() wrappers raise TypeError when they get
         672                 :            :   NotImplemented.
         673                 :            :
         674                 :            :   (*) Practical amendments:
         675                 :            :
         676                 :            :   - If rich comparison returns NotImplemented, == and != are decided by
         677                 :            :     comparing the object pointer (i.e. falling back to the base object
         678                 :            :     implementation).
         679                 :            :
         680                 :            : */
         681                 :            :
         682                 :            : /* Map rich comparison operators to their swapped version, e.g. LT <--> GT */
         683                 :            : int _Py_SwappedOp[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE};
         684                 :            :
         685                 :            : static const char * const opstrings[] = {"<", "<=", "==", "!=", ">", ">="};
         686                 :            :
         687                 :            : /* Perform a rich comparison, raising TypeError when the requested comparison
         688                 :            :    operator is not supported. */
         689                 :            : static PyObject *
         690                 :     806531 : do_richcompare(PyThreadState *tstate, PyObject *v, PyObject *w, int op)
         691                 :            : {
         692                 :            :     richcmpfunc f;
         693                 :            :     PyObject *res;
         694                 :     806531 :     int checked_reverse_op = 0;
         695                 :            :
         696   [ +  +  +  + ]:     822621 :     if (!Py_IS_TYPE(v, Py_TYPE(w)) &&
         697                 :      16090 :         PyType_IsSubtype(Py_TYPE(w), Py_TYPE(v)) &&
         698         [ +  - ]:        117 :         (f = Py_TYPE(w)->tp_richcompare) != NULL) {
         699                 :        117 :         checked_reverse_op = 1;
         700                 :        117 :         res = (*f)(w, v, _Py_SwappedOp[op]);
         701         [ +  + ]:        117 :         if (res != Py_NotImplemented)
         702                 :         52 :             return res;
         703                 :         65 :         Py_DECREF(res);
         704                 :            :     }
         705         [ +  + ]:     806479 :     if ((f = Py_TYPE(v)->tp_richcompare) != NULL) {
         706                 :     804064 :         res = (*f)(v, w, op);
         707         [ +  + ]:     804064 :         if (res != Py_NotImplemented)
         708                 :     793024 :             return res;
         709                 :      11040 :         Py_DECREF(res);
         710                 :            :     }
         711   [ +  +  +  + ]:      13455 :     if (!checked_reverse_op && (f = Py_TYPE(w)->tp_richcompare) != NULL) {
         712                 :      13283 :         res = (*f)(w, v, _Py_SwappedOp[op]);
         713         [ +  + ]:      13283 :         if (res != Py_NotImplemented)
         714                 :         15 :             return res;
         715                 :      13268 :         Py_DECREF(res);
         716                 :            :     }
         717                 :            :     /* If neither object implements it, provide a sensible default
         718                 :            :        for == and !=, but raise an exception for ordering. */
         719      [ +  +  - ]:      13440 :     switch (op) {
         720                 :      13436 :     case Py_EQ:
         721         [ -  + ]:      13436 :         res = (v == w) ? Py_True : Py_False;
         722                 :      13436 :         break;
         723                 :          4 :     case Py_NE:
         724         [ +  + ]:          4 :         res = (v != w) ? Py_True : Py_False;
         725                 :          4 :         break;
         726                 :          0 :     default:
         727                 :          0 :         _PyErr_Format(tstate, PyExc_TypeError,
         728                 :            :                       "'%s' not supported between instances of '%.100s' and '%.100s'",
         729                 :            :                       opstrings[op],
         730                 :          0 :                       Py_TYPE(v)->tp_name,
         731                 :          0 :                       Py_TYPE(w)->tp_name);
         732                 :          0 :         return NULL;
         733                 :            :     }
         734                 :      13440 :     return Py_NewRef(res);
         735                 :            : }
         736                 :            :
         737                 :            : /* Perform a rich comparison with object result.  This wraps do_richcompare()
         738                 :            :    with a check for NULL arguments and a recursion check. */
         739                 :            :
         740                 :            : PyObject *
         741                 :     806531 : PyObject_RichCompare(PyObject *v, PyObject *w, int op)
         742                 :            : {
         743                 :     806531 :     PyThreadState *tstate = _PyThreadState_GET();
         744                 :            :
         745                 :            :     assert(Py_LT <= op && op <= Py_GE);
         746   [ +  -  -  + ]:     806531 :     if (v == NULL || w == NULL) {
         747         [ #  # ]:          0 :         if (!_PyErr_Occurred(tstate)) {
         748                 :          0 :             PyErr_BadInternalCall();
         749                 :            :         }
         750                 :          0 :         return NULL;
         751                 :            :     }
         752         [ -  + ]:     806531 :     if (_Py_EnterRecursiveCallTstate(tstate, " in comparison")) {
         753                 :          0 :         return NULL;
         754                 :            :     }
         755                 :     806531 :     PyObject *res = do_richcompare(tstate, v, w, op);
         756                 :     806531 :     _Py_LeaveRecursiveCallTstate(tstate);
         757                 :     806531 :     return res;
         758                 :            : }
         759                 :            :
         760                 :            : /* Perform a rich comparison with integer result.  This wraps
         761                 :            :    PyObject_RichCompare(), returning -1 for error, 0 for false, 1 for true. */
         762                 :            : int
         763                 :    1965491 : PyObject_RichCompareBool(PyObject *v, PyObject *w, int op)
         764                 :            : {
         765                 :            :     PyObject *res;
         766                 :            :     int ok;
         767                 :            :
         768                 :            :     /* Quick result when objects are the same.
         769                 :            :        Guarantees that identity implies equality. */
         770         [ +  + ]:    1965491 :     if (v == w) {
         771         [ +  + ]:    1545136 :         if (op == Py_EQ)
         772                 :    1542589 :             return 1;
         773         [ -  + ]:       2547 :         else if (op == Py_NE)
         774                 :          0 :             return 0;
         775                 :            :     }
         776                 :            :
         777                 :     422902 :     res = PyObject_RichCompare(v, w, op);
         778         [ -  + ]:     422902 :     if (res == NULL)
         779                 :          0 :         return -1;
         780         [ +  - ]:     422902 :     if (PyBool_Check(res))
         781                 :     422902 :         ok = (res == Py_True);
         782                 :            :     else
         783                 :          0 :         ok = PyObject_IsTrue(res);
         784                 :     422902 :     Py_DECREF(res);
         785                 :     422902 :     return ok;
         786                 :            : }
         787                 :            :
         788                 :            : Py_hash_t
         789                 :          0 : PyObject_HashNotImplemented(PyObject *v)
         790                 :            : {
         791                 :          0 :     PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'",
         792                 :          0 :                  Py_TYPE(v)->tp_name);
         793                 :          0 :     return -1;
         794                 :            : }
         795                 :            :
         796                 :            : Py_hash_t
         797                 :    4608352 : PyObject_Hash(PyObject *v)
         798                 :            : {
         799                 :    4608352 :     PyTypeObject *tp = Py_TYPE(v);
         800         [ +  - ]:    4608352 :     if (tp->tp_hash != NULL)
         801                 :    4608352 :         return (*tp->tp_hash)(v);
         802                 :            :     /* To keep to the general practice that inheriting
         803                 :            :      * solely from object in C code should work without
         804                 :            :      * an explicit call to PyType_Ready, we implicitly call
         805                 :            :      * PyType_Ready here and then check the tp_hash slot again
         806                 :            :      */
         807         [ #  # ]:          0 :     if (tp->tp_dict == NULL) {
         808         [ #  # ]:          0 :         if (PyType_Ready(tp) < 0)
         809                 :          0 :             return -1;
         810         [ #  # ]:          0 :         if (tp->tp_hash != NULL)
         811                 :          0 :             return (*tp->tp_hash)(v);
         812                 :            :     }
         813                 :            :     /* Otherwise, the object can't be hashed */
         814                 :          0 :     return PyObject_HashNotImplemented(v);
         815                 :            : }
         816                 :            :
         817                 :            : PyObject *
         818                 :    1446675 : PyObject_GetAttrString(PyObject *v, const char *name)
         819                 :            : {
         820                 :            :     PyObject *w, *res;
         821                 :            :
         822         [ -  + ]:    1446675 :     if (Py_TYPE(v)->tp_getattr != NULL)
         823                 :          0 :         return (*Py_TYPE(v)->tp_getattr)(v, (char*)name);
         824                 :    1446675 :     w = PyUnicode_FromString(name);
         825         [ -  + ]:    1446675 :     if (w == NULL)
         826                 :          0 :         return NULL;
         827                 :    1446675 :     res = PyObject_GetAttr(v, w);
         828                 :    1446675 :     Py_DECREF(w);
         829                 :    1446675 :     return res;
         830                 :            : }
         831                 :            :
         832                 :            : int
         833                 :          0 : PyObject_HasAttrString(PyObject *v, const char *name)
         834                 :            : {
         835                 :          0 :     PyObject *res = PyObject_GetAttrString(v, name);
         836         [ #  # ]:          0 :     if (res != NULL) {
         837                 :          0 :         Py_DECREF(res);
         838                 :          0 :         return 1;
         839                 :            :     }
         840                 :          0 :     PyErr_Clear();
         841                 :          0 :     return 0;
         842                 :            : }
         843                 :            :
         844                 :            : int
         845                 :      12585 : PyObject_SetAttrString(PyObject *v, const char *name, PyObject *w)
         846                 :            : {
         847                 :            :     PyObject *s;
         848                 :            :     int res;
         849                 :            :
         850         [ -  + ]:      12585 :     if (Py_TYPE(v)->tp_setattr != NULL)
         851                 :          0 :         return (*Py_TYPE(v)->tp_setattr)(v, (char*)name, w);
         852                 :      12585 :     s = PyUnicode_InternFromString(name);
         853         [ -  + ]:      12585 :     if (s == NULL)
         854                 :          0 :         return -1;
         855                 :      12585 :     res = PyObject_SetAttr(v, s, w);
         856                 :      12585 :     Py_XDECREF(s);
         857                 :      12585 :     return res;
         858                 :            : }
         859                 :            :
         860                 :            : int
         861                 :       9923 : _PyObject_IsAbstract(PyObject *obj)
         862                 :            : {
         863                 :            :     int res;
         864                 :            :     PyObject* isabstract;
         865                 :            :
         866         [ +  + ]:       9923 :     if (obj == NULL)
         867                 :         74 :         return 0;
         868                 :            :
         869                 :       9849 :     res = _PyObject_LookupAttr(obj, &_Py_ID(__isabstractmethod__), &isabstract);
         870         [ +  + ]:       9849 :     if (res > 0) {
         871                 :       2123 :         res = PyObject_IsTrue(isabstract);
         872                 :       2123 :         Py_DECREF(isabstract);
         873                 :            :     }
         874                 :       9849 :     return res;
         875                 :            : }
         876                 :            :
         877                 :            : PyObject *
         878                 :          0 : _PyObject_GetAttrId(PyObject *v, _Py_Identifier *name)
         879                 :            : {
         880                 :            :     PyObject *result;
         881                 :          0 :     PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
         882         [ #  # ]:          0 :     if (!oname)
         883                 :          0 :         return NULL;
         884                 :          0 :     result = PyObject_GetAttr(v, oname);
         885                 :          0 :     return result;
         886                 :            : }
         887                 :            :
         888                 :            : int
         889                 :          0 : _PyObject_SetAttrId(PyObject *v, _Py_Identifier *name, PyObject *w)
         890                 :            : {
         891                 :            :     int result;
         892                 :          0 :     PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
         893         [ #  # ]:          0 :     if (!oname)
         894                 :          0 :         return -1;
         895                 :          0 :     result = PyObject_SetAttr(v, oname, w);
         896                 :          0 :     return result;
         897                 :            : }
         898                 :            :
         899                 :            : static inline int
         900                 :      13572 : set_attribute_error_context(PyObject* v, PyObject* name)
         901                 :            : {
         902                 :            :     assert(PyErr_Occurred());
         903         [ -  + ]:      13572 :     if (!PyErr_ExceptionMatches(PyExc_AttributeError)){
         904                 :          0 :         return 0;
         905                 :            :     }
         906                 :            :     // Intercept AttributeError exceptions and augment them to offer suggestions later.
         907                 :      13572 :     PyObject *exc = PyErr_GetRaisedException();
         908         [ -  + ]:      13572 :     if (!PyErr_GivenExceptionMatches(exc, PyExc_AttributeError)) {
         909                 :          0 :         goto restore;
         910                 :            :     }
         911                 :      13572 :     PyAttributeErrorObject* the_exc = (PyAttributeErrorObject*) exc;
         912                 :            :     // Check if this exception was already augmented
         913   [ +  +  -  + ]:      13572 :     if (the_exc->name || the_exc->obj) {
         914                 :       4214 :         goto restore;
         915                 :            :     }
         916                 :            :     // Augment the exception with the name and object
         917   [ +  -  -  + ]:      18716 :     if (PyObject_SetAttr(exc, &_Py_ID(name), name) ||
         918                 :       9358 :         PyObject_SetAttr(exc, &_Py_ID(obj), v)) {
         919                 :          0 :         return 1;
         920                 :            :     }
         921                 :       9358 : restore:
         922                 :      13572 :     PyErr_SetRaisedException(exc);
         923                 :      13572 :     return 0;
         924                 :            : }
         925                 :            :
         926                 :            : PyObject *
         927                 :    3690793 : PyObject_GetAttr(PyObject *v, PyObject *name)
         928                 :            : {
         929                 :    3690793 :     PyTypeObject *tp = Py_TYPE(v);
         930         [ -  + ]:    3690793 :     if (!PyUnicode_Check(name)) {
         931                 :          0 :         PyErr_Format(PyExc_TypeError,
         932                 :            :                      "attribute name must be string, not '%.200s'",
         933                 :          0 :                      Py_TYPE(name)->tp_name);
         934                 :          0 :         return NULL;
         935                 :            :     }
         936                 :            :
         937                 :    3690793 :     PyObject* result = NULL;
         938         [ +  - ]:    3690793 :     if (tp->tp_getattro != NULL) {
         939                 :    3690793 :         result = (*tp->tp_getattro)(v, name);
         940                 :            :     }
         941         [ #  # ]:          0 :     else if (tp->tp_getattr != NULL) {
         942                 :          0 :         const char *name_str = PyUnicode_AsUTF8(name);
         943         [ #  # ]:          0 :         if (name_str == NULL) {
         944                 :          0 :             return NULL;
         945                 :            :         }
         946                 :          0 :         result = (*tp->tp_getattr)(v, (char *)name_str);
         947                 :            :     }
         948                 :            :     else {
         949                 :          0 :         PyErr_Format(PyExc_AttributeError,
         950                 :            :                     "'%.50s' object has no attribute '%U'",
         951                 :            :                     tp->tp_name, name);
         952                 :            :     }
         953                 :            :
         954         [ +  + ]:    3690793 :     if (result == NULL) {
         955                 :       4889 :         set_attribute_error_context(v, name);
         956                 :            :     }
         957                 :    3690793 :     return result;
         958                 :            : }
         959                 :            :
         960                 :            : int
         961                 :     330839 : _PyObject_LookupAttr(PyObject *v, PyObject *name, PyObject **result)
         962                 :            : {
         963                 :     330839 :     PyTypeObject *tp = Py_TYPE(v);
         964                 :            :
         965         [ -  + ]:     330839 :     if (!PyUnicode_Check(name)) {
         966                 :          0 :         PyErr_Format(PyExc_TypeError,
         967                 :            :                      "attribute name must be string, not '%.200s'",
         968                 :          0 :                      Py_TYPE(name)->tp_name);
         969                 :          0 :         *result = NULL;
         970                 :          0 :         return -1;
         971                 :            :     }
         972                 :            :
         973         [ +  + ]:     330839 :     if (tp->tp_getattro == PyObject_GenericGetAttr) {
         974                 :     310527 :         *result = _PyObject_GenericGetAttrWithDict(v, name, NULL, 1);
         975         [ +  + ]:     310527 :         if (*result != NULL) {
         976                 :     295101 :             return 1;
         977                 :            :         }
         978         [ -  + ]:      15426 :         if (PyErr_Occurred()) {
         979                 :          0 :             return -1;
         980                 :            :         }
         981                 :      15426 :         return 0;
         982                 :            :     }
         983         [ +  + ]:      20312 :     if (tp->tp_getattro == (getattrofunc)_Py_type_getattro) {
         984                 :       9494 :         int supress_missing_attribute_exception = 0;
         985                 :       9494 :         *result = _Py_type_getattro_impl((PyTypeObject*)v, name, &supress_missing_attribute_exception);
         986         [ +  + ]:       9494 :         if (supress_missing_attribute_exception) {
         987                 :            :             // return 0 without having to clear the exception
         988                 :        371 :             return 0;
         989                 :            :         }
         990                 :            :     }
         991         [ +  - ]:      10818 :     else if (tp->tp_getattro != NULL) {
         992                 :      10818 :         *result = (*tp->tp_getattro)(v, name);
         993                 :            :     }
         994         [ #  # ]:          0 :     else if (tp->tp_getattr != NULL) {
         995                 :          0 :         const char *name_str = PyUnicode_AsUTF8(name);
         996         [ #  # ]:          0 :         if (name_str == NULL) {
         997                 :          0 :             *result = NULL;
         998                 :          0 :             return -1;
         999                 :            :         }
        1000                 :          0 :         *result = (*tp->tp_getattr)(v, (char *)name_str);
        1001                 :            :     }
        1002                 :            :     else {
        1003                 :          0 :         *result = NULL;
        1004                 :          0 :         return 0;
        1005                 :            :     }
        1006                 :            :
        1007         [ +  + ]:      19941 :     if (*result != NULL) {
        1008                 :      15337 :         return 1;
        1009                 :            :     }
        1010         [ -  + ]:       4604 :     if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
        1011                 :          0 :         return -1;
        1012                 :            :     }
        1013                 :       4604 :     PyErr_Clear();
        1014                 :       4604 :     return 0;
        1015                 :            : }
        1016                 :            :
        1017                 :            : int
        1018                 :          0 : _PyObject_LookupAttrId(PyObject *v, _Py_Identifier *name, PyObject **result)
        1019                 :            : {
        1020                 :          0 :     PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
        1021         [ #  # ]:          0 :     if (!oname) {
        1022                 :          0 :         *result = NULL;
        1023                 :          0 :         return -1;
        1024                 :            :     }
        1025                 :          0 :     return  _PyObject_LookupAttr(v, oname, result);
        1026                 :            : }
        1027                 :            :
        1028                 :            : int
        1029                 :          0 : PyObject_HasAttr(PyObject *v, PyObject *name)
        1030                 :            : {
        1031                 :            :     PyObject *res;
        1032         [ #  # ]:          0 :     if (_PyObject_LookupAttr(v, name, &res) < 0) {
        1033                 :          0 :         PyErr_Clear();
        1034                 :          0 :         return 0;
        1035                 :            :     }
        1036         [ #  # ]:          0 :     if (res == NULL) {
        1037                 :          0 :         return 0;
        1038                 :            :     }
        1039                 :          0 :     Py_DECREF(res);
        1040                 :          0 :     return 1;
        1041                 :            : }
        1042                 :            :
        1043                 :            : int
        1044                 :    3221402 : PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
        1045                 :            : {
        1046                 :    3221402 :     PyTypeObject *tp = Py_TYPE(v);
        1047                 :            :     int err;
        1048                 :            :
        1049         [ -  + ]:    3221402 :     if (!PyUnicode_Check(name)) {
        1050                 :          0 :         PyErr_Format(PyExc_TypeError,
        1051                 :            :                      "attribute name must be string, not '%.200s'",
        1052                 :          0 :                      Py_TYPE(name)->tp_name);
        1053                 :          0 :         return -1;
        1054                 :            :     }
        1055                 :    3221402 :     Py_INCREF(name);
        1056                 :            :
        1057                 :    3221402 :     PyUnicode_InternInPlace(&name);
        1058         [ +  - ]:    3221402 :     if (tp->tp_setattro != NULL) {
        1059                 :    3221402 :         err = (*tp->tp_setattro)(v, name, value);
        1060                 :    3221402 :         Py_DECREF(name);
        1061                 :    3221402 :         return err;
        1062                 :            :     }
        1063         [ #  # ]:          0 :     if (tp->tp_setattr != NULL) {
        1064                 :          0 :         const char *name_str = PyUnicode_AsUTF8(name);
        1065         [ #  # ]:          0 :         if (name_str == NULL) {
        1066                 :          0 :             Py_DECREF(name);
        1067                 :          0 :             return -1;
        1068                 :            :         }
        1069                 :          0 :         err = (*tp->tp_setattr)(v, (char *)name_str, value);
        1070                 :          0 :         Py_DECREF(name);
        1071                 :          0 :         return err;
        1072                 :            :     }
        1073                 :          0 :     Py_DECREF(name);
        1074                 :            :     _PyObject_ASSERT(name, Py_REFCNT(name) >= 1);
        1075   [ #  #  #  # ]:          0 :     if (tp->tp_getattr == NULL && tp->tp_getattro == NULL)
        1076         [ #  # ]:          0 :         PyErr_Format(PyExc_TypeError,
        1077                 :            :                      "'%.100s' object has no attributes "
        1078                 :            :                      "(%s .%U)",
        1079                 :            :                      tp->tp_name,
        1080                 :            :                      value==NULL ? "del" : "assign to",
        1081                 :            :                      name);
        1082                 :            :     else
        1083         [ #  # ]:          0 :         PyErr_Format(PyExc_TypeError,
        1084                 :            :                      "'%.100s' object has only read-only attributes "
        1085                 :            :                      "(%s .%U)",
        1086                 :            :                      tp->tp_name,
        1087                 :            :                      value==NULL ? "del" : "assign to",
        1088                 :            :                      name);
        1089                 :          0 :     return -1;
        1090                 :            : }
        1091                 :            :
        1092                 :            : PyObject **
        1093                 :    5071468 : _PyObject_ComputedDictPointer(PyObject *obj)
        1094                 :            : {
        1095                 :    5071468 :     PyTypeObject *tp = Py_TYPE(obj);
        1096                 :            :     assert((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0);
        1097                 :            :
        1098                 :    5071468 :     Py_ssize_t dictoffset = tp->tp_dictoffset;
        1099         [ +  + ]:    5071468 :     if (dictoffset == 0) {
        1100                 :    1459150 :         return NULL;
        1101                 :            :     }
        1102                 :            :
        1103         [ -  + ]:    3612318 :     if (dictoffset < 0) {
        1104                 :            :         assert(dictoffset != -1);
        1105                 :            :
        1106                 :          0 :         Py_ssize_t tsize = Py_SIZE(obj);
        1107         [ #  # ]:          0 :         if (tsize < 0) {
        1108                 :          0 :             tsize = -tsize;
        1109                 :            :         }
        1110                 :          0 :         size_t size = _PyObject_VAR_SIZE(tp, tsize);
        1111                 :            :         assert(size <= (size_t)PY_SSIZE_T_MAX);
        1112                 :          0 :         dictoffset += (Py_ssize_t)size;
        1113                 :            :
        1114                 :            :         _PyObject_ASSERT(obj, dictoffset > 0);
        1115                 :            :         _PyObject_ASSERT(obj, dictoffset % SIZEOF_VOID_P == 0);
        1116                 :            :     }
        1117                 :    3612318 :     return (PyObject **) ((char *)obj + dictoffset);
        1118                 :            : }
        1119                 :            :
        1120                 :            : /* Helper to get a pointer to an object's __dict__ slot, if any.
        1121                 :            :  * Creates the dict from inline attributes if necessary.
        1122                 :            :  * Does not set an exception.
        1123                 :            :  *
        1124                 :            :  * Note that the tp_dictoffset docs used to recommend this function,
        1125                 :            :  * so it should be treated as part of the public API.
        1126                 :            :  */
        1127                 :            : PyObject **
        1128                 :          0 : _PyObject_GetDictPtr(PyObject *obj)
        1129                 :            : {
        1130         [ #  # ]:          0 :     if ((Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) {
        1131                 :          0 :         return _PyObject_ComputedDictPointer(obj);
        1132                 :            :     }
        1133                 :          0 :     PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj);
        1134         [ #  # ]:          0 :     if (_PyDictOrValues_IsValues(*dorv_ptr)) {
        1135                 :          0 :         PyObject *dict = _PyObject_MakeDictFromInstanceAttributes(obj, _PyDictOrValues_GetValues(*dorv_ptr));
        1136         [ #  # ]:          0 :         if (dict == NULL) {
        1137                 :          0 :             PyErr_Clear();
        1138                 :          0 :             return NULL;
        1139                 :            :         }
        1140                 :          0 :         dorv_ptr->dict = dict;
        1141                 :            :     }
        1142                 :          0 :     return &dorv_ptr->dict;
        1143                 :            : }
        1144                 :            :
        1145                 :            : PyObject *
        1146                 :    1767924 : PyObject_SelfIter(PyObject *obj)
        1147                 :            : {
        1148                 :    1767924 :     return Py_NewRef(obj);
        1149                 :            : }
        1150                 :            :
        1151                 :            : /* Helper used when the __next__ method is removed from a type:
        1152                 :            :    tp_iternext is never NULL and can be safely called without checking
        1153                 :            :    on every iteration.
        1154                 :            :  */
        1155                 :            :
        1156                 :            : PyObject *
        1157                 :          0 : _PyObject_NextNotImplemented(PyObject *self)
        1158                 :            : {
        1159                 :          0 :     PyErr_Format(PyExc_TypeError,
        1160                 :            :                  "'%.200s' object is not iterable",
        1161                 :          0 :                  Py_TYPE(self)->tp_name);
        1162                 :          0 :     return NULL;
        1163                 :            : }
        1164                 :            :
        1165                 :            :
        1166                 :            : /* Specialized version of _PyObject_GenericGetAttrWithDict
        1167                 :            :    specifically for the LOAD_METHOD opcode.
        1168                 :            :
        1169                 :            :    Return 1 if a method is found, 0 if it's a regular attribute
        1170                 :            :    from __dict__ or something returned by using a descriptor
        1171                 :            :    protocol.
        1172                 :            :
        1173                 :            :    `method` will point to the resolved attribute or NULL.  In the
        1174                 :            :    latter case, an error will be set.
        1175                 :            : */
        1176                 :            : int
        1177                 :     949240 : _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method)
        1178                 :            : {
        1179                 :     949240 :     int meth_found = 0;
        1180                 :            :
        1181                 :            :     assert(*method == NULL);
        1182                 :            :
        1183                 :     949240 :     PyTypeObject *tp = Py_TYPE(obj);
        1184         [ -  + ]:     949240 :     if (!_PyType_IsReady(tp)) {
        1185         [ #  # ]:          0 :         if (PyType_Ready(tp) < 0) {
        1186                 :          0 :             return 0;
        1187                 :            :         }
        1188                 :            :     }
        1189                 :            :
        1190   [ +  +  -  + ]:     949240 :     if (tp->tp_getattro != PyObject_GenericGetAttr || !PyUnicode_CheckExact(name)) {
        1191                 :     256148 :         *method = PyObject_GetAttr(obj, name);
        1192                 :     256148 :         return 0;
        1193                 :            :     }
        1194                 :            :
        1195                 :     693092 :     PyObject *descr = _PyType_Lookup(tp, name);
        1196                 :     693092 :     descrgetfunc f = NULL;
        1197         [ +  + ]:     693092 :     if (descr != NULL) {
        1198                 :     693011 :         Py_INCREF(descr);
        1199         [ +  + ]:     693011 :         if (_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) {
        1200                 :     688430 :             meth_found = 1;
        1201                 :            :         } else {
        1202                 :       4581 :             f = Py_TYPE(descr)->tp_descr_get;
        1203   [ +  +  +  + ]:       4581 :             if (f != NULL && PyDescr_IsData(descr)) {
        1204                 :          8 :                 *method = f(descr, obj, (PyObject *)Py_TYPE(obj));
        1205                 :          8 :                 Py_DECREF(descr);
        1206                 :          8 :                 return 0;
        1207                 :            :             }
        1208                 :            :         }
        1209                 :            :     }
        1210                 :            :     PyObject *dict;
        1211         [ +  + ]:     693084 :     if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) {
        1212                 :      19311 :         PyDictOrValues* dorv_ptr = _PyObject_DictOrValuesPointer(obj);
        1213         [ +  + ]:      19311 :         if (_PyDictOrValues_IsValues(*dorv_ptr)) {
        1214                 :      12104 :             PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr);
        1215                 :      12104 :             PyObject *attr = _PyObject_GetInstanceAttribute(obj, values, name);
        1216         [ +  + ]:      12104 :             if (attr != NULL) {
        1217                 :         62 :                 *method = attr;
        1218                 :         62 :                 Py_XDECREF(descr);
        1219                 :         62 :                 return 0;
        1220                 :            :             }
        1221                 :      12042 :             dict = NULL;
        1222                 :            :         }
        1223                 :            :         else {
        1224                 :       7207 :             dict = dorv_ptr->dict;
        1225                 :            :         }
        1226                 :            :     }
        1227                 :            :     else {
        1228                 :     673773 :         PyObject **dictptr = _PyObject_ComputedDictPointer(obj);
        1229         [ +  + ]:     673773 :         if (dictptr != NULL) {
        1230                 :     666478 :             dict = *dictptr;
        1231                 :            :         }
        1232                 :            :         else {
        1233                 :       7295 :             dict = NULL;
        1234                 :            :         }
        1235                 :            :     }
        1236         [ +  + ]:     693022 :     if (dict != NULL) {
        1237                 :     662469 :         Py_INCREF(dict);
        1238                 :     662469 :         PyObject *attr = PyDict_GetItemWithError(dict, name);
        1239         [ +  + ]:     662469 :         if (attr != NULL) {
        1240                 :         19 :             *method = Py_NewRef(attr);
        1241                 :         19 :             Py_DECREF(dict);
        1242                 :         19 :             Py_XDECREF(descr);
        1243                 :         19 :             return 0;
        1244                 :            :         }
        1245                 :     662450 :         Py_DECREF(dict);
        1246                 :            :
        1247         [ -  + ]:     662450 :         if (PyErr_Occurred()) {
        1248                 :          0 :             Py_XDECREF(descr);
        1249                 :          0 :             return 0;
        1250                 :            :         }
        1251                 :            :     }
        1252                 :            :
        1253         [ +  + ]:     693003 :     if (meth_found) {
        1254                 :     688430 :         *method = descr;
        1255                 :     688430 :         return 1;
        1256                 :            :     }
        1257                 :            :
        1258         [ +  + ]:       4573 :     if (f != NULL) {
        1259                 :        410 :         *method = f(descr, obj, (PyObject *)Py_TYPE(obj));
        1260                 :        410 :         Py_DECREF(descr);
        1261                 :        410 :         return 0;
        1262                 :            :     }
        1263                 :            :
        1264         [ +  - ]:       4163 :     if (descr != NULL) {
        1265                 :       4163 :         *method = descr;
        1266                 :       4163 :         return 0;
        1267                 :            :     }
        1268                 :            :
        1269                 :          0 :     PyErr_Format(PyExc_AttributeError,
        1270                 :            :                  "'%.50s' object has no attribute '%U'",
        1271                 :            :                  tp->tp_name, name);
        1272                 :            :
        1273                 :          0 :     set_attribute_error_context(obj, name);
        1274                 :          0 :     return 0;
        1275                 :            : }
        1276                 :            :
        1277                 :            : /* Generic GetAttr functions - put these in your tp_[gs]etattro slot. */
        1278                 :            :
        1279                 :            : PyObject *
        1280                 :    3512049 : _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name,
        1281                 :            :                                  PyObject *dict, int suppress)
        1282                 :            : {
        1283                 :            :     /* Make sure the logic of _PyObject_GetMethod is in sync with
        1284                 :            :        this method.
        1285                 :            :
        1286                 :            :        When suppress=1, this function suppresses AttributeError.
        1287                 :            :     */
        1288                 :            :
        1289                 :    3512049 :     PyTypeObject *tp = Py_TYPE(obj);
        1290                 :    3512049 :     PyObject *descr = NULL;
        1291                 :    3512049 :     PyObject *res = NULL;
        1292                 :            :     descrgetfunc f;
        1293                 :            :
        1294         [ -  + ]:    3512049 :     if (!PyUnicode_Check(name)){
        1295                 :          0 :         PyErr_Format(PyExc_TypeError,
        1296                 :            :                      "attribute name must be string, not '%.200s'",
        1297                 :          0 :                      Py_TYPE(name)->tp_name);
        1298                 :          0 :         return NULL;
        1299                 :            :     }
        1300                 :    3512049 :     Py_INCREF(name);
        1301                 :            :
        1302         [ -  + ]:    3512049 :     if (tp->tp_dict == NULL) {
        1303         [ #  # ]:          0 :         if (PyType_Ready(tp) < 0)
        1304                 :          0 :             goto done;
        1305                 :            :     }
        1306                 :            :
        1307                 :    3512049 :     descr = _PyType_Lookup(tp, name);
        1308                 :            :
        1309                 :    3512049 :     f = NULL;
        1310         [ +  + ]:    3512049 :     if (descr != NULL) {
        1311                 :    2790488 :         Py_INCREF(descr);
        1312                 :    2790488 :         f = Py_TYPE(descr)->tp_descr_get;
        1313   [ +  +  +  + ]:    2790488 :         if (f != NULL && PyDescr_IsData(descr)) {
        1314                 :     706876 :             res = f(descr, obj, (PyObject *)Py_TYPE(obj));
        1315   [ +  +  -  +  :     706876 :             if (res == NULL && suppress &&
                       -  - ]
        1316                 :          0 :                     PyErr_ExceptionMatches(PyExc_AttributeError)) {
        1317                 :          0 :                 PyErr_Clear();
        1318                 :            :             }
        1319                 :     706876 :             goto done;
        1320                 :            :         }
        1321                 :            :     }
        1322         [ +  - ]:    2805173 :     if (dict == NULL) {
        1323         [ +  + ]:    2805173 :         if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) {
        1324                 :     881698 :             PyDictOrValues* dorv_ptr = _PyObject_DictOrValuesPointer(obj);
        1325         [ +  + ]:     881698 :             if (_PyDictOrValues_IsValues(*dorv_ptr)) {
        1326                 :     191511 :                 PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr);
        1327         [ +  - ]:     191511 :                 if (PyUnicode_CheckExact(name)) {
        1328                 :     191511 :                     res = _PyObject_GetInstanceAttribute(obj, values, name);
        1329         [ +  + ]:     191511 :                     if (res != NULL) {
        1330                 :      16296 :                         goto done;
        1331                 :            :                     }
        1332                 :            :                 }
        1333                 :            :                 else {
        1334                 :          0 :                     dict = _PyObject_MakeDictFromInstanceAttributes(obj, values);
        1335         [ #  # ]:          0 :                     if (dict == NULL) {
        1336                 :          0 :                         res = NULL;
        1337                 :          0 :                         goto done;
        1338                 :            :                     }
        1339                 :          0 :                     dorv_ptr->dict = dict;
        1340                 :            :                 }
        1341                 :            :             }
        1342                 :            :             else {
        1343                 :     690187 :                 dict = _PyDictOrValues_GetDict(*dorv_ptr);
        1344                 :            :             }
        1345                 :            :         }
        1346                 :            :         else {
        1347                 :    1923475 :             PyObject **dictptr = _PyObject_ComputedDictPointer(obj);
        1348         [ +  + ]:    1923475 :             if (dictptr) {
        1349                 :     471620 :                 dict = *dictptr;
        1350                 :            :             }
        1351                 :            :         }
        1352                 :            :     }
        1353         [ +  + ]:    2788877 :     if (dict != NULL) {
        1354                 :    1155647 :         Py_INCREF(dict);
        1355                 :    1155647 :         res = PyDict_GetItemWithError(dict, name);
        1356         [ +  + ]:    1155647 :         if (res != NULL) {
        1357                 :     684407 :             Py_INCREF(res);
        1358                 :     684407 :             Py_DECREF(dict);
        1359                 :     684407 :             goto done;
        1360                 :            :         }
        1361                 :            :         else {
        1362                 :     471240 :             Py_DECREF(dict);
        1363         [ -  + ]:     471240 :             if (PyErr_Occurred()) {
        1364   [ #  #  #  # ]:          0 :                 if (suppress && PyErr_ExceptionMatches(PyExc_AttributeError)) {
        1365                 :          0 :                     PyErr_Clear();
        1366                 :            :                 }
        1367                 :            :                 else {
        1368                 :          0 :                     goto done;
        1369                 :            :                 }
        1370                 :            :             }
        1371                 :            :         }
        1372                 :            :     }
        1373                 :            :
        1374         [ +  + ]:    2104470 :     if (f != NULL) {
        1375                 :    2063313 :         res = f(descr, obj, (PyObject *)Py_TYPE(obj));
        1376   [ -  +  -  -  :    2063313 :         if (res == NULL && suppress &&
                       -  - ]
        1377                 :          0 :                 PyErr_ExceptionMatches(PyExc_AttributeError)) {
        1378                 :          0 :             PyErr_Clear();
        1379                 :            :         }
        1380                 :    2063313 :         goto done;
        1381                 :            :     }
        1382                 :            :
        1383         [ +  + ]:      41157 :     if (descr != NULL) {
        1384                 :      17023 :         res = descr;
        1385                 :      17023 :         descr = NULL;
        1386                 :      17023 :         goto done;
        1387                 :            :     }
        1388                 :            :
        1389         [ +  + ]:      24134 :     if (!suppress) {
        1390                 :       8683 :         PyErr_Format(PyExc_AttributeError,
        1391                 :            :                      "'%.50s' object has no attribute '%U'",
        1392                 :            :                      tp->tp_name, name);
        1393                 :            :
        1394                 :       8683 :         set_attribute_error_context(obj, name);
        1395                 :            :     }
        1396                 :      15451 :   done:
        1397                 :    3512049 :     Py_XDECREF(descr);
        1398                 :    3512049 :     Py_DECREF(name);
        1399                 :    3512049 :     return res;
        1400                 :            : }
        1401                 :            :
        1402                 :            : PyObject *
        1403                 :    3201143 : PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
        1404                 :            : {
        1405                 :    3201143 :     return _PyObject_GenericGetAttrWithDict(obj, name, NULL, 0);
        1406                 :            : }
        1407                 :            :
        1408                 :            : PyObject *
        1409                 :        379 : _PyObject_GenericTryGetAttr(PyObject *obj, PyObject *name)
        1410                 :            : {
        1411                 :        379 :     return _PyObject_GenericGetAttrWithDict(obj, name, NULL, 1);
        1412                 :            : }
        1413                 :            :
        1414                 :            : int
        1415                 :    3221402 : _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name,
        1416                 :            :                                  PyObject *value, PyObject *dict)
        1417                 :            : {
        1418                 :    3221402 :     PyTypeObject *tp = Py_TYPE(obj);
        1419                 :            :     PyObject *descr;
        1420                 :            :     descrsetfunc f;
        1421                 :    3221402 :     int res = -1;
        1422                 :            :
        1423         [ -  + ]:    3221402 :     if (!PyUnicode_Check(name)){
        1424                 :          0 :         PyErr_Format(PyExc_TypeError,
        1425                 :            :                      "attribute name must be string, not '%.200s'",
        1426                 :          0 :                      Py_TYPE(name)->tp_name);
        1427                 :          0 :         return -1;
        1428                 :            :     }
        1429                 :            :
        1430   [ -  +  -  - ]:    3221402 :     if (tp->tp_dict == NULL && PyType_Ready(tp) < 0)
        1431                 :          0 :         return -1;
        1432                 :            :
        1433                 :    3221402 :     Py_INCREF(name);
        1434                 :    3221402 :     Py_INCREF(tp);
        1435                 :    3221402 :     descr = _PyType_Lookup(tp, name);
        1436                 :            :
        1437         [ +  + ]:    3221402 :     if (descr != NULL) {
        1438                 :    1356789 :         Py_INCREF(descr);
        1439                 :    1356789 :         f = Py_TYPE(descr)->tp_descr_set;
        1440         [ +  + ]:    1356789 :         if (f != NULL) {
        1441                 :      22238 :             res = f(descr, obj, value);
        1442                 :      22238 :             goto done;
        1443                 :            :         }
        1444                 :            :     }
        1445                 :            :
        1446         [ +  - ]:    3199164 :     if (dict == NULL) {
        1447                 :            :         PyObject **dictptr;
        1448         [ +  + ]:    3199164 :         if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) {
        1449                 :     725661 :             PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj);
        1450         [ +  + ]:     725661 :             if (_PyDictOrValues_IsValues(*dorv_ptr)) {
        1451                 :     410649 :                 res = _PyObject_StoreInstanceAttribute(
        1452                 :            :                     obj, _PyDictOrValues_GetValues(*dorv_ptr), name, value);
        1453                 :     410649 :                 goto error_check;
        1454                 :            :             }
        1455                 :     315012 :             dictptr = &dorv_ptr->dict;
        1456                 :            :         }
        1457                 :            :         else {
        1458                 :    2473503 :             dictptr = _PyObject_ComputedDictPointer(obj);
        1459                 :            :         }
        1460         [ -  + ]:    2788515 :         if (dictptr == NULL) {
        1461         [ #  # ]:          0 :             if (descr == NULL) {
        1462                 :          0 :                 PyErr_Format(PyExc_AttributeError,
        1463                 :            :                             "'%.100s' object has no attribute '%U'",
        1464                 :            :                             tp->tp_name, name);
        1465                 :            :             }
        1466                 :            :             else {
        1467                 :          0 :                 PyErr_Format(PyExc_AttributeError,
        1468                 :            :                             "'%.50s' object attribute '%U' is read-only",
        1469                 :            :                             tp->tp_name, name);
        1470                 :            :             }
        1471                 :          0 :             goto done;
        1472                 :            :         }
        1473                 :            :         else {
        1474                 :    2788515 :             res = _PyObjectDict_SetItem(tp, dictptr, name, value);
        1475                 :            :         }
        1476                 :            :     }
        1477                 :            :     else {
        1478                 :          0 :         Py_INCREF(dict);
        1479         [ #  # ]:          0 :         if (value == NULL)
        1480                 :          0 :             res = PyDict_DelItem(dict, name);
        1481                 :            :         else
        1482                 :          0 :             res = PyDict_SetItem(dict, name, value);
        1483                 :          0 :         Py_DECREF(dict);
        1484                 :            :     }
        1485                 :    3199164 :   error_check:
        1486   [ +  -  -  - ]:    3199164 :     if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
        1487         [ #  # ]:          0 :         if (PyType_IsSubtype(tp, &PyType_Type)) {
        1488                 :          0 :             PyErr_Format(PyExc_AttributeError,
        1489                 :            :                          "type object '%.50s' has no attribute '%U'",
        1490                 :            :                          ((PyTypeObject*)obj)->tp_name, name);
        1491                 :            :         }
        1492                 :            :         else {
        1493                 :          0 :             PyErr_Format(PyExc_AttributeError,
        1494                 :            :                          "'%.100s' object has no attribute '%U'",
        1495                 :            :                          tp->tp_name, name);
        1496                 :            :         }
        1497                 :            :     }
        1498                 :    3199164 :   done:
        1499                 :    3221402 :     Py_XDECREF(descr);
        1500                 :    3221402 :     Py_DECREF(tp);
        1501                 :    3221402 :     Py_DECREF(name);
        1502                 :    3221402 :     return res;
        1503                 :            : }
        1504                 :            :
        1505                 :            : int
        1506                 :    3216538 : PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
        1507                 :            : {
        1508                 :    3216538 :     return _PyObject_GenericSetAttrWithDict(obj, name, value, NULL);
        1509                 :            : }
        1510                 :            :
        1511                 :            : int
        1512                 :          0 : PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context)
        1513                 :            : {
        1514                 :          0 :     PyObject **dictptr = _PyObject_GetDictPtr(obj);
        1515         [ #  # ]:          0 :     if (dictptr == NULL) {
        1516   [ #  #  #  # ]:          0 :         if (_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_MANAGED_DICT) &&
        1517                 :          0 :             _PyDictOrValues_IsValues(*_PyObject_DictOrValuesPointer(obj)))
        1518                 :            :         {
        1519                 :            :             /* Was unable to convert to dict */
        1520                 :          0 :             PyErr_NoMemory();
        1521                 :            :         }
        1522                 :            :         else {
        1523                 :          0 :             PyErr_SetString(PyExc_AttributeError,
        1524                 :            :                             "This object has no __dict__");
        1525                 :            :         }
        1526                 :          0 :         return -1;
        1527                 :            :     }
        1528         [ #  # ]:          0 :     if (value == NULL) {
        1529                 :          0 :         PyErr_SetString(PyExc_TypeError, "cannot delete __dict__");
        1530                 :          0 :         return -1;
        1531                 :            :     }
        1532         [ #  # ]:          0 :     if (!PyDict_Check(value)) {
        1533                 :          0 :         PyErr_Format(PyExc_TypeError,
        1534                 :            :                      "__dict__ must be set to a dictionary, "
        1535                 :          0 :                      "not a '%.200s'", Py_TYPE(value)->tp_name);
        1536                 :          0 :         return -1;
        1537                 :            :     }
        1538                 :          0 :     Py_XSETREF(*dictptr, Py_NewRef(value));
        1539                 :          0 :     return 0;
        1540                 :            : }
        1541                 :            :
        1542                 :            :
        1543                 :            : /* Test a value used as condition, e.g., in a while or if statement.
        1544                 :            :    Return -1 if an error occurred */
        1545                 :            :
        1546                 :            : int
        1547                 :    1371372 : PyObject_IsTrue(PyObject *v)
        1548                 :            : {
        1549                 :            :     Py_ssize_t res;
        1550         [ +  + ]:    1371372 :     if (v == Py_True)
        1551                 :     289967 :         return 1;
        1552         [ +  + ]:    1081405 :     if (v == Py_False)
        1553                 :     446355 :         return 0;
        1554         [ +  + ]:     635050 :     if (v == Py_None)
        1555                 :      27276 :         return 0;
        1556         [ +  + ]:     607774 :     else if (Py_TYPE(v)->tp_as_number != NULL &&
        1557         [ +  + ]:     583010 :              Py_TYPE(v)->tp_as_number->nb_bool != NULL)
        1558                 :     549610 :         res = (*Py_TYPE(v)->tp_as_number->nb_bool)(v);
        1559         [ +  + ]:      58164 :     else if (Py_TYPE(v)->tp_as_mapping != NULL &&
        1560         [ +  + ]:      56844 :              Py_TYPE(v)->tp_as_mapping->mp_length != NULL)
        1561                 :      53216 :         res = (*Py_TYPE(v)->tp_as_mapping->mp_length)(v);
        1562         [ +  + ]:       4948 :     else if (Py_TYPE(v)->tp_as_sequence != NULL &&
        1563         [ +  + ]:       4712 :              Py_TYPE(v)->tp_as_sequence->sq_length != NULL)
        1564                 :       1084 :         res = (*Py_TYPE(v)->tp_as_sequence->sq_length)(v);
        1565                 :            :     else
        1566                 :       3864 :         return 1;
        1567                 :            :     /* if it is negative, it should be either -1 or -2 */
        1568         [ +  + ]:     603910 :     return (res > 0) ? 1 : Py_SAFE_DOWNCAST(res, Py_ssize_t, int);
        1569                 :            : }
        1570                 :            :
        1571                 :            : /* equivalent of 'not v'
        1572                 :            :    Return -1 if an error occurred */
        1573                 :            :
        1574                 :            : int
        1575                 :          0 : PyObject_Not(PyObject *v)
        1576                 :            : {
        1577                 :            :     int res;
        1578                 :          0 :     res = PyObject_IsTrue(v);
        1579         [ #  # ]:          0 :     if (res < 0)
        1580                 :          0 :         return res;
        1581                 :          0 :     return res == 0;
        1582                 :            : }
        1583                 :            :
        1584                 :            : /* Test whether an object can be called */
        1585                 :            :
        1586                 :            : int
        1587                 :       2374 : PyCallable_Check(PyObject *x)
        1588                 :            : {
        1589         [ -  + ]:       2374 :     if (x == NULL)
        1590                 :          0 :         return 0;
        1591                 :       2374 :     return Py_TYPE(x)->tp_call != NULL;
        1592                 :            : }
        1593                 :            :
        1594                 :            :
        1595                 :            : /* Helper for PyObject_Dir without arguments: returns the local scope. */
        1596                 :            : static PyObject *
        1597                 :          0 : _dir_locals(void)
        1598                 :            : {
        1599                 :            :     PyObject *names;
        1600                 :            :     PyObject *locals;
        1601                 :            :
        1602                 :          0 :     locals = PyEval_GetLocals();
        1603         [ #  # ]:          0 :     if (locals == NULL)
        1604                 :          0 :         return NULL;
        1605                 :            :
        1606                 :          0 :     names = PyMapping_Keys(locals);
        1607         [ #  # ]:          0 :     if (!names)
        1608                 :          0 :         return NULL;
        1609         [ #  # ]:          0 :     if (!PyList_Check(names)) {
        1610                 :          0 :         PyErr_Format(PyExc_TypeError,
        1611                 :            :             "dir(): expected keys() of locals to be a list, "
        1612                 :          0 :             "not '%.200s'", Py_TYPE(names)->tp_name);
        1613                 :          0 :         Py_DECREF(names);
        1614                 :          0 :         return NULL;
        1615                 :            :     }
        1616         [ #  # ]:          0 :     if (PyList_Sort(names)) {
        1617                 :          0 :         Py_DECREF(names);
        1618                 :          0 :         return NULL;
        1619                 :            :     }
        1620                 :            :     /* the locals don't need to be DECREF'd */
        1621                 :          0 :     return names;
        1622                 :            : }
        1623                 :            :
        1624                 :            : /* Helper for PyObject_Dir: object introspection. */
        1625                 :            : static PyObject *
        1626                 :         30 : _dir_object(PyObject *obj)
        1627                 :            : {
        1628                 :            :     PyObject *result, *sorted;
        1629                 :         30 :     PyObject *dirfunc = _PyObject_LookupSpecial(obj, &_Py_ID(__dir__));
        1630                 :            :
        1631                 :            :     assert(obj != NULL);
        1632         [ -  + ]:         30 :     if (dirfunc == NULL) {
        1633         [ #  # ]:          0 :         if (!PyErr_Occurred())
        1634                 :          0 :             PyErr_SetString(PyExc_TypeError, "object does not provide __dir__");
        1635                 :          0 :         return NULL;
        1636                 :            :     }
        1637                 :            :     /* use __dir__ */
        1638                 :         30 :     result = _PyObject_CallNoArgs(dirfunc);
        1639                 :         30 :     Py_DECREF(dirfunc);
        1640         [ -  + ]:         30 :     if (result == NULL)
        1641                 :          0 :         return NULL;
        1642                 :            :     /* return sorted(result) */
        1643                 :         30 :     sorted = PySequence_List(result);
        1644                 :         30 :     Py_DECREF(result);
        1645         [ -  + ]:         30 :     if (sorted == NULL)
        1646                 :          0 :         return NULL;
        1647         [ -  + ]:         30 :     if (PyList_Sort(sorted)) {
        1648                 :          0 :         Py_DECREF(sorted);
        1649                 :          0 :         return NULL;
        1650                 :            :     }
        1651                 :         30 :     return sorted;
        1652                 :            : }
        1653                 :            :
        1654                 :            : /* Implementation of dir() -- if obj is NULL, returns the names in the current
        1655                 :            :    (local) scope.  Otherwise, performs introspection of the object: returns a
        1656                 :            :    sorted list of attribute names (supposedly) accessible from the object
        1657                 :            : */
        1658                 :            : PyObject *
        1659                 :         30 : PyObject_Dir(PyObject *obj)
        1660                 :            : {
        1661         [ -  + ]:         30 :     return (obj == NULL) ? _dir_locals() : _dir_object(obj);
        1662                 :            : }
        1663                 :            :
        1664                 :            : /*
        1665                 :            : None is a non-NULL undefined value.
        1666                 :            : There is (and should be!) no way to create other objects of this type,
        1667                 :            : so there is exactly one (which is indestructible, by the way).
        1668                 :            : */
        1669                 :            :
        1670                 :            : /* ARGSUSED */
        1671                 :            : static PyObject *
        1672                 :       3695 : none_repr(PyObject *op)
        1673                 :            : {
        1674                 :       3695 :     return PyUnicode_FromString("None");
        1675                 :            : }
        1676                 :            :
        1677                 :            : static void _Py_NO_RETURN
        1678                 :          0 : none_dealloc(PyObject* Py_UNUSED(ignore))
        1679                 :            : {
        1680                 :          0 :     _Py_FatalRefcountError("deallocating None");
        1681                 :            : }
        1682                 :            :
        1683                 :            : static PyObject *
        1684                 :          0 : none_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
        1685                 :            : {
        1686   [ #  #  #  #  :          0 :     if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) {
                       #  # ]
        1687                 :          0 :         PyErr_SetString(PyExc_TypeError, "NoneType takes no arguments");
        1688                 :          0 :         return NULL;
        1689                 :            :     }
        1690                 :          0 :     Py_RETURN_NONE;
        1691                 :            : }
        1692                 :            :
        1693                 :            : static int
        1694                 :          0 : none_bool(PyObject *v)
        1695                 :            : {
        1696                 :          0 :     return 0;
        1697                 :            : }
        1698                 :            :
        1699                 :     105874 : static Py_hash_t none_hash(PyObject *v)
        1700                 :            : {
        1701                 :     105874 :     return 0xFCA86420;
        1702                 :            : }
        1703                 :            :
        1704                 :            : static PyNumberMethods none_as_number = {
        1705                 :            :     0,                          /* nb_add */
        1706                 :            :     0,                          /* nb_subtract */
        1707                 :            :     0,                          /* nb_multiply */
        1708                 :            :     0,                          /* nb_remainder */
        1709                 :            :     0,                          /* nb_divmod */
        1710                 :            :     0,                          /* nb_power */
        1711                 :            :     0,                          /* nb_negative */
        1712                 :            :     0,                          /* nb_positive */
        1713                 :            :     0,                          /* nb_absolute */
        1714                 :            :     (inquiry)none_bool,         /* nb_bool */
        1715                 :            :     0,                          /* nb_invert */
        1716                 :            :     0,                          /* nb_lshift */
        1717                 :            :     0,                          /* nb_rshift */
        1718                 :            :     0,                          /* nb_and */
        1719                 :            :     0,                          /* nb_xor */
        1720                 :            :     0,                          /* nb_or */
        1721                 :            :     0,                          /* nb_int */
        1722                 :            :     0,                          /* nb_reserved */
        1723                 :            :     0,                          /* nb_float */
        1724                 :            :     0,                          /* nb_inplace_add */
        1725                 :            :     0,                          /* nb_inplace_subtract */
        1726                 :            :     0,                          /* nb_inplace_multiply */
        1727                 :            :     0,                          /* nb_inplace_remainder */
        1728                 :            :     0,                          /* nb_inplace_power */
        1729                 :            :     0,                          /* nb_inplace_lshift */
        1730                 :            :     0,                          /* nb_inplace_rshift */
        1731                 :            :     0,                          /* nb_inplace_and */
        1732                 :            :     0,                          /* nb_inplace_xor */
        1733                 :            :     0,                          /* nb_inplace_or */
        1734                 :            :     0,                          /* nb_floor_divide */
        1735                 :            :     0,                          /* nb_true_divide */
        1736                 :            :     0,                          /* nb_inplace_floor_divide */
        1737                 :            :     0,                          /* nb_inplace_true_divide */
        1738                 :            :     0,                          /* nb_index */
        1739                 :            : };
        1740                 :            :
        1741                 :            : PyTypeObject _PyNone_Type = {
        1742                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
        1743                 :            :     "NoneType",
        1744                 :            :     0,
        1745                 :            :     0,
        1746                 :            :     none_dealloc,       /*tp_dealloc*/ /*never called*/
        1747                 :            :     0,                  /*tp_vectorcall_offset*/
        1748                 :            :     0,                  /*tp_getattr*/
        1749                 :            :     0,                  /*tp_setattr*/
        1750                 :            :     0,                  /*tp_as_async*/
        1751                 :            :     none_repr,          /*tp_repr*/
        1752                 :            :     &none_as_number,    /*tp_as_number*/
        1753                 :            :     0,                  /*tp_as_sequence*/
        1754                 :            :     0,                  /*tp_as_mapping*/
        1755                 :            :     (hashfunc)none_hash,/*tp_hash */
        1756                 :            :     0,                  /*tp_call */
        1757                 :            :     0,                  /*tp_str */
        1758                 :            :     0,                  /*tp_getattro */
        1759                 :            :     0,                  /*tp_setattro */
        1760                 :            :     0,                  /*tp_as_buffer */
        1761                 :            :     Py_TPFLAGS_DEFAULT, /*tp_flags */
        1762                 :            :     0,                  /*tp_doc */
        1763                 :            :     0,                  /*tp_traverse */
        1764                 :            :     0,                  /*tp_clear */
        1765                 :            :     0,                  /*tp_richcompare */
        1766                 :            :     0,                  /*tp_weaklistoffset */
        1767                 :            :     0,                  /*tp_iter */
        1768                 :            :     0,                  /*tp_iternext */
        1769                 :            :     0,                  /*tp_methods */
        1770                 :            :     0,                  /*tp_members */
        1771                 :            :     0,                  /*tp_getset */
        1772                 :            :     0,                  /*tp_base */
        1773                 :            :     0,                  /*tp_dict */
        1774                 :            :     0,                  /*tp_descr_get */
        1775                 :            :     0,                  /*tp_descr_set */
        1776                 :            :     0,                  /*tp_dictoffset */
        1777                 :            :     0,                  /*tp_init */
        1778                 :            :     0,                  /*tp_alloc */
        1779                 :            :     none_new,           /*tp_new */
        1780                 :            : };
        1781                 :            :
        1782                 :            : PyObject _Py_NoneStruct = {
        1783                 :            :   _PyObject_EXTRA_INIT
        1784                 :            :   1, &_PyNone_Type
        1785                 :            : };
        1786                 :            :
        1787                 :            : /* NotImplemented is an object that can be used to signal that an
        1788                 :            :    operation is not implemented for the given type combination. */
        1789                 :            :
        1790                 :            : static PyObject *
        1791                 :          0 : NotImplemented_repr(PyObject *op)
        1792                 :            : {
        1793                 :          0 :     return PyUnicode_FromString("NotImplemented");
        1794                 :            : }
        1795                 :            :
        1796                 :            : static PyObject *
        1797                 :          0 : NotImplemented_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
        1798                 :            : {
        1799                 :          0 :     return PyUnicode_FromString("NotImplemented");
        1800                 :            : }
        1801                 :            :
        1802                 :            : static PyMethodDef notimplemented_methods[] = {
        1803                 :            :     {"__reduce__", NotImplemented_reduce, METH_NOARGS, NULL},
        1804                 :            :     {NULL, NULL}
        1805                 :            : };
        1806                 :            :
        1807                 :            : static PyObject *
        1808                 :          0 : notimplemented_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
        1809                 :            : {
        1810   [ #  #  #  #  :          0 :     if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) {
                       #  # ]
        1811                 :          0 :         PyErr_SetString(PyExc_TypeError, "NotImplementedType takes no arguments");
        1812                 :          0 :         return NULL;
        1813                 :            :     }
        1814                 :          0 :     Py_RETURN_NOTIMPLEMENTED;
        1815                 :            : }
        1816                 :            :
        1817                 :            : static void _Py_NO_RETURN
        1818                 :          0 : notimplemented_dealloc(PyObject* ignore)
        1819                 :            : {
        1820                 :            :     /* This should never get called, but we also don't want to SEGV if
        1821                 :            :      * we accidentally decref NotImplemented out of existence.
        1822                 :            :      */
        1823                 :          0 :     Py_FatalError("deallocating NotImplemented");
        1824                 :            : }
        1825                 :            :
        1826                 :            : static int
        1827                 :          0 : notimplemented_bool(PyObject *v)
        1828                 :            : {
        1829         [ #  # ]:          0 :     if (PyErr_WarnEx(PyExc_DeprecationWarning,
        1830                 :            :                      "NotImplemented should not be used in a boolean context",
        1831                 :            :                      1) < 0)
        1832                 :            :     {
        1833                 :          0 :         return -1;
        1834                 :            :     }
        1835                 :          0 :     return 1;
        1836                 :            : }
        1837                 :            :
        1838                 :            : static PyNumberMethods notimplemented_as_number = {
        1839                 :            :     .nb_bool = notimplemented_bool,
        1840                 :            : };
        1841                 :            :
        1842                 :            : PyTypeObject _PyNotImplemented_Type = {
        1843                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
        1844                 :            :     "NotImplementedType",
        1845                 :            :     0,
        1846                 :            :     0,
        1847                 :            :     notimplemented_dealloc,       /*tp_dealloc*/ /*never called*/
        1848                 :            :     0,                  /*tp_vectorcall_offset*/
        1849                 :            :     0,                  /*tp_getattr*/
        1850                 :            :     0,                  /*tp_setattr*/
        1851                 :            :     0,                  /*tp_as_async*/
        1852                 :            :     NotImplemented_repr,        /*tp_repr*/
        1853                 :            :     &notimplemented_as_number,  /*tp_as_number*/
        1854                 :            :     0,                  /*tp_as_sequence*/
        1855                 :            :     0,                  /*tp_as_mapping*/
        1856                 :            :     0,                  /*tp_hash */
        1857                 :            :     0,                  /*tp_call */
        1858                 :            :     0,                  /*tp_str */
        1859                 :            :     0,                  /*tp_getattro */
        1860                 :            :     0,                  /*tp_setattro */
        1861                 :            :     0,                  /*tp_as_buffer */
        1862                 :            :     Py_TPFLAGS_DEFAULT, /*tp_flags */
        1863                 :            :     0,                  /*tp_doc */
        1864                 :            :     0,                  /*tp_traverse */
        1865                 :            :     0,                  /*tp_clear */
        1866                 :            :     0,                  /*tp_richcompare */
        1867                 :            :     0,                  /*tp_weaklistoffset */
        1868                 :            :     0,                  /*tp_iter */
        1869                 :            :     0,                  /*tp_iternext */
        1870                 :            :     notimplemented_methods, /*tp_methods */
        1871                 :            :     0,                  /*tp_members */
        1872                 :            :     0,                  /*tp_getset */
        1873                 :            :     0,                  /*tp_base */
        1874                 :            :     0,                  /*tp_dict */
        1875                 :            :     0,                  /*tp_descr_get */
        1876                 :            :     0,                  /*tp_descr_set */
        1877                 :            :     0,                  /*tp_dictoffset */
        1878                 :            :     0,                  /*tp_init */
        1879                 :            :     0,                  /*tp_alloc */
        1880                 :            :     notimplemented_new, /*tp_new */
        1881                 :            : };
        1882                 :            :
        1883                 :            : PyObject _Py_NotImplementedStruct = {
        1884                 :            :     _PyObject_EXTRA_INIT
        1885                 :            :     1, &_PyNotImplemented_Type
        1886                 :            : };
        1887                 :            :
        1888                 :            : #ifdef MS_WINDOWS
        1889                 :            : extern PyTypeObject PyHKEY_Type;
        1890                 :            : #endif
        1891                 :            : extern PyTypeObject _Py_GenericAliasIterType;
        1892                 :            : extern PyTypeObject _PyMemoryIter_Type;
        1893                 :            : extern PyTypeObject _PyLineIterator;
        1894                 :            : extern PyTypeObject _PyPositionsIterator;
        1895                 :            :
        1896                 :            : static PyTypeObject* static_types[] = {
        1897                 :            :     // The two most important base types: must be initialized first and
        1898                 :            :     // deallocated last.
        1899                 :            :     &PyBaseObject_Type,
        1900                 :            :     &PyType_Type,
        1901                 :            :
        1902                 :            :     // Static types with base=&PyBaseObject_Type
        1903                 :            :     &PyAsyncGen_Type,
        1904                 :            :     &PyByteArrayIter_Type,
        1905                 :            :     &PyByteArray_Type,
        1906                 :            :     &PyBytesIter_Type,
        1907                 :            :     &PyBytes_Type,
        1908                 :            :     &PyCFunction_Type,
        1909                 :            :     &PyCallIter_Type,
        1910                 :            :     &PyCapsule_Type,
        1911                 :            :     &PyCell_Type,
        1912                 :            :     &PyClassMethodDescr_Type,
        1913                 :            :     &PyClassMethod_Type,
        1914                 :            :     &PyCode_Type,
        1915                 :            :     &PyComplex_Type,
        1916                 :            :     &PyContextToken_Type,
        1917                 :            :     &PyContextVar_Type,
        1918                 :            :     &PyContext_Type,
        1919                 :            :     &PyCoro_Type,
        1920                 :            :     &PyDictItems_Type,
        1921                 :            :     &PyDictIterItem_Type,
        1922                 :            :     &PyDictIterKey_Type,
        1923                 :            :     &PyDictIterValue_Type,
        1924                 :            :     &PyDictKeys_Type,
        1925                 :            :     &PyDictProxy_Type,
        1926                 :            :     &PyDictRevIterItem_Type,
        1927                 :            :     &PyDictRevIterKey_Type,
        1928                 :            :     &PyDictRevIterValue_Type,
        1929                 :            :     &PyDictValues_Type,
        1930                 :            :     &PyDict_Type,
        1931                 :            :     &PyEllipsis_Type,
        1932                 :            :     &PyEnum_Type,
        1933                 :            :     &PyFilter_Type,
        1934                 :            :     &PyFloat_Type,
        1935                 :            :     &PyFrame_Type,
        1936                 :            :     &PyFrozenSet_Type,
        1937                 :            :     &PyFunction_Type,
        1938                 :            :     &PyGen_Type,
        1939                 :            :     &PyGetSetDescr_Type,
        1940                 :            : #ifdef MS_WINDOWS
        1941                 :            :     &PyHKEY_Type,
        1942                 :            : #endif
        1943                 :            :     &PyInstanceMethod_Type,
        1944                 :            :     &PyListIter_Type,
        1945                 :            :     &PyListRevIter_Type,
        1946                 :            :     &PyList_Type,
        1947                 :            :     &PyLongRangeIter_Type,
        1948                 :            :     &PyLong_Type,
        1949                 :            :     &PyMap_Type,
        1950                 :            :     &PyMemberDescr_Type,
        1951                 :            :     &PyMemoryView_Type,
        1952                 :            :     &PyMethodDescr_Type,
        1953                 :            :     &PyMethod_Type,
        1954                 :            :     &PyModuleDef_Type,
        1955                 :            :     &PyModule_Type,
        1956                 :            :     &PyODictIter_Type,
        1957                 :            :     &PyPickleBuffer_Type,
        1958                 :            :     &PyProperty_Type,
        1959                 :            :     &PyRangeIter_Type,
        1960                 :            :     &PyRange_Type,
        1961                 :            :     &PyReversed_Type,
        1962                 :            :     &PySTEntry_Type,
        1963                 :            :     &PySeqIter_Type,
        1964                 :            :     &PySetIter_Type,
        1965                 :            :     &PySet_Type,
        1966                 :            :     &PySlice_Type,
        1967                 :            :     &PyStaticMethod_Type,
        1968                 :            :     &PyStdPrinter_Type,
        1969                 :            :     &PySuper_Type,
        1970                 :            :     &PyTraceBack_Type,
        1971                 :            :     &PyTupleIter_Type,
        1972                 :            :     &PyTuple_Type,
        1973                 :            :     &PyUnicodeIter_Type,
        1974                 :            :     &PyUnicode_Type,
        1975                 :            :     &PyWrapperDescr_Type,
        1976                 :            :     &PyZip_Type,
        1977                 :            :     &Py_GenericAliasType,
        1978                 :            :     &_PyAnextAwaitable_Type,
        1979                 :            :     &_PyAsyncGenASend_Type,
        1980                 :            :     &_PyAsyncGenAThrow_Type,
        1981                 :            :     &_PyAsyncGenWrappedValue_Type,
        1982                 :            :     &_PyContextTokenMissing_Type,
        1983                 :            :     &_PyCoroWrapper_Type,
        1984                 :            :     &_Py_GenericAliasIterType,
        1985                 :            :     &_PyHamtItems_Type,
        1986                 :            :     &_PyHamtKeys_Type,
        1987                 :            :     &_PyHamtValues_Type,
        1988                 :            :     &_PyHamt_ArrayNode_Type,
        1989                 :            :     &_PyHamt_BitmapNode_Type,
        1990                 :            :     &_PyHamt_CollisionNode_Type,
        1991                 :            :     &_PyHamt_Type,
        1992                 :            :     &_PyInterpreterID_Type,
        1993                 :            :     &_PyLineIterator,
        1994                 :            :     &_PyManagedBuffer_Type,
        1995                 :            :     &_PyMemoryIter_Type,
        1996                 :            :     &_PyMethodWrapper_Type,
        1997                 :            :     &_PyNamespace_Type,
        1998                 :            :     &_PyNone_Type,
        1999                 :            :     &_PyNotImplemented_Type,
        2000                 :            :     &_PyPositionsIterator,
        2001                 :            :     &_PyUnicodeASCIIIter_Type,
        2002                 :            :     &_PyUnion_Type,
        2003                 :            :     &_PyWeakref_CallableProxyType,
        2004                 :            :     &_PyWeakref_ProxyType,
        2005                 :            :     &_PyWeakref_RefType,
        2006                 :            :
        2007                 :            :     // subclasses: _PyTypes_FiniTypes() deallocates them before their base
        2008                 :            :     // class
        2009                 :            :     &PyBool_Type,         // base=&PyLong_Type
        2010                 :            :     &PyCMethod_Type,      // base=&PyCFunction_Type
        2011                 :            :     &PyODictItems_Type,   // base=&PyDictItems_Type
        2012                 :            :     &PyODictKeys_Type,    // base=&PyDictKeys_Type
        2013                 :            :     &PyODictValues_Type,  // base=&PyDictValues_Type
        2014                 :            :     &PyODict_Type,        // base=&PyDict_Type
        2015                 :            : };
        2016                 :            :
        2017                 :            :
        2018                 :            : PyStatus
        2019                 :         29 : _PyTypes_InitTypes(PyInterpreterState *interp)
        2020                 :            : {
        2021         [ -  + ]:         29 :     if (!_Py_IsMainInterpreter(interp)) {
        2022                 :          0 :         return _PyStatus_OK();
        2023                 :            :     }
        2024                 :            :
        2025                 :            :     // All other static types (unless initialized elsewhere)
        2026         [ +  + ]:       3161 :     for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
        2027                 :       3132 :         PyTypeObject *type = static_types[i];
        2028         [ -  + ]:       3132 :         if (_PyStaticType_InitBuiltin(type) < 0) {
        2029                 :          0 :             return _PyStatus_ERR("Can't initialize builtin type");
        2030                 :            :         }
        2031                 :            :         if (type == &PyType_Type) {
        2032                 :            :             // Sanitify checks of the two most important types
        2033                 :            :             assert(PyBaseObject_Type.tp_base == NULL);
        2034                 :            :             assert(PyType_Type.tp_base == &PyBaseObject_Type);
        2035                 :            :         }
        2036                 :            :     }
        2037                 :            :
        2038                 :         29 :     return _PyStatus_OK();
        2039                 :            : }
        2040                 :            :
        2041                 :            :
        2042                 :            : // Best-effort function clearing static types.
        2043                 :            : //
        2044                 :            : // Don't deallocate a type if it still has subclasses. If a Py_Finalize()
        2045                 :            : // sub-function is interrupted by CTRL+C or fails with MemoryError, some
        2046                 :            : // subclasses are not cleared properly. Leave the static type unchanged in this
        2047                 :            : // case.
        2048                 :            : void
        2049                 :         25 : _PyTypes_FiniTypes(PyInterpreterState *interp)
        2050                 :            : {
        2051         [ -  + ]:         25 :     if (!_Py_IsMainInterpreter(interp)) {
        2052                 :          0 :         return;
        2053                 :            :     }
        2054                 :            :
        2055                 :            :     // Deallocate types in the reverse order to deallocate subclasses before
        2056                 :            :     // their base classes.
        2057         [ +  + ]:       2725 :     for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types)-1; i>=0; i--) {
        2058                 :       2700 :         PyTypeObject *type = static_types[i];
        2059                 :       2700 :         _PyStaticType_Dealloc(type);
        2060                 :            :     }
        2061                 :            : }
        2062                 :            :
        2063                 :            :
        2064                 :            : static inline void
        2065                 :   28932996 : new_reference(PyObject *op)
        2066                 :            : {
        2067         [ -  + ]:   28932996 :     if (_PyRuntime.tracemalloc.config.tracing) {
        2068                 :          0 :         _PyTraceMalloc_NewReference(op);
        2069                 :            :     }
        2070                 :   28932996 :     Py_SET_REFCNT(op, 1);
        2071                 :            : #ifdef Py_TRACE_REFS
        2072                 :            :     _Py_AddToAllObjects(op, 1);
        2073                 :            : #endif
        2074                 :   28932996 : }
        2075                 :            :
        2076                 :            : void
        2077                 :   28806719 : _Py_NewReference(PyObject *op)
        2078                 :            : {
        2079                 :            : #ifdef Py_REF_DEBUG
        2080                 :            :     reftotal_increment();
        2081                 :            : #endif
        2082                 :   28806719 :     new_reference(op);
        2083                 :   28806719 : }
        2084                 :            :
        2085                 :            : void
        2086                 :     126277 : _Py_NewReferenceNoTotal(PyObject *op)
        2087                 :            : {
        2088                 :     126277 :     new_reference(op);
        2089                 :     126277 : }
        2090                 :            :
        2091                 :            :
        2092                 :            : #ifdef Py_TRACE_REFS
        2093                 :            : void
        2094                 :            : _Py_ForgetReference(PyObject *op)
        2095                 :            : {
        2096                 :            :     if (Py_REFCNT(op) < 0) {
        2097                 :            :         _PyObject_ASSERT_FAILED_MSG(op, "negative refcnt");
        2098                 :            :     }
        2099                 :            :
        2100                 :            :     if (op == &refchain ||
        2101                 :            :         op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op)
        2102                 :            :     {
        2103                 :            :         _PyObject_ASSERT_FAILED_MSG(op, "invalid object chain");
        2104                 :            :     }
        2105                 :            :
        2106                 :            : #ifdef SLOW_UNREF_CHECK
        2107                 :            :     PyObject *p;
        2108                 :            :     for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
        2109                 :            :         if (p == op) {
        2110                 :            :             break;
        2111                 :            :         }
        2112                 :            :     }
        2113                 :            :     if (p == &refchain) {
        2114                 :            :         /* Not found */
        2115                 :            :         _PyObject_ASSERT_FAILED_MSG(op,
        2116                 :            :                                     "object not found in the objects list");
        2117                 :            :     }
        2118                 :            : #endif
        2119                 :            :
        2120                 :            :     op->_ob_next->_ob_prev = op->_ob_prev;
        2121                 :            :     op->_ob_prev->_ob_next = op->_ob_next;
        2122                 :            :     op->_ob_next = op->_ob_prev = NULL;
        2123                 :            : }
        2124                 :            :
        2125                 :            : /* Print all live objects.  Because PyObject_Print is called, the
        2126                 :            :  * interpreter must be in a healthy state.
        2127                 :            :  */
        2128                 :            : void
        2129                 :            : _Py_PrintReferences(FILE *fp)
        2130                 :            : {
        2131                 :            :     PyObject *op;
        2132                 :            :     fprintf(fp, "Remaining objects:\n");
        2133                 :            :     for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
        2134                 :            :         fprintf(fp, "%p [%zd] ", (void *)op, Py_REFCNT(op));
        2135                 :            :         if (PyObject_Print(op, fp, 0) != 0) {
        2136                 :            :             PyErr_Clear();
        2137                 :            :         }
        2138                 :            :         putc('\n', fp);
        2139                 :            :     }
        2140                 :            : }
        2141                 :            :
        2142                 :            : /* Print the addresses of all live objects.  Unlike _Py_PrintReferences, this
        2143                 :            :  * doesn't make any calls to the Python C API, so is always safe to call.
        2144                 :            :  */
        2145                 :            : void
        2146                 :            : _Py_PrintReferenceAddresses(FILE *fp)
        2147                 :            : {
        2148                 :            :     PyObject *op;
        2149                 :            :     fprintf(fp, "Remaining object addresses:\n");
        2150                 :            :     for (op = refchain._ob_next; op != &refchain; op = op->_ob_next)
        2151                 :            :         fprintf(fp, "%p [%zd] %s\n", (void *)op,
        2152                 :            :             Py_REFCNT(op), Py_TYPE(op)->tp_name);
        2153                 :            : }
        2154                 :            :
        2155                 :            : PyObject *
        2156                 :            : _Py_GetObjects(PyObject *self, PyObject *args)
        2157                 :            : {
        2158                 :            :     int i, n;
        2159                 :            :     PyObject *t = NULL;
        2160                 :            :     PyObject *res, *op;
        2161                 :            :
        2162                 :            :     if (!PyArg_ParseTuple(args, "i|O", &n, &t))
        2163                 :            :         return NULL;
        2164                 :            :     op = refchain._ob_next;
        2165                 :            :     res = PyList_New(0);
        2166                 :            :     if (res == NULL)
        2167                 :            :         return NULL;
        2168                 :            :     for (i = 0; (n == 0 || i < n) && op != &refchain; i++) {
        2169                 :            :         while (op == self || op == args || op == res || op == t ||
        2170                 :            :                (t != NULL && !Py_IS_TYPE(op, (PyTypeObject *) t))) {
        2171                 :            :             op = op->_ob_next;
        2172                 :            :             if (op == &refchain)
        2173                 :            :                 return res;
        2174                 :            :         }
        2175                 :            :         if (PyList_Append(res, op) < 0) {
        2176                 :            :             Py_DECREF(res);
        2177                 :            :             return NULL;
        2178                 :            :         }
        2179                 :            :         op = op->_ob_next;
        2180                 :            :     }
        2181                 :            :     return res;
        2182                 :            : }
        2183                 :            :
        2184                 :            : #endif
        2185                 :            :
        2186                 :            :
        2187                 :            : /* Hack to force loading of abstract.o */
        2188                 :            : Py_ssize_t (*_Py_abstract_hack)(PyObject *) = PyObject_Size;
        2189                 :            :
        2190                 :            :
        2191                 :            : void
        2192                 :          0 : _PyObject_DebugTypeStats(FILE *out)
        2193                 :            : {
        2194                 :          0 :     _PyDict_DebugMallocStats(out);
        2195                 :          0 :     _PyFloat_DebugMallocStats(out);
        2196                 :          0 :     _PyList_DebugMallocStats(out);
        2197                 :          0 :     _PyTuple_DebugMallocStats(out);
        2198                 :          0 : }
        2199                 :            :
        2200                 :            : /* These methods are used to control infinite recursion in repr, str, print,
        2201                 :            :    etc.  Container objects that may recursively contain themselves,
        2202                 :            :    e.g. builtin dictionaries and lists, should use Py_ReprEnter() and
        2203                 :            :    Py_ReprLeave() to avoid infinite recursion.
        2204                 :            :
        2205                 :            :    Py_ReprEnter() returns 0 the first time it is called for a particular
        2206                 :            :    object and 1 every time thereafter.  It returns -1 if an exception
        2207                 :            :    occurred.  Py_ReprLeave() has no return value.
        2208                 :            :
        2209                 :            :    See dictobject.c and listobject.c for examples of use.
        2210                 :            : */
        2211                 :            :
        2212                 :            : int
        2213                 :      15104 : Py_ReprEnter(PyObject *obj)
        2214                 :            : {
        2215                 :            :     PyObject *dict;
        2216                 :            :     PyObject *list;
        2217                 :            :     Py_ssize_t i;
        2218                 :            :
        2219                 :      15104 :     dict = PyThreadState_GetDict();
        2220                 :            :     /* Ignore a missing thread-state, so that this function can be called
        2221                 :            :        early on startup. */
        2222         [ -  + ]:      15104 :     if (dict == NULL)
        2223                 :          0 :         return 0;
        2224                 :      15104 :     list = PyDict_GetItemWithError(dict, &_Py_ID(Py_Repr));
        2225         [ +  + ]:      15104 :     if (list == NULL) {
        2226         [ -  + ]:          2 :         if (PyErr_Occurred()) {
        2227                 :          0 :             return -1;
        2228                 :            :         }
        2229                 :          2 :         list = PyList_New(0);
        2230         [ -  + ]:          2 :         if (list == NULL)
        2231                 :          0 :             return -1;
        2232         [ -  + ]:          2 :         if (PyDict_SetItem(dict, &_Py_ID(Py_Repr), list) < 0)
        2233                 :          0 :             return -1;
        2234                 :          2 :         Py_DECREF(list);
        2235                 :            :     }
        2236                 :      15104 :     i = PyList_GET_SIZE(list);
        2237         [ +  + ]:      46238 :     while (--i >= 0) {
        2238         [ -  + ]:      31134 :         if (PyList_GET_ITEM(list, i) == obj)
        2239                 :          0 :             return 1;
        2240                 :            :     }
        2241         [ -  + ]:      15104 :     if (PyList_Append(list, obj) < 0)
        2242                 :          0 :         return -1;
        2243                 :      15104 :     return 0;
        2244                 :            : }
        2245                 :            :
        2246                 :            : void
        2247                 :      15104 : Py_ReprLeave(PyObject *obj)
        2248                 :            : {
        2249                 :            :     PyObject *dict;
        2250                 :            :     PyObject *list;
        2251                 :            :     Py_ssize_t i;
        2252                 :            :
        2253                 :      15104 :     PyObject *exc = PyErr_GetRaisedException();
        2254                 :            :
        2255                 :      15104 :     dict = PyThreadState_GetDict();
        2256         [ -  + ]:      15104 :     if (dict == NULL)
        2257                 :          0 :         goto finally;
        2258                 :            :
        2259                 :      15104 :     list = PyDict_GetItemWithError(dict, &_Py_ID(Py_Repr));
        2260   [ +  -  -  + ]:      15104 :     if (list == NULL || !PyList_Check(list))
        2261                 :          0 :         goto finally;
        2262                 :            :
        2263                 :      15104 :     i = PyList_GET_SIZE(list);
        2264                 :            :     /* Count backwards because we always expect obj to be list[-1] */
        2265         [ +  - ]:      15104 :     while (--i >= 0) {
        2266         [ +  - ]:      15104 :         if (PyList_GET_ITEM(list, i) == obj) {
        2267                 :      15104 :             PyList_SetSlice(list, i, i + 1, NULL);
        2268                 :      15104 :             break;
        2269                 :            :         }
        2270                 :            :     }
        2271                 :            :
        2272                 :          0 : finally:
        2273                 :            :     /* ignore exceptions because there is no way to report them. */
        2274                 :      15104 :     PyErr_SetRaisedException(exc);
        2275                 :      15104 : }
        2276                 :            :
        2277                 :            : /* Trashcan support. */
        2278                 :            :
        2279                 :            : #define _PyTrash_UNWIND_LEVEL 50
        2280                 :            :
        2281                 :            : /* Add op to the gcstate->trash_delete_later list.  Called when the current
        2282                 :            :  * call-stack depth gets large.  op must be a currently untracked gc'ed
        2283                 :            :  * object, with refcount 0.  Py_DECREF must already have been called on it.
        2284                 :            :  */
        2285                 :            : static void
        2286                 :          0 : _PyTrash_thread_deposit_object(struct _py_trashcan *trash, PyObject *op)
        2287                 :            : {
        2288                 :            :     _PyObject_ASSERT(op, _PyObject_IS_GC(op));
        2289                 :            :     _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op));
        2290                 :            :     _PyObject_ASSERT(op, Py_REFCNT(op) == 0);
        2291                 :          0 :     _PyGCHead_SET_PREV(_Py_AS_GC(op), (PyGC_Head*)trash->delete_later);
        2292                 :          0 :     trash->delete_later = op;
        2293                 :          0 : }
        2294                 :            :
        2295                 :            : /* Deallocate all the objects in the gcstate->trash_delete_later list.
        2296                 :            :  * Called when the call-stack unwinds again. */
        2297                 :            : static void
        2298                 :          0 : _PyTrash_thread_destroy_chain(struct _py_trashcan *trash)
        2299                 :            : {
        2300                 :            :     /* We need to increase trash_delete_nesting here, otherwise,
        2301                 :            :        _PyTrash_thread_destroy_chain will be called recursively
        2302                 :            :        and then possibly crash.  An example that may crash without
        2303                 :            :        increase:
        2304                 :            :            N = 500000  # need to be large enough
        2305                 :            :            ob = object()
        2306                 :            :            tups = [(ob,) for i in range(N)]
        2307                 :            :            for i in range(49):
        2308                 :            :                tups = [(tup,) for tup in tups]
        2309                 :            :            del tups
        2310                 :            :     */
        2311                 :            :     assert(trash->delete_nesting == 0);
        2312                 :          0 :     ++trash->delete_nesting;
        2313         [ #  # ]:          0 :     while (trash->delete_later) {
        2314                 :          0 :         PyObject *op = trash->delete_later;
        2315                 :          0 :         destructor dealloc = Py_TYPE(op)->tp_dealloc;
        2316                 :            :
        2317                 :          0 :         trash->delete_later =
        2318                 :          0 :             (PyObject*) _PyGCHead_PREV(_Py_AS_GC(op));
        2319                 :            :
        2320                 :            :         /* Call the deallocator directly.  This used to try to
        2321                 :            :          * fool Py_DECREF into calling it indirectly, but
        2322                 :            :          * Py_DECREF was already called on this object, and in
        2323                 :            :          * assorted non-release builds calling Py_DECREF again ends
        2324                 :            :          * up distorting allocation statistics.
        2325                 :            :          */
        2326                 :            :         _PyObject_ASSERT(op, Py_REFCNT(op) == 0);
        2327                 :          0 :         (*dealloc)(op);
        2328                 :            :         assert(trash->delete_nesting == 1);
        2329                 :            :     }
        2330                 :          0 :     --trash->delete_nesting;
        2331                 :          0 : }
        2332                 :            :
        2333                 :            :
        2334                 :            : static struct _py_trashcan *
        2335                 :   14510988 : _PyTrash_get_state(PyThreadState *tstate)
        2336                 :            : {
        2337         [ +  - ]:   14510988 :     if (tstate != NULL) {
        2338                 :   14510988 :         return &tstate->trash;
        2339                 :            :     }
        2340                 :            :     // The current thread must be finalizing.
        2341                 :            :     // Fall back to using thread-local state.
        2342                 :            :     // XXX Use thread-local variable syntax?
        2343                 :            :     assert(PyThread_tss_is_created(&_PyRuntime.trashTSSkey));
        2344                 :            :     struct _py_trashcan *trash =
        2345                 :          0 :         (struct _py_trashcan *)PyThread_tss_get(&_PyRuntime.trashTSSkey);
        2346         [ #  # ]:          0 :     if (trash == NULL) {
        2347                 :          0 :         trash = PyMem_RawMalloc(sizeof(struct _py_trashcan));
        2348         [ #  # ]:          0 :         if (trash == NULL) {
        2349                 :          0 :             Py_FatalError("Out of memory");
        2350                 :            :         }
        2351                 :          0 :         PyThread_tss_set(&_PyRuntime.trashTSSkey, (void *)trash);
        2352                 :            :     }
        2353                 :          0 :     return trash;
        2354                 :            : }
        2355                 :            :
        2356                 :            : static void
        2357                 :    6190566 : _PyTrash_clear_state(PyThreadState *tstate)
        2358                 :            : {
        2359         [ +  - ]:    6190566 :     if (tstate != NULL) {
        2360                 :            :         assert(tstate->trash.delete_later == NULL);
        2361                 :    6190566 :         return;
        2362                 :            :     }
        2363         [ #  # ]:          0 :     if (PyThread_tss_is_created(&_PyRuntime.trashTSSkey)) {
        2364                 :            :         struct _py_trashcan *trash =
        2365                 :          0 :             (struct _py_trashcan *)PyThread_tss_get(&_PyRuntime.trashTSSkey);
        2366         [ #  # ]:          0 :         if (trash != NULL) {
        2367                 :          0 :             PyThread_tss_set(&_PyRuntime.trashTSSkey, (void *)NULL);
        2368                 :          0 :             PyMem_RawFree(trash);
        2369                 :            :         }
        2370                 :            :     }
        2371                 :            : }
        2372                 :            :
        2373                 :            :
        2374                 :            : int
        2375                 :    7255494 : _PyTrash_begin(PyThreadState *tstate, PyObject *op)
        2376                 :            : {
        2377                 :            :     // XXX Make sure the GIL is held.
        2378                 :    7255494 :     struct _py_trashcan *trash = _PyTrash_get_state(tstate);
        2379         [ -  + ]:    7255494 :     if (trash->delete_nesting >= _PyTrash_UNWIND_LEVEL) {
        2380                 :            :         /* Store the object (to be deallocated later) and jump past
        2381                 :            :          * Py_TRASHCAN_END, skipping the body of the deallocator */
        2382                 :          0 :         _PyTrash_thread_deposit_object(trash, op);
        2383                 :          0 :         return 1;
        2384                 :            :     }
        2385                 :    7255494 :     ++trash->delete_nesting;
        2386                 :    7255494 :     return 0;
        2387                 :            : }
        2388                 :            :
        2389                 :            :
        2390                 :            : void
        2391                 :    7255494 : _PyTrash_end(PyThreadState *tstate)
        2392                 :            : {
        2393                 :            :     // XXX Make sure the GIL is held.
        2394                 :    7255494 :     struct _py_trashcan *trash = _PyTrash_get_state(tstate);
        2395                 :    7255494 :     --trash->delete_nesting;
        2396         [ +  + ]:    7255494 :     if (trash->delete_nesting <= 0) {
        2397         [ -  + ]:    6190566 :         if (trash->delete_later != NULL) {
        2398                 :          0 :             _PyTrash_thread_destroy_chain(trash);
        2399                 :            :         }
        2400                 :    6190566 :         _PyTrash_clear_state(tstate);
        2401                 :            :     }
        2402                 :    7255494 : }
        2403                 :            :
        2404                 :            :
        2405                 :            : /* bpo-40170: It's only be used in Py_TRASHCAN_BEGIN macro to hide
        2406                 :            :    implementation details. */
        2407                 :            : int
        2408                 :    7256589 : _PyTrash_cond(PyObject *op, destructor dealloc)
        2409                 :            : {
        2410                 :    7256589 :     return Py_TYPE(op)->tp_dealloc == dealloc;
        2411                 :            : }
        2412                 :            :
        2413                 :            :
        2414                 :            : void _Py_NO_RETURN
        2415                 :          0 : _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg,
        2416                 :            :                        const char *file, int line, const char *function)
        2417                 :            : {
        2418                 :          0 :     fprintf(stderr, "%s:%d: ", file, line);
        2419         [ #  # ]:          0 :     if (function) {
        2420                 :          0 :         fprintf(stderr, "%s: ", function);
        2421                 :            :     }
        2422                 :          0 :     fflush(stderr);
        2423                 :            :
        2424         [ #  # ]:          0 :     if (expr) {
        2425                 :          0 :         fprintf(stderr, "Assertion \"%s\" failed", expr);
        2426                 :            :     }
        2427                 :            :     else {
        2428                 :          0 :         fprintf(stderr, "Assertion failed");
        2429                 :            :     }
        2430                 :          0 :     fflush(stderr);
        2431                 :            :
        2432         [ #  # ]:          0 :     if (msg) {
        2433                 :          0 :         fprintf(stderr, ": %s", msg);
        2434                 :            :     }
        2435                 :          0 :     fprintf(stderr, "\n");
        2436                 :          0 :     fflush(stderr);
        2437                 :            :
        2438         [ #  # ]:          0 :     if (_PyObject_IsFreed(obj)) {
        2439                 :            :         /* It seems like the object memory has been freed:
        2440                 :            :            don't access it to prevent a segmentation fault. */
        2441                 :          0 :         fprintf(stderr, "<object at %p is freed>\n", obj);
        2442                 :          0 :         fflush(stderr);
        2443                 :            :     }
        2444                 :            :     else {
        2445                 :            :         /* Display the traceback where the object has been allocated.
        2446                 :            :            Do it before dumping repr(obj), since repr() is more likely
        2447                 :            :            to crash than dumping the traceback. */
        2448                 :          0 :         PyTypeObject *type = Py_TYPE(obj);
        2449                 :          0 :         const size_t presize = _PyType_PreHeaderSize(type);
        2450                 :          0 :         void *ptr = (void *)((char *)obj - presize);
        2451                 :          0 :         _PyMem_DumpTraceback(fileno(stderr), ptr);
        2452                 :            :
        2453                 :            :         /* This might succeed or fail, but we're about to abort, so at least
        2454                 :            :            try to provide any extra info we can: */
        2455                 :          0 :         _PyObject_Dump(obj);
        2456                 :            :
        2457                 :          0 :         fprintf(stderr, "\n");
        2458                 :          0 :         fflush(stderr);
        2459                 :            :     }
        2460                 :            :
        2461                 :          0 :     Py_FatalError("_PyObject_AssertFailed");
        2462                 :            : }
        2463                 :            :
        2464                 :            :
        2465                 :            : void
        2466                 :   18024377 : _Py_Dealloc(PyObject *op)
        2467                 :            : {
        2468                 :   18024377 :     PyTypeObject *type = Py_TYPE(op);
        2469                 :   18024377 :     destructor dealloc = type->tp_dealloc;
        2470                 :            : #ifdef Py_DEBUG
        2471                 :            :     PyThreadState *tstate = _PyThreadState_GET();
        2472                 :            :     PyObject *old_exc = tstate != NULL ? tstate->current_exception : NULL;
        2473                 :            :     // Keep the old exception type alive to prevent undefined behavior
        2474                 :            :     // on (tstate->curexc_type != old_exc_type) below
        2475                 :            :     Py_XINCREF(old_exc);
        2476                 :            :     // Make sure that type->tp_name remains valid
        2477                 :            :     Py_INCREF(type);
        2478                 :            : #endif
        2479                 :            :
        2480                 :            : #ifdef Py_TRACE_REFS
        2481                 :            :     _Py_ForgetReference(op);
        2482                 :            : #endif
        2483                 :   18024377 :     (*dealloc)(op);
        2484                 :            :
        2485                 :            : #ifdef Py_DEBUG
        2486                 :            :     // gh-89373: The tp_dealloc function must leave the current exception
        2487                 :            :     // unchanged.
        2488                 :            :     if (tstate != NULL && tstate->current_exception != old_exc) {
        2489                 :            :         const char *err;
        2490                 :            :         if (old_exc == NULL) {
        2491                 :            :             err = "Deallocator of type '%s' raised an exception";
        2492                 :            :         }
        2493                 :            :         else if (tstate->current_exception == NULL) {
        2494                 :            :             err = "Deallocator of type '%s' cleared the current exception";
        2495                 :            :         }
        2496                 :            :         else {
        2497                 :            :             // It can happen if dealloc() normalized the current exception.
        2498                 :            :             // A deallocator function must not change the current exception,
        2499                 :            :             // not even normalize it.
        2500                 :            :             err = "Deallocator of type '%s' overrode the current exception";
        2501                 :            :         }
        2502                 :            :         _Py_FatalErrorFormat(__func__, err, type->tp_name);
        2503                 :            :     }
        2504                 :            :     Py_XDECREF(old_exc);
        2505                 :            :     Py_DECREF(type);
        2506                 :            : #endif
        2507                 :   18024377 : }
        2508                 :            :
        2509                 :            :
        2510                 :            : PyObject **
        2511                 :          0 : PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
        2512                 :            : {
        2513                 :          0 :     return _PyObject_GET_WEAKREFS_LISTPTR(op);
        2514                 :            : }
        2515                 :            :
        2516                 :            :
        2517                 :            : #undef Py_NewRef
        2518                 :            : #undef Py_XNewRef
        2519                 :            :
        2520                 :            : // Export Py_NewRef() and Py_XNewRef() as regular functions for the stable ABI.
        2521                 :            : PyObject*
        2522                 :          0 : Py_NewRef(PyObject *obj)
        2523                 :            : {
        2524                 :          0 :     return _Py_NewRef(obj);
        2525                 :            : }
        2526                 :            :
        2527                 :            : PyObject*
        2528                 :          0 : Py_XNewRef(PyObject *obj)
        2529                 :            : {
        2530                 :          0 :     return _Py_XNewRef(obj);
        2531                 :            : }
        2532                 :            :
        2533                 :            : #undef Py_Is
        2534                 :            : #undef Py_IsNone
        2535                 :            : #undef Py_IsTrue
        2536                 :            : #undef Py_IsFalse
        2537                 :            :
        2538                 :            : // Export Py_Is(), Py_IsNone(), Py_IsTrue(), Py_IsFalse() as regular functions
        2539                 :            : // for the stable ABI.
        2540                 :          0 : int Py_Is(PyObject *x, PyObject *y)
        2541                 :            : {
        2542                 :          0 :     return (x == y);
        2543                 :            : }
        2544                 :            :
        2545                 :          0 : int Py_IsNone(PyObject *x)
        2546                 :            : {
        2547                 :          0 :     return Py_Is(x, Py_None);
        2548                 :            : }
        2549                 :            :
        2550                 :          0 : int Py_IsTrue(PyObject *x)
        2551                 :            : {
        2552                 :          0 :     return Py_Is(x, Py_True);
        2553                 :            : }
        2554                 :            :
        2555                 :          0 : int Py_IsFalse(PyObject *x)
        2556                 :            : {
        2557                 :          0 :     return Py_Is(x, Py_False);
        2558                 :            : }
        2559                 :            :
        2560                 :            : #ifdef __cplusplus
        2561                 :            : }
        2562                 :            : #endif

Generated by: LCOV version 1.14