https://github.com/python/cpython/commit/e5d70d9627949ca2462f1af15d065ef3cfded56a
commit: e5d70d9627949ca2462f1af15d065ef3cfded56a
branch: 3.13
author: Petr Viktorin <[email protected]>
committer: encukou <[email protected]>
date: 2026-07-02T10:07:33+02:00
summary:

[3.13] gh-144473: Add "steal" term to glossary; clarify "stealing" onerror 
(GH-144502) (GH-152772) (GH-152779)

With one exception, all "stealing" functions also steal on error,
but it makes sense to note this in each case.

(cherry picked from commit 34503f39532279efb12653754bb3a7e535fb66cc)
(cherry picked from commit f8fb02db9d1d83a2fe4d2a62dfda69a02023b75a)

Co-authored-by: Peter Bierma <[email protected]>

files:
M Doc/c-api/bytes.rst
M Doc/c-api/dict.rst
M Doc/c-api/exceptions.rst
M Doc/c-api/gen.rst
M Doc/c-api/intro.rst
M Doc/c-api/list.rst
M Doc/c-api/module.rst
M Doc/c-api/sequence.rst
M Doc/c-api/tuple.rst
M Doc/glossary.rst

diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst
index 38e6b7ef9931b9c..72b5ec8f68ce5bb 100644
--- a/Doc/c-api/bytes.rst
+++ b/Doc/c-api/bytes.rst
@@ -176,10 +176,11 @@ called with a non-bytes parameter.
 .. c:function:: void PyBytes_Concat(PyObject **bytes, PyObject *newpart)
 
    Create a new bytes object in *\*bytes* containing the contents of *newpart*
-   appended to *bytes*; the caller will own the new reference.  The reference 
to
-   the old value of *bytes* will be stolen.  If the new object cannot be
-   created, the old reference to *bytes* will still be discarded and the value
-   of *\*bytes* will be set to ``NULL``; the appropriate exception will be set.
+   appended to *bytes*; the caller will own the new reference.
+   The reference to the old value of *bytes* will be ":term:`stolen <steal>`".
+   If the new object cannot be created, the old reference to *bytes* will still
+   be "stolen", the value of *\*bytes* will be set to ``NULL``, and
+   the appropriate exception will be set.
 
 
 .. c:function:: void PyBytes_ConcatAndDel(PyObject **bytes, PyObject *newpart)
diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst
index b45bb043502bbaa..88dcb1225f61788 100644
--- a/Doc/c-api/dict.rst
+++ b/Doc/c-api/dict.rst
@@ -84,8 +84,8 @@ Dictionary Objects
 
    Insert *val* into the dictionary *p* with a key of *key*.  *key* must be
    :term:`hashable`; if it isn't, :exc:`TypeError` will be raised. Return
-   ``0`` on success or ``-1`` on failure.  This function *does not* steal a
-   reference to *val*.
+   ``0`` on success or ``-1`` on failure.
+   This function *does not* ":term:`steal`" a reference to *val*.
 
 
 .. c:function:: int PyDict_SetItemString(PyObject *p, const char *key, 
PyObject *val)
diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
index 1791f53f30e5bbb..22df73bd6717a3e 100644
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -503,7 +503,8 @@ Querying the error indicator
 
    .. warning::
 
-      This call steals a reference to *exc*, which must be a valid exception.
+      This call ":term:`steals <steal>`" a reference to *exc*,
+      which must be a valid exception.
 
    .. versionadded:: 3.12
 
@@ -641,7 +642,8 @@ Querying the error indicator
 
    Set the exception info, as known from ``sys.exc_info()``.  This refers
    to an exception that was *already caught*, not to an exception that was
-   freshly raised.  This function steals the references of the arguments.
+   freshly raised.  This function ":term:`steals <steal>`" the references
+   of the arguments.
    To clear the exception state, pass ``NULL`` for all three arguments.
    This function is kept for backwards compatibility. Prefer using
    :c:func:`PyErr_SetHandledException`.
@@ -658,8 +660,8 @@ Querying the error indicator
    .. versionchanged:: 3.11
       The ``type`` and ``traceback`` arguments are no longer used and
       can be NULL. The interpreter now derives them from the exception
-      instance (the ``value`` argument). The function still steals
-      references of all three arguments.
+      instance (the ``value`` argument). The function still
+      ":term:`steals <steal>`" references of all three arguments.
 
 
 Signal Handling
