-
-
Notifications
You must be signed in to change notification settings - Fork 32k
gh-133164: Add PyUnstable_Object_IsUniqueReferencedTemporary
C API
#133170
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
32b6cd0
479f185
4a53a98
fdc438a
b6508df
07ba540
99e3265
0e0e674
07f3b23
bba589f
f23de33
6efe2fb
f30ccf4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -89,6 +89,10 @@ If you encounter :exc:`NameError`\s or pickling errors coming out of | |
:mod:`multiprocessing` or :mod:`concurrent.futures`, see the | ||
:ref:`forkserver restrictions <multiprocessing-programming-forkserver>`. | ||
|
||
The interpreter avoids some reference count modifications internally when | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👌 |
||
it's safe to do so. This can lead to different values returned from | ||
:func:`sys.getrefcount` and :c:func:`Py_REFCNT` compared to previous versions | ||
of Python. See :ref:`below <whatsnew314-refcount>` for details. | ||
|
||
New features | ||
============ | ||
|
@@ -2210,6 +2214,11 @@ New features | |
take a C integer and produce a Python :class:`bool` object. (Contributed by | ||
Pablo Galindo in :issue:`45325`.) | ||
|
||
* Add :c:func:`PyUnstable_Object_IsUniqueReferencedTemporary` to determine if an object | ||
is a unique temporary object on the interpreter's operand stack. This can | ||
be used in some cases as a replacement for checking if :c:func:`Py_REFCNT` | ||
is ``1`` for Python objects passed as arguments to C API functions. | ||
|
||
|
||
Limited C API changes | ||
--------------------- | ||
|
@@ -2244,6 +2253,17 @@ Porting to Python 3.14 | |
a :exc:`UnicodeError` object. | ||
(Contributed by Bénédikt Tran in :gh:`127691`.) | ||
|
||
.. _whatsnew314-refcount: | ||
|
||
* The interpreter internally avoids some reference count modifications when | ||
loading objects onto the operands stack by :term:`borrowing <borrowed reference>` | ||
references when possible. This can lead to smaller reference count values | ||
compared to previous Python versions. C API extensions that checked | ||
:c:func:`Py_REFCNT` of ``1`` to determine if an function argument is not | ||
referenced by any other code should instead use | ||
:c:func:`PyUnstable_Object_IsUniqueReferencedTemporary` as a safer replacement. | ||
|
||
|
||
* Private functions promoted to public C APIs: | ||
|
||
* ``_PyBytes_Join()``: :c:func:`PyBytes_Join`. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Add :c:func:`PyUnstable_Object_IsUniqueReferencedTemporary` function for | ||
determining if an object exists as a unique temporary variable on the | ||
interpreter's stack. This is a replacement for some cases where checking | ||
that :c:func:`Py_REFCNT` is one is no longer sufficient to determine if it's | ||
safe to modify a Python object in-place with no visible side effects. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ | |
#include "pycore_hamt.h" // _PyHamtItems_Type | ||
#include "pycore_initconfig.h" // _PyStatus_OK() | ||
#include "pycore_instruction_sequence.h" // _PyInstructionSequence_Type | ||
#include "pycore_interpframe.h" // _PyFrame_Stackbase() | ||
#include "pycore_interpolation.h" // _PyInterpolation_Type | ||
#include "pycore_list.h" // _PyList_DebugMallocStats() | ||
#include "pycore_long.h" // _PyLong_GetZero() | ||
|
@@ -2621,6 +2622,29 @@ PyUnstable_Object_EnableDeferredRefcount(PyObject *op) | |
#endif | ||
} | ||
|
||
int | ||
PyUnstable_Object_IsUniqueReferencedTemporary(PyObject *op) | ||
{ | ||
if (!_PyObject_IsUniquelyReferenced(op)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this just demonstrates that We need to check that the following are true:
I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's discuss the name for |
||
return 0; | ||
} | ||
|
||
_PyInterpreterFrame *frame = _PyEval_GetFrame(); | ||
if (frame == NULL) { | ||
return 0; | ||
} | ||
|
||
_PyStackRef *base = _PyFrame_Stackbase(frame); | ||
_PyStackRef *stackpointer = frame->stackpointer; | ||
while (stackpointer > base) { | ||
stackpointer--; | ||
if (op == PyStackRef_AsPyObjectBorrow(*stackpointer)) { | ||
return PyStackRef_IsHeapSafe(*stackpointer); | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
int | ||
PyUnstable_TryIncRef(PyObject *op) | ||
{ | ||
|
Uh oh!
There was an error while loading. Please reload this page.