Skip to content

Commit 8a64537

Browse files
committed
Add a test.
1 parent 58ac265 commit 8a64537

File tree

4 files changed

+25
-1
lines changed

4 files changed

+25
-1
lines changed

Doc/c-api/object.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ Object Protocol
615615
616616
.. c:function:: int PyUnstable_IsImmortal(PyObject *obj)
617617
618-
This function returns ``1`` if *obj* is :term:`immortal`, and ``0`` otherwise.
618+
This function returns ``1`` if *obj* is :term:`immortal`, and ``0`` otherwise. This function cannot fail.
619619
620620
Immortal objects don't care about reference counting, thus they no-op calls to :c:func:`Py_INCREF`
621621
and :c:func:`Py_DECREF`. Some immutable objects such as literal strings, small integers, or special tuples

Include/cpython/object.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,3 +541,6 @@ PyAPI_FUNC(PyRefTracer) PyRefTracer_GetTracer(void**);
541541
* 0 if the runtime ignored it. This function cannot fail.
542542
*/
543543
PyAPI_FUNC(int) PyUnstable_Object_EnableDeferredRefcount(PyObject *);
544+
545+
/* Check whether the object is immortal. This cannot fail. */
546+
PyAPI_FUNC(int) PyUnstable_IsImmortal(PyObject *);

Lib/test/test_capi/test_immortal.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,20 @@ def test_immortal_builtins(self):
2727
for obj in ([], {}, set()):
2828
self.assertFalse(_testinternalcapi.is_static_immortal(obj))
2929

30+
def test_immortal(self):
31+
# Not extensive
32+
known_immortals = (True, False, None, 0, ())
33+
for immortal in known_immortals:
34+
with self.subTest(immortal=immortal):
35+
self.assertTrue(_testcapi.is_immortal(immortal))
36+
37+
# Some arbitrary mutable objects
38+
non_immortals = (object(), self, [object()])
39+
for non_immortal in non_immortals:
40+
with self.subTest(non_immortal=non_immortal):
41+
self.assertFalse(_testcapi.is_immortal(non_immortal))
42+
43+
3044

3145
if __name__ == "__main__":
3246
unittest.main()

Modules/_testcapimodule.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3487,6 +3487,12 @@ tracemalloc_track_race(PyObject *self, PyObject *args)
34873487
#undef NTHREAD
34883488
}
34893489

3490+
static PyObject *
3491+
is_immortal(PyObject *self, PyObject *op)
3492+
{
3493+
return PyUnstable_IsImmortal(op);
3494+
}
3495+
34903496
static PyMethodDef TestMethods[] = {
34913497
{"set_errno", set_errno, METH_VARARGS},
34923498
{"test_config", test_config, METH_NOARGS},
@@ -3630,6 +3636,7 @@ static PyMethodDef TestMethods[] = {
36303636
{"test_atexit", test_atexit, METH_NOARGS},
36313637
{"code_offset_to_line", _PyCFunction_CAST(code_offset_to_line), METH_FASTCALL},
36323638
{"tracemalloc_track_race", tracemalloc_track_race, METH_NOARGS},
3639+
{"is_immortal", is_immortal, METH_O}
36333640
{NULL, NULL} /* sentinel */
36343641
};
36353642

0 commit comments

Comments
 (0)