(((PyObject*)(o))->ob_refcnt)
+.. c:function:: void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)
+
+ Set the object *o* reference counter to *refcnt*.
+
+ .. versionadded:: 3.9
+
+
.. c:macro:: Py_SIZE(o)
This macro is used to access the :attr:`ob_size` member of a Python object.
#define Py_TYPE(ob) (_PyObject_CAST(ob)->ob_type)
#define Py_SIZE(ob) (_PyVarObject_CAST(ob)->ob_size)
+static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) {
+ ob->ob_refcnt = refcnt;
+}
+#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt)
+
/*
Type objects contain a string containing the type name (to help somewhat
in debugging), the allocation parameters (see PyObject_New() and
--- /dev/null
+Add a :c:func:`Py_SET_REFCNT` function to set the reference counter of an
+object.
/* Temporarily resurrect the object. */
assert(Py_REFCNT(self) == 0);
- Py_REFCNT(self) = 1;
+ Py_SET_REFCNT(self, 1);
/* Save the current exception, if any. */
PyErr_Fetch(&error_type, &error_value, &error_traceback);
* cause a recursive call.
*/
assert(Py_REFCNT(self) > 0);
- if (--Py_REFCNT(self) == 0) {
+ Py_SET_REFCNT(self, Py_REFCNT(self) - 1);
+ if (Py_REFCNT(self) == 0) {
/* this is the normal path out */
return;
}
{
Py_ssize_t refcnt = Py_REFCNT(self);
_Py_NewReference(self);
- Py_REFCNT(self) = refcnt;
+ Py_SET_REFCNT(self, refcnt);
}
assert(!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self));
/* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased
return NULL;
}
/* Initialize reference count to avoid early crash in ceval or GC */
- Py_REFCNT(op) = 1;
+ Py_SET_REFCNT(op, 1);
/* object fields like ob_type are uninitialized! */
return test_pyobject_is_freed("check_pyobject_uninitialized_is_freed", op);
}
return NULL;
}
/* Initialize reference count to avoid early crash in ceval or GC */
- Py_REFCNT(op) = 1;
+ Py_SET_REFCNT(op, 1);
/* ob_type field is after the memory block: part of "forbidden bytes"
when using debug hooks on memory allocators! */
return test_pyobject_is_freed("check_pyobject_forbidden_bytes_is_freed", op);
}
Py_TYPE(op)->tp_dealloc(op);
/* Reset reference count to avoid early crash in ceval or GC */
- Py_REFCNT(op) = 1;
+ Py_SET_REFCNT(op, 1);
/* object memory is freed! */
return test_pyobject_is_freed("check_pyobject_freed_is_freed", op);
}
}
assert(Py_REFCNT(obj) == 1);
- Py_REFCNT(obj) = 0;
+ Py_SET_REFCNT(obj, 0);
/* Py_DECREF() must call _Py_NegativeRefcount() and abort Python */
Py_DECREF(obj);
return NULL;
if (def->m_base.m_index == 0) {
max_module_number++;
- Py_REFCNT(def) = 1;
+ Py_SET_REFCNT(def, 1);
Py_TYPE(def) = &PyModuleDef_Type;
def->m_base.m_index = max_module_number;
}
}
/* Temporarily resurrect the object. */
- Py_REFCNT(self) = 1;
+ Py_SET_REFCNT(self, 1);
PyObject_CallFinalizer(self);
/* Undo the temporary resurrection; can't use DECREF here, it would
* cause a recursive call. */
- if (--Py_REFCNT(self) == 0) {
+ Py_SET_REFCNT(self, Py_REFCNT(self) - 1);
+ if (Py_REFCNT(self) == 0) {
return 0; /* this is the normal path out */
}
* never happened. */
Py_ssize_t refcnt = Py_REFCNT(self);
_Py_NewReference(self);
- Py_REFCNT(self) = refcnt;
+ Py_SET_REFCNT(self, refcnt);
_PyObject_ASSERT(self,
(!PyType_IS_GC(Py_TYPE(self))
#ifdef Py_REF_DEBUG
_Py_RefTotal++;
#endif
- Py_REFCNT(op) = 1;
+ Py_SET_REFCNT(op, 1);
#ifdef Py_TRACE_REFS
_Py_AddToAllObjects(op, 1);
#endif
case SSTATE_INTERNED_MORTAL:
/* revive dead object temporarily for DelItem */
- Py_REFCNT(unicode) = 3;
+ Py_SET_REFCNT(unicode, 3);
if (PyDict_DelItem(interned, unicode) != 0) {
_PyErr_WriteUnraisableMsg("deletion of interned string failed",
NULL);
}
/* The two references in interned are not counted by refcnt.
The deallocator will take care of this */
- Py_REFCNT(s) -= 2;
+ Py_SET_REFCNT(s, Py_REFCNT(s) - 2);
_PyUnicode_STATE(s).interned = SSTATE_INTERNED_MORTAL;
}