@@ -845,7 +847,7 @@ Exception Objects
 
    Set the context associated with the exception to *ctx*.  Use ``NULL`` to 
clear
    it.  There is no type check to make sure that *ctx* is an exception 
instance.
-   This steals a reference to *ctx*.
+   This ":term:`steals <steal>`" a reference to *ctx*.
 
 
 .. c:function:: PyObject* PyException_GetCause(PyObject *ex)
@@ -860,7 +862,8 @@ Exception Objects
 
    Set the cause associated with the exception to *cause*.  Use ``NULL`` to 
clear
    it.  There is no type check to make sure that *cause* is either an exception
-   instance or ``None``.  This steals a reference to *cause*.
+   instance or ``None``.
+   This ":term:`steals <steal>`" a reference to *cause*.
 
    The :attr:`~BaseException.__suppress_context__` attribute is implicitly set
    to ``True`` by this function.
diff --git a/Doc/c-api/gen.rst b/Doc/c-api/gen.rst
index 44f3bdbf959b9cd..ae7bf7c94aa5ea9 100644
--- a/Doc/c-api/gen.rst
+++ b/Doc/c-api/gen.rst
@@ -35,15 +35,15 @@ than explicitly calling :c:func:`PyGen_New` or 
:c:func:`PyGen_NewWithQualName`.
 .. c:function:: PyObject* PyGen_New(PyFrameObject *frame)
 
    Create and return a new generator object based on the *frame* object.
-   A reference to *frame* is stolen by this function. The argument must not be
-   ``NULL``.
+   A reference to *frame* is ":term:`stolen <steal>`" by this function (even
+   on error). The argument must not be ``NULL``.
 
 .. c:function:: PyObject* PyGen_NewWithQualName(PyFrameObject *frame, PyObject 
*name, PyObject *qualname)
 
    Create and return a new generator object based on the *frame* object,
    with ``__name__`` and ``__qualname__`` set to *name* and *qualname*.
-   A reference to *frame* is stolen by this function.  The *frame* argument
-   must not be ``NULL``.
+   A reference to *frame* is ":term:`stolen <steal>`" by this function (even
+   on error).  The *frame* argument must not be ``NULL``.
 
 .. c:function:: PyCodeObject* PyGen_GetCode(PyGenObject *gen)
 
@@ -67,8 +67,9 @@ Asynchronous Generator Objects
 .. c:function:: PyObject *PyAsyncGen_New(PyFrameObject *frame, PyObject *name, 
PyObject *qualname)
 
    Create a new asynchronous generator wrapping *frame*, with ``__name__`` and
-   ``__qualname__`` set to *name* and *qualname*. *frame* is stolen by this
-   function and must not be ``NULL``.
+   ``__qualname__`` set to *name* and *qualname*.
+   *frame* is ":term:`stolen <steal>`" by this function (even on error) and
+   must not be ``NULL``.
 
    On success, this function returns a :term:`strong reference` to the
    new asynchronous generator. On failure, this function returns ``NULL``
diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst
index a49dde40a1c790f..2d3360a5a3bd927 100644
--- a/Doc/c-api/intro.rst
+++ b/Doc/c-api/intro.rst
@@ -592,9 +592,12 @@ the caller is said to *borrow* the reference. Nothing 
needs to be done for a
 
 Conversely, when a calling function passes in a reference to an  object, there
 are two possibilities: the function *steals* a  reference to the object, or it
-does not.  *Stealing a reference* means that when you pass a reference to a
-function, that function assumes that it now owns that reference, and you are 
not
-responsible for it any longer.
+does not.
+
+*Stealing a reference* means that when you pass a reference to a
+function, that function assumes that it now owns that reference.
+Since the new owner can use :c:func:`!Py_DECREF` at its discretion,
+you (the caller) must not use that reference after the call.
 
 .. index::
    single: PyList_SetItem (C function)
diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst
index 758415a76e5cb41..1d1c6e8658de385 100644
--- a/Doc/c-api/list.rst
+++ b/Doc/c-api/list.rst
@@ -88,8 +88,10 @@ List Objects
 
    .. note::
 
-      This function "steals" a reference to *item* and discards a reference to
-      an item already in the list at the affected position.
+      This function ":term:`steals <steal>`" a reference to *item*,
+      even on error.
+      On success, it discards a reference to an item already in the list
+      at the affected position (unless it was ``NULL``).
 
 
 .. c:function:: void PyList_SET_ITEM(PyObject *list, Py_ssize_t i, PyObject *o)
@@ -103,7 +105,7 @@ List Objects
 
    .. note::
 
-      This macro "steals" a reference to *item*, and, unlike
+      This macro ":term:`steals <steal>`" a reference to *item*, and, unlike
       :c:func:`PyList_SetItem`, does *not* discard a reference to any item that
       is being replaced; any reference in *list* at position *i* will be
       leaked.
diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst
index 1296f14f32c4255..419865180383a56 100644
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -617,8 +617,8 @@ state:
 
 .. c:function:: int PyModule_Add(PyObject *module, const char *name, PyObject 
*value)
 
-   Similar to :c:func:`PyModule_AddObjectRef`, but "steals" a reference
-   to *value*.
+   Similar to :c:func:`PyModule_AddObjectRef`, but ":term:`steals <steal>`"
+   a reference to *value* (even on error).
    It can be called with a result of function that returns a new reference
    without bothering to check its result or even saving it to a variable.
 
@@ -633,8 +633,8 @@ state:
 
 .. c:function:: int PyModule_AddObject(PyObject *module, const char *name, 
PyObject *value)
 
-   Similar to :c:func:`PyModule_AddObjectRef`, but steals a reference to
-   *value* on success (if it returns ``0``).
+   Similar to :c:func:`PyModule_AddObjectRef`, but :term:`steals <steal>`
+   a reference to *value* on success (if it returns ``0``).
 
    The new :c:func:`PyModule_Add` or :c:func:`PyModule_AddObjectRef`
    functions are recommended, since it is
diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst
index ce28839f5ba739d..465c55b5352d6c3 100644
--- a/Doc/c-api/sequence.rst
+++ b/Doc/c-api/sequence.rst
@@ -67,7 +67,7 @@ Sequence Protocol
    Assign object *v* to the *i*\ th element of *o*.  Raise an exception
    and return ``-1`` on failure; return ``0`` on success.  This
    is the equivalent of the Python statement ``o[i] = v``.  This function *does
-   not* steal a reference to *v*.
+   not* ":term:`steal`" a reference to *v*.
 
    If *v* is ``NULL``, the element is deleted, but this feature is
    deprecated in favour of using :c:func:`PySequence_DelItem`.
diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst
index cfb3fbb44431aca..6b4d08e6bff223b 100644
--- a/Doc/c-api/tuple.rst
+++ b/Doc/c-api/tuple.rst
@@ -90,8 +90,9 @@ Tuple Objects
 
    .. note::
 
-      This function "steals" a reference to *o* and discards a reference to
-      an item already in the tuple at the affected position.
+      This function ":term:`steals <steal>`" a reference to *o* and discards
+      a reference to an item already in the tuple at the affected position
+      (unless it was NULL).
 
 
 .. c:function:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o)
@@ -104,7 +105,7 @@ Tuple Objects
 
    .. note::
 
-      This function "steals" a reference to *o*, and, unlike
+      This function ":term:`steals <steal>`" a reference to *o*, and, unlike
       :c:func:`PyTuple_SetItem`, does *not* discard a reference to any item 
that
       is being replaced; any reference in the tuple at position *pos* will be
       leaked.
@@ -238,7 +239,7 @@ type.
 
    .. note::
 
-      This function "steals" a reference to *o*.
+      This function ":term:`steals <steal>`" a reference to *o*.
 
 
 .. c:function:: void PyStructSequence_SET_ITEM(PyObject *p, Py_ssize_t *pos, 
PyObject *o)
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index 9275ca663341f3f..a31c699b13993d9 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -1435,6 +1435,14 @@ Glossary
    stdlib
       An abbreviation of :term:`standard library`.
 
+   steal
+      In Python's C API, "*stealing*" an argument means that ownership of the
+      argument is transferred to the called function.
+      The caller must not use that reference after the call.
+      Generally, functions that "steal" an argument do so even if they fail.
+
+      See :ref:`api-refcountdetails` for a full explanation.
+
    strong reference
       In Python's C API, a strong reference is a reference to an object
       which is owned by the code holding the reference.  The strong

_______________________________________________
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]

Reply via email to