Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-143300: implementPyUnstable_SetImmortal#144543

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
kumaraditya303 merged 11 commits intopython:mainfromkumaraditya303:immortal
Feb 11, 2026
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletionsDoc/c-api/object.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -801,3 +801,20 @@ Object Protocol
cannot fail.

.. versionadded:: 3.14

.. c:function:: int PyUnstable_SetImmortal(PyObject *op)

Marks the object *op* :term:`immortal`. The argument should be uniquely referenced by
the calling thread. This is intended to be used for reducing reference counting contention
in the :term:`free-threaded build` for objects which are shared across threads.

This is a one-way process: objects can only be made immortal; they cannot be
made mortal once again. Immortal objects do not participate in reference counting
and will never be garbage collected. If the object is GC-tracked, it is untracked.

This function is intended to be used soon after *op* is created, by the code that
creates it, such as in the object's :c:member:`~PyTypeObject.tp_new` slot.
Returns 1 if the object was made immortal and returns 0 if it was not.
This function cannot fail.

.. versionadded:: next
2 changes: 2 additions & 0 deletionsInclude/cpython/object.h
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -493,3 +493,5 @@ PyAPI_FUNC(int) PyUnstable_TryIncRef(PyObject *);
PyAPI_FUNC(void) PyUnstable_EnableTryIncRef(PyObject *);

PyAPI_FUNC(int) PyUnstable_Object_IsUniquelyReferenced(PyObject *);

PyAPI_FUNC(int) PyUnstable_SetImmortal(PyObject *op);
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
Add :c:func:`PyUnstable_SetImmortal` C-API function to mark objects as :term:`immortal`.
39 changes: 39 additions & 0 deletionsModules/_testcapi/object.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -201,6 +201,44 @@ test_py_try_inc_ref(PyObject *self, PyObject *unused)
Py_RETURN_NONE;
}

static PyObject *
test_py_set_immortal(PyObject *self, PyObject *unused)
{
// the object is allocated on C stack as otherwise,
// it would trip the refleak checker when the object
// is made immortal and leak memory, for the same
// reason we cannot call PyObject_Init() on it.
PyObject object = {0};
#ifdef Py_GIL_DISABLED
object.ob_tid = _Py_ThreadId();
object.ob_gc_bits = 0;
object.ob_ref_local = 1;
object.ob_ref_shared = 0;
#else
object.ob_refcnt = 1;
#endif
object.ob_type = &PyBaseObject_Type;

assert(!PyUnstable_IsImmortal(&object));
int rc = PyUnstable_SetImmortal(&object);
assert(rc == 1);
assert(PyUnstable_IsImmortal(&object));
Py_DECREF(&object); // should not dealloc
assert(PyUnstable_IsImmortal(&object));

// Check already immortal object
rc = PyUnstable_SetImmortal(&object);
assert(rc == 0);

// Check unicode objects
PyObject *unicode = PyUnicode_FromString("test");
assert(!PyUnstable_IsImmortal(unicode));
rc = PyUnstable_SetImmortal(unicode);
assert(rc == 0);
assert(!PyUnstable_IsImmortal(unicode));
Py_DECREF(unicode);
Py_RETURN_NONE;
}

static PyObject *
_test_incref(PyObject *ob)
Expand DownExpand Up@@ -528,6 +566,7 @@ static PyMethodDef test_methods[] = {
{"pyobject_is_unique_temporary", pyobject_is_unique_temporary, METH_O},
{"pyobject_is_unique_temporary_new_object", pyobject_is_unique_temporary_new_object, METH_NOARGS},
{"test_py_try_inc_ref", test_py_try_inc_ref, METH_NOARGS},
{"test_py_set_immortal", test_py_set_immortal, METH_NOARGS},
{"test_xincref_doesnt_leak",test_xincref_doesnt_leak, METH_NOARGS},
{"test_incref_doesnt_leak", test_incref_doesnt_leak, METH_NOARGS},
{"test_xdecref_doesnt_leak",test_xdecref_doesnt_leak, METH_NOARGS},
Expand Down
11 changes: 11 additions & 0 deletionsObjects/object.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2839,6 +2839,17 @@ PyUnstable_EnableTryIncRef(PyObject *op)
#endif
}

int
PyUnstable_SetImmortal(PyObject *op)
{
assert(op != NULL);
if (!_PyObject_IsUniquelyReferenced(op) || PyUnicode_Check(op)) {
return 0;
}
_Py_SetImmortal(op);
return 1;
}

void
_Py_ResurrectReference(PyObject *op)
{
Expand Down
Loading

[8]ページ先頭

©2009-2026 Movatter.jp