FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Add PyUnstable_SetImmortal by kumaraditya303 · Pull Request #164 · python/pythoncapi-compat · GitHub

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (1) .h  (1) .rst  (2) All 3 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
5 changes: 5 additions & 0 deletions docs/api.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ Python 3.15

On PyPy, always returns ``-1``.

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

See `PyUnstable_SetImmortal() documentation <https://docs.python.org/dev/c-api/object.html#c.PyUnstable_SetImmortal>`__.

Comment thread
kumaraditya303 marked this conversation as resolved.
Availability: Python 3.13 and newer, not available on PyPy.

Python 3.14
-----------
Expand Down
4 changes: 4 additions & 0 deletions docs/changelog.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Changelog
=========

* 2026-02-12: Add functions:

* ``PyUnstable_SetImmortal()``

* 2025-10-14: Add functions:

* ``PyTuple_FromArray()``
Expand Down
31 changes: 31 additions & 0 deletions pythoncapi_compat.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -2659,6 +2659,37 @@ PyUnstable_Unicode_GET_CACHED_HASH(PyObject *op)
}
#endif

#if 0x030D0000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030F00A7 && !defined(PYPY_VERSION)
Comment thread
kumaraditya303 marked this conversation as resolved.
// Immortal objects were implemented in Python 3.12, however there is no easy API
// to make objects immortal until 3.14 which has _Py_SetImmortal(). Since
// immortal objects are primarily needed for free-threading, this API is implemented
// for 3.14 using _Py_SetImmortal() and uses private macros on 3.13.
static inline int
PyUnstable_SetImmortal(PyObject *op)
{
assert(op != NULL);
if (!PyUnstable_Object_IsUniquelyReferenced(op) || PyUnicode_Check(op)) {
return 0;
}
#if 0x030E0000 <= PY_VERSION_HEX
PyAPI_FUNC(void) _Py_SetImmortal(PyObject *op);
_Py_SetImmortal(op);
#else
// Python 3.13 doesn't export _Py_SetImmortal() function
if (PyObject_GC_IsTracked(op)) {
PyObject_GC_UnTrack(op);
}
#ifdef Py_GIL_DISABLED
op->ob_tid = _Py_UNOWNED_TID;
op->ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL;
op->ob_ref_shared = 0;
#else
op->ob_refcnt = _Py_IMMORTAL_REFCNT;
#endif
#endif
return 1;
}
#endif

#ifdef __cplusplus
}
Expand Down
36 changes: 36 additions & 0 deletions tests/test_pythoncapi_compat_cext.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -2489,6 +2489,39 @@ test_try_incref(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
Py_RETURN_NONE;
}

#if 0x030D0000 <= PY_VERSION_HEX && !defined(PYPY_VERSION)
static PyObject *
test_set_immortal(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
{
PyObject object;
memset(&object, 0, sizeof(PyObject));
#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;

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

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

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


static struct PyMethodDef methods[] = {
{"test_object", test_object, METH_NOARGS, _Py_NULL},
Expand Down Expand Up @@ -2546,6 +2579,9 @@ static struct PyMethodDef methods[] = {
{"test_byteswriter", test_byteswriter, METH_NOARGS, _Py_NULL},
{"test_tuple", test_tuple, METH_NOARGS, _Py_NULL},
{"test_try_incref", test_try_incref, METH_NOARGS, _Py_NULL},
#if 0x030D0000 <= PY_VERSION_HEX && !defined(PYPY_VERSION)
{"test_set_immortal", test_set_immortal, METH_NOARGS, _Py_NULL},
#endif
{_Py_NULL, _Py_NULL, 0, _Py_NULL}
};

Expand Down
Loading

Back | FazBrowse Home | New Git URL