.. versionadded:: 3.14
+.. c:function:: int PyUnstable_IsImmortal(PyObject *obj)
+
+ This function returns non-zero if *obj* is :term:`immortal`, and zero
+ otherwise. This function cannot fail.
+
+ .. note::
+
+ Objects that are immortal in one CPython version are not guaranteed to
+ be immortal in another.
+
+ .. versionadded:: next
bit-packing Python version numbers.
(Contributed by Petr Viktorin in :gh:`128629`.)
+* Add :c:func:`PyUnstable_IsImmortal` for determining whether an object is :term:`immortal`,
+ for debugging purposes.
+
Porting to Python 3.14
----------------------
* 0 if the runtime ignored it. This function cannot fail.
*/
PyAPI_FUNC(int) PyUnstable_Object_EnableDeferredRefcount(PyObject *);
+
+/* Check whether the object is immortal. This cannot fail. */
+PyAPI_FUNC(int) PyUnstable_IsImmortal(PyObject *);
_testinternalcapi = import_helper.import_module('_testinternalcapi')
-class TestCAPI(unittest.TestCase):
- def test_immortal_builtins(self):
- _testcapi.test_immortal_builtins()
+class TestUnstableCAPI(unittest.TestCase):
+ def test_immortal(self):
+ # Not extensive
+ known_immortals = (True, False, None, 0, ())
+ for immortal in known_immortals:
+ with self.subTest(immortal=immortal):
+ self.assertTrue(_testcapi.is_immortal(immortal))
+
+ # Some arbitrary mutable objects
+ non_immortals = (object(), self, [object()])
+ for non_immortal in non_immortals:
+ with self.subTest(non_immortal=non_immortal):
+ self.assertFalse(_testcapi.is_immortal(non_immortal))
+
+ # CRASHES _testcapi.is_immortal(NULL)
- def test_immortal_small_ints(self):
- _testcapi.test_immortal_small_ints()
class TestInternalCAPI(unittest.TestCase):
--- /dev/null
+Add :c:func:`PyUnstable_IsImmortal` for determining whether an object is
+:term:`immortal`.
Py_RETURN_NONE;
}
+static PyObject *
+is_immortal(PyObject *self, PyObject *op)
+{
+ return PyBool_FromLong(PyUnstable_IsImmortal(op));
+}
+
static PyMethodDef test_methods[] = {
{"test_immortal_builtins", test_immortal_builtins, METH_NOARGS},
{"test_immortal_small_ints", test_immortal_small_ints, METH_NOARGS},
+ {"is_immortal", is_immortal, METH_O},
{NULL},
};
return PyLong_FromLong(result);
}
+
static PyMethodDef test_methods[] = {
{"call_pyobject_print", call_pyobject_print, METH_VARARGS},
{"pyobject_print_null", pyobject_print_null, METH_VARARGS},
{
return _Py_REFCNT(ob);
}
+
+int
+PyUnstable_IsImmortal(PyObject *op)
+{
+ /* Checking a reference count requires a thread state */
+ _Py_AssertHoldsTstate();
+ assert(op != NULL);
+ return _Py_IsImmortal(op);
+}