summaryrefslogtreecommitdiffstats
path: root/Doc
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2022-11-09 13:06:36 (GMT)
committerGitHub <noreply@github.com>2022-11-09 13:06:36 (GMT)
commitc03e05c2e72f3ea5e797389e7d1042eef85ad37a (patch)
tree3a30ddb1b3b35a9b2ea7d233f242c72e74e71e71 /Doc
parent0124b5dd28eff7bb80eb7244e97e402a036db13b (diff)
downloadcpython-c03e05c2e72f3ea5e797389e7d1042eef85ad37a.zip
cpython-c03e05c2e72f3ea5e797389e7d1042eef85ad37a.tar.gz
cpython-c03e05c2e72f3ea5e797389e7d1042eef85ad37a.tar.bz2
gh-98724: Fix Py_CLEAR() macro side effects (#99100)
The Py_CLEAR(), Py_SETREF() and Py_XSETREF() macros now only evaluate their argument once. If an argument has side effects, these side effects are no longer duplicated. Add test_py_clear() and test_py_setref() unit tests to _testcapi.
Diffstat (limited to 'Doc')
-rw-r--r--Doc/c-api/refcounting.rst46
-rw-r--r--Doc/whatsnew/3.12.rst5
2 files changed, 49 insertions, 2 deletions
diff --git a/Doc/c-api/refcounting.rst b/Doc/c-api/refcounting.rst
index cd1f2ef..d8e9c2d 100644
--- a/Doc/c-api/refcounting.rst
+++ b/Doc/c-api/refcounting.rst
@@ -7,8 +7,8 @@
Reference Counting
******************
-The macros in this section are used for managing reference counts of Python
-objects.
+The functions and macros in this section are used for managing reference counts
+of Python objects.
.. c:function:: Py_ssize_t Py_REFCNT(PyObject *o)
@@ -129,6 +129,11 @@ objects.
It is a good idea to use this macro whenever decrementing the reference
count of an object that might be traversed during garbage collection.
+ .. versionchanged:: 3.12
+ The macro argument is now only evaluated once. If the argument has side
+ effects, these are no longer duplicated.
+
+
.. c:function:: void Py_IncRef(PyObject *o)
Increment the reference count for object *o*. A function version of :c:func:`Py_XINCREF`.
@@ -139,3 +144,40 @@ objects.
Decrement the reference count for object *o*. A function version of :c:func:`Py_XDECREF`.
It can be used for runtime dynamic embedding of Python.
+
+
+.. c:macro:: Py_SETREF(dst, src)
+
+ Macro safely decrementing the `dst` reference count and setting `dst` to
+ `src`.
+
+ As in case of :c:func:`Py_CLEAR`, "the obvious" code can be deadly::
+
+ Py_DECREF(dst);
+ dst = src;
+
+ The safe way is::
+
+ Py_SETREF(dst, src);
+
+ That arranges to set `dst` to `src` _before_ decrementing reference count of
+ *dst* old value, so that any code triggered as a side-effect of `dst`
+ getting torn down no longer believes `dst` points to a valid object.
+
+ .. versionadded:: 3.6
+
+ .. versionchanged:: 3.12
+ The macro arguments are now only evaluated once. If an argument has side
+ effects, these are no longer duplicated.
+
+
+.. c:macro:: Py_XSETREF(dst, src)
+
+ Variant of :c:macro:`Py_SETREF` macro that uses :c:func:`Py_XDECREF` instead
+ of :c:func:`Py_DECREF`.
+
+ .. versionadded:: 3.6
+
+ .. versionchanged:: 3.12
+ The macro arguments are now only evaluated once. If an argument has side
+ effects, these are no longer duplicated.
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 7ebfc55..37b9fb1 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -792,6 +792,11 @@ Porting to Python 3.12
:class:`bytes` type is accepted for bytes strings.
(Contributed by Victor Stinner in :gh:`98393`.)
+* The :c:macro:`Py_CLEAR`, :c:macro:`Py_SETREF` and :c:macro:`Py_XSETREF`
+ macros now only evaluate their argument once. If the argument has side
+ effects, these side effects are no longer duplicated.
+ (Contributed by Victor Stinner in :gh:`98724`.)
+
Deprecated
----------