Skip to content

Commit 3af7834

Browse files
vstinnerencukou
authored andcommitted
[3.12] pythongh-121528: Add _Py_IsImmortalLoose() function for assertions. (python#121725)
1 parent 58f7763 commit 3af7834

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

Include/internal/pycore_object.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,28 @@ extern "C" {
1414
#include "pycore_pystate.h" // _PyInterpreterState_GET()
1515
#include "pycore_runtime.h" // _PyRuntime
1616

17+
#define _Py_IMMORTAL_REFCNT_LOOSE ((_Py_IMMORTAL_REFCNT >> 1) + 1)
18+
19+
// gh-121528, gh-118997: Similar to _Py_IsImmortal() but be more loose when
20+
// comparing the reference count to stay compatible with C extensions built
21+
// with the stable ABI 3.11 or older. Such extensions implement INCREF/DECREF
22+
// as refcnt++ and refcnt-- without taking in account immortal objects. For
23+
// example, the reference count of an immortal object can change from
24+
// _Py_IMMORTAL_REFCNT to _Py_IMMORTAL_REFCNT+1 (INCREF) or
25+
// _Py_IMMORTAL_REFCNT-1 (DECREF).
26+
//
27+
// This function should only be used in assertions. Otherwise, _Py_IsImmortal()
28+
// must be used instead.
29+
static inline int _Py_IsImmortalLoose(PyObject *op)
30+
{
31+
#if defined(Py_GIL_DISABLED)
32+
return _Py_IsImmortal(op);
33+
#else
34+
return (op->ob_refcnt >= _Py_IMMORTAL_REFCNT_LOOSE);
35+
#endif
36+
}
37+
#define _Py_IsImmortalLoose(op) _Py_IsImmortalLoose(_PyObject_CAST(op))
38+
1739
/* We need to maintain an internal copy of Py{Var}Object_HEAD_INIT to avoid
1840
designated initializer conflicts in C++20. If we use the deinition in
1941
object.h, we will be mixing designated and non-designated initializers in

0 commit comments

Comments
 (0)