mirror of
https://github.com/python/cpython.git
synced 2026-05-06 12:49:07 -04:00
gh-142589: Fix PyUnstable_Object_IsUniqueReferencedTemporary (gh-142593)
PyUnstable_Object_IsUniqueReferencedTemporary wasn't handling tagged ints on the evaluation stack properly.
This commit is contained in:
@@ -251,6 +251,13 @@ class CAPITest(unittest.TestCase):
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Fix :c:func:`PyUnstable_Object_IsUniqueReferencedTemporary()` handling of
|
||||
tagged ints on the interpreter stack.
|
||||
@@ -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},
|
||||
|
||||
+6
-2
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user