https://github.com/python/cpython/commit/a26c831bc486b6e607cee6a5923bad52b97c2341
commit: a26c831bc486b6e607cee6a5923bad52b97c2341
branch: main
author: Sam Gross <[email protected]>
committer: colesbury <[email protected]>
date: 2025-12-11T14:41:03-05:00
summary:
gh-142589: Fix PyUnstable_Object_IsUniqueReferencedTemporary (gh-142593)
PyUnstable_Object_IsUniqueReferencedTemporary wasn't handling tagged
ints on the evaluation stack properly.
files:
A Misc/NEWS.d/next/C_API/2025-12-11-13-01-49.gh-issue-142589.nNAqgw.rst
M Lib/test/test_capi/test_object.py
M Modules/_testcapi/object.c
M Objects/object.c
diff --git a/Lib/test/test_capi/test_object.py
b/Lib/test/test_capi/test_object.py
index c5040913e9e1f1..67572ab1ba268d 100644
--- a/Lib/test/test_capi/test_object.py
+++ b/Lib/test/test_capi/test_object.py
@@ -251,6 +251,13 @@ def func(x):
func(object())
+ # Test that a newly created object in C is not considered
+ # a uniquely referenced temporary, because it's not on the stack.
+ # gh-142586: do the test in a loop over a list to test for handling
+ # tagged ints on the stack.
+ for i in [0, 1, 2]:
+
self.assertFalse(_testcapi.pyobject_is_unique_temporary_new_object())
+
def pyobject_dump(self, obj, release_gil=False):
pyobject_dump = _testcapi.pyobject_dump
diff --git
a/Misc/NEWS.d/next/C_API/2025-12-11-13-01-49.gh-issue-142589.nNAqgw.rst
b/Misc/NEWS.d/next/C_API/2025-12-11-13-01-49.gh-issue-142589.nNAqgw.rst
new file mode 100644
index 00000000000000..529277b951ada3
--- /dev/null
+++ b/Misc/NEWS.d/next/C_API/2025-12-11-13-01-49.gh-issue-142589.nNAqgw.rst
@@ -0,0 +1,2 @@
+Fix :c:func:`PyUnstable_Object_IsUniqueReferencedTemporary()` handling of
+tagged ints on the interpreter stack.
diff --git a/Modules/_testcapi/object.c b/Modules/_testcapi/object.c
index 4c9632c07a99f4..a4f76c409c6f78 100644
--- a/Modules/_testcapi/object.c
+++ b/Modules/_testcapi/object.c
@@ -138,6 +138,15 @@ pyobject_is_unique_temporary(PyObject *self, PyObject *obj)
return PyLong_FromLong(result);
}
+static PyObject *
+pyobject_is_unique_temporary_new_object(PyObject *self, PyObject *unused)
+{
+ PyObject *obj = PyList_New(0);
+ int result = PyUnstable_Object_IsUniqueReferencedTemporary(obj);
+ Py_DECREF(obj);
+ return PyLong_FromLong(result);
+}
+
static int MyObject_dealloc_called = 0;
static void
@@ -517,6 +526,7 @@ static PyMethodDef test_methods[] = {
{"pyobject_clear_weakrefs_no_callbacks",
pyobject_clear_weakrefs_no_callbacks, METH_O},
{"pyobject_enable_deferred_refcount", pyobject_enable_deferred_refcount,
METH_O},
{"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_xincref_doesnt_leak",test_xincref_doesnt_leak, METH_NOARGS},
{"test_incref_doesnt_leak", test_incref_doesnt_leak, METH_NOARGS},
diff --git a/Objects/object.c b/Objects/object.c
index fcea3503de8213..36a37bb0bbea4d 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -2759,8 +2759,12 @@ PyUnstable_Object_IsUniqueReferencedTemporary(PyObject
*op)
_PyStackRef *stackpointer = frame->stackpointer;
while (stackpointer > base) {
stackpointer--;
- if (op == PyStackRef_AsPyObjectBorrow(*stackpointer)) {
- return PyStackRef_IsHeapSafe(*stackpointer);
+ _PyStackRef ref = *stackpointer;
+ if (PyStackRef_IsTaggedInt(ref)) {
+ continue;
+ }
+ if (op == PyStackRef_AsPyObjectBorrow(ref)) {
+ return PyStackRef_IsHeapSafe(ref);
}
}
return 0;
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]