#ifndef Py_CPYTHON_OBJECT_H # error "this header file must not be included directly" #endif PyAPI_FUNC(void) _Py_NewReference(PyObject *op); PyAPI_FUNC(void) _Py_NewReferenceNoTotal(PyObject *op); PyAPI_FUNC(void) _Py_ResurrectReference(PyObject *op); #ifdef Py_REF_DEBUG /* These are useful as debugging aids when chasing down refleaks. */ PyAPI_FUNC(Py_ssize_t) _Py_GetGlobalRefTotal(void); #define _Py_GetRefTotal … PyAPI_FUNC(Py_ssize_t) _Py_GetLegacyRefTotal(void); PyAPI_FUNC(Py_ssize_t) _PyInterpreterState_GetRefTotal(PyInterpreterState *); #endif /********************* String Literals ****************************************/ /* This structure helps managing static strings. The basic usage goes like this: Instead of doing r = PyObject_CallMethod(o, "foo", "args", ...); do _Py_IDENTIFIER(foo); ... r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...); PyId_foo is a static variable, either on block level or file level. On first usage, the string "foo" is interned, and the structures are linked. On interpreter shutdown, all strings are released. Alternatively, _Py_static_string allows choosing the variable name. _PyUnicode_FromId returns a borrowed reference to the interned string. _PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*. */ _Py_Identifier; #ifndef Py_BUILD_CORE // For now we are keeping _Py_IDENTIFIER for continued use // in non-builtin extensions (and naughty PyPI modules). #define _Py_static_string_init … #define _Py_static_string … #define _Py_IDENTIFIER … #endif /* !Py_BUILD_CORE */ PyNumberMethods; PySequenceMethods; PyMappingMethods; sendfunc; PyAsyncMethods; PyBufferProcs; /* Allow printfunc in the tp_vectorcall_offset slot for * backwards-compatibility */ printfunc; // If this structure is modified, Doc/includes/typestruct.h should be updated // as well. struct _typeobject { … }; /* This struct is used by the specializer * It should be treated as an opaque blob * by code other than the specializer and interpreter. */ struct _specialization_cache { … }; /* The *real* layout of a type object when allocated on the heap */ PyHeapTypeObject; PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *); PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); PyAPI_FUNC(PyObject *) _PyType_LookupRef(PyTypeObject *, PyObject *); PyAPI_FUNC(PyObject *) PyType_GetDict(PyTypeObject *); PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); PyAPI_FUNC(void) _Py_BreakPoint(void); PyAPI_FUNC(void) _PyObject_Dump(PyObject *); PyAPI_FUNC(PyObject*) _PyObject_GetAttrId(PyObject *, _Py_Identifier *); PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *); PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *); PyAPI_FUNC(void) PyUnstable_Object_ClearWeakRefsNoCallbacks(PyObject *); /* Same as PyObject_Generic{Get,Set}Attr, but passing the attributes dict as the last parameter. */ PyAPI_FUNC(PyObject *) _PyObject_GenericGetAttrWithDict(PyObject *, PyObject *, PyObject *, int); PyAPI_FUNC(int) _PyObject_GenericSetAttrWithDict(PyObject *, PyObject *, PyObject *, PyObject *); PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *); /* Safely decref `dst` and set `dst` to `src`. * * As in case of Py_CLEAR "the obvious" code can be deadly: * * Py_DECREF(dst); * dst = src; * * The safe way is: * * Py_SETREF(dst, src); * * That arranges to set `dst` to `src` _before_ decref'ing, so that any code * triggered as a side-effect of `dst` getting torn down no longer believes * `dst` points to a valid object. * * Temporary variables are used to only evaluate macro arguments once and so * avoid the duplication of side effects. _Py_TYPEOF() or memcpy() is used to * avoid a miscompilation caused by type punning. See Py_CLEAR() comment for * implementation details about type punning. * * The memcpy() implementation does not emit a compiler warning if 'src' has * not the same type than 'src': any pointer type is accepted for 'src'. */ #ifdef _Py_TYPEOF #define Py_SETREF(dst, src) … #else #define Py_SETREF … #endif /* Py_XSETREF() is a variant of Py_SETREF() that uses Py_XDECREF() instead of * Py_DECREF(). */ #ifdef _Py_TYPEOF #define Py_XSETREF(dst, src) … #else #define Py_XSETREF … #endif /* Define a pair of assertion macros: _PyObject_ASSERT_FROM(), _PyObject_ASSERT_WITH_MSG() and _PyObject_ASSERT(). These work like the regular C assert(), in that they will abort the process with a message on stderr if the given condition fails to hold, but compile away to nothing if NDEBUG is defined. However, before aborting, Python will also try to call _PyObject_Dump() on the given object. This may be of use when investigating bugs in which a particular object is corrupt (e.g. buggy a tp_visit method in an extension module breaking the garbage collector), to help locate the broken objects. The WITH_MSG variant allows you to supply an additional message that Python will attempt to print to stderr, after the object dump. */ #ifdef NDEBUG /* No debugging: compile away the assertions: */ #define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) … #else /* With debugging: generate checks: */ #define _PyObject_ASSERT_FROM … #endif #define _PyObject_ASSERT_WITH_MSG(obj, expr, msg) … #define _PyObject_ASSERT(obj, expr) … #define _PyObject_ASSERT_FAILED_MSG(obj, msg) … /* Declare and define _PyObject_AssertFailed() even when NDEBUG is defined, to avoid causing compiler/linker errors when building extensions without NDEBUG against a Python built with NDEBUG defined. msg, expr and function can be NULL. */ PyAPI_FUNC(void) _Py_NO_RETURN _PyObject_AssertFailed( PyObject *obj, const char *expr, const char *msg, const char *file, int line, const char *function); /* Trashcan mechanism, thanks to Christian Tismer. When deallocating a container object, it's possible to trigger an unbounded chain of deallocations, as each Py_DECREF in turn drops the refcount on "the next" object in the chain to 0. This can easily lead to stack overflows, especially in threads (which typically have less stack space to work with). A container object can avoid this by bracketing the body of its tp_dealloc function with a pair of macros: static void mytype_dealloc(mytype *p) { ... declarations go here ... PyObject_GC_UnTrack(p); // must untrack first Py_TRASHCAN_BEGIN(p, mytype_dealloc) ... The body of the deallocator goes here, including all calls ... ... to Py_DECREF on contained objects. ... Py_TRASHCAN_END // there should be no code after this } CAUTION: Never return from the middle of the body! If the body needs to "get out early", put a label immediately before the Py_TRASHCAN_END call, and goto it. Else the call-depth counter (see below) will stay above 0 forever, and the trashcan will never get emptied. How it works: The BEGIN macro increments a call-depth counter. So long as this counter is small, the body of the deallocator is run directly without further ado. But if the counter gets large, it instead adds p to a list of objects to be deallocated later, skips the body of the deallocator, and resumes execution after the END macro. The tp_dealloc routine then returns without deallocating anything (and so unbounded call-stack depth is avoided). When the call stack finishes unwinding again, code generated by the END macro notices this, and calls another routine to deallocate all the objects that may have been added to the list of deferred deallocations. In effect, a chain of N deallocations is broken into (N-1)/(Py_TRASHCAN_HEADROOM-1) pieces, with the call stack never exceeding a depth of Py_TRASHCAN_HEADROOM. Since the tp_dealloc of a subclass typically calls the tp_dealloc of the base class, we need to ensure that the trashcan is only triggered on the tp_dealloc of the actual class being deallocated. Otherwise we might end up with a partially-deallocated object. To check this, the tp_dealloc function must be passed as second argument to Py_TRASHCAN_BEGIN(). */ /* Python 3.9 private API, invoked by the macros below. */ PyAPI_FUNC(int) _PyTrash_begin(PyThreadState *tstate, PyObject *op); PyAPI_FUNC(void) _PyTrash_end(PyThreadState *tstate); PyAPI_FUNC(void) _PyTrash_thread_deposit_object(PyThreadState *tstate, PyObject *op); PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(PyThreadState *tstate); /* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */ /* To avoid raising recursion errors during dealloc trigger trashcan before we reach * recursion limit. To avoid trashing, we don't attempt to empty the trashcan until * we have headroom above the trigger limit */ #define Py_TRASHCAN_HEADROOM … #define Py_TRASHCAN_BEGIN(op, dealloc) … /* The body of the deallocator is here. */ #define Py_TRASHCAN_END … PyAPI_FUNC(void *) PyObject_GetItemData(PyObject *obj); PyAPI_FUNC(int) PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg); PyAPI_FUNC(int) _PyObject_SetManagedDict(PyObject *obj, PyObject *new_dict); PyAPI_FUNC(void) PyObject_ClearManagedDict(PyObject *obj); #define TYPE_MAX_WATCHERS … PyType_WatchCallback; PyAPI_FUNC(int) PyType_AddWatcher(PyType_WatchCallback callback); PyAPI_FUNC(int) PyType_ClearWatcher(int watcher_id); PyAPI_FUNC(int) PyType_Watch(int watcher_id, PyObject *type); PyAPI_FUNC(int) PyType_Unwatch(int watcher_id, PyObject *type); /* Attempt to assign a version tag to the given type. * * Returns 1 if the type already had a valid version tag or a new one was * assigned, or 0 if a new tag could not be assigned. */ PyAPI_FUNC(int) PyUnstable_Type_AssignVersionTag(PyTypeObject *type); PyRefTracerEvent; PyRefTracer; PyAPI_FUNC(int) PyRefTracer_SetTracer(PyRefTracer tracer, void *data); PyAPI_FUNC(PyRefTracer) PyRefTracer_GetTracer(void**); /* Enable PEP-703 deferred reference counting on the object. * * Returns 1 if deferred reference counting was successfully enabled, and * 0 if the runtime ignored it. This function cannot fail. */ PyAPI_FUNC(int) PyUnstable_Object_EnableDeferredRefcount(PyObject *);