https://github.com/python/cpython/commit/f8fb02db9d1d83a2fe4d2a62dfda69a02023b75a
commit: f8fb02db9d1d83a2fe4d2a62dfda69a02023b75a
branch: 3.14
author: Petr Viktorin <[email protected]>
committer: encukou <[email protected]>
date: 2026-07-01T14:25:56+02:00
summary:

[3.14] gh-144473: Add "steal" term to glossary; clarify "stealing" on error 
(GH-144502) (GH-152772)

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)

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/threads.rst
M Doc/c-api/tuple.rst
M Doc/c-api/unicode.rst
M Doc/glossary.rst

diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst
index 3a34b5329eb7ef4..b90d030719eca5b 100644
--- a/Doc/c-api/bytes.rst
+++ b/Doc/c-api/bytes.rst
@@ -180,10 +180,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.
 
    .. note::
       If *newpart* implements the buffer protocol, then the buffer
diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst
index b77a07399361862..4c19af0d3a806e4 100644
--- a/Doc/c-api/dict.rst
+++ b/Doc/c-api/dict.rst
@@ -89,8 +89,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*.
 
    .. note::
 
diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
index 575fbc14f33f2cc..6e9b0733fb628c2 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
@@ -851,7 +853,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)
@@ -866,7 +868,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 74db49a6814800b..3d51e7dacc33849 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)
@@ -68,8 +68,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 d73377fb6e6173d..f39b253a7cfe6bb 100644
--- a/Doc/c-api/intro.rst
+++ b/Doc/c-api/intro.rst
@@ -641,9 +641,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 8f560699d355e49..21769c4c5c869c8 100644
--- a/Doc/c-api/list.rst
+++ b/Doc/c-api/list.rst
@@ -102,8 +102,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)
@@ -117,7 +119,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 5a562721ce5df42..51e81917b2cfebf 100644
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -559,8 +559,8 @@ or code that creates modules dynamically.
 
 .. 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.
 
@@ -575,8 +575,8 @@ or code that creates modules dynamically.
 
 .. 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 6bae8f25ad75d15..90490cf6749b59c 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/threads.rst b/Doc/c-api/threads.rst
index badbdee564d4273..7a528d712a3edd1 100644
--- a/Doc/c-api/threads.rst
+++ b/Doc/c-api/threads.rst
@@ -741,7 +741,7 @@ pointer and a void pointer argument.
 
    Asynchronously raise an exception in a thread. The *id* argument is the 
thread
    id of the target thread; *exc* is the exception object to be raised. This
-   function does not steal any references to *exc*. To prevent naive misuse, 
you
+   function does not :term:`steal` any references to *exc*. To prevent naive 
misuse, you
    must write your own C extension to call this.  Must be called with an 
:term:`attached thread state`.
    Returns the number of thread states modified; this is normally one, but 
will be
    zero if the thread id isn't found.  If *exc* is ``NULL``, the pending
diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst
index be960243f763664..157b303d0b903fc 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.
@@ -244,7 +245,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/c-api/unicode.rst b/Doc/c-api/unicode.rst
index a47d9f7e2bb5f67..aa2288fb77dc383 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -663,7 +663,8 @@ APIs:
 
    Append the string *right* to the end of *p_left*.
    *p_left* must point to a :term:`strong reference` to a Unicode object;
-   :c:func:`!PyUnicode_Append` releases ("steals") this reference.
+   :c:func:`!PyUnicode_Append` releases (":term:`steals <steal>`")
+   this reference.
 
    On error, set *\*p_left* to ``NULL`` and set an exception.
 
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index 7b74651fda1fe5a..515fa77dd038df2 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -1515,6 +1515,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