[Python-checkins] bpo-42294: Add borrowed/strong reference to doc glossary (GH-23206)

vstinner webhook-mailer at python.org
Mon Nov 9 07:40:57 EST 2020


https://github.com/python/cpython/commit/23c5f93b83f78f295313e137011edb18b24c37c2
commit: 23c5f93b83f78f295313e137011edb18b24c37c2
branch: master
author: Victor Stinner <vstinner at python.org>
committer: vstinner <vstinner at python.org>
date: 2020-11-09T13:40:47+01:00
summary:

bpo-42294: Add borrowed/strong reference to doc glossary (GH-23206)

Add "borrowed reference" and "strong reference" to the documentation
glossary.

Enhance also Py_INCREF() and Py_NewRef() documentation.

files:
M Doc/c-api/arg.rst
M Doc/c-api/init.rst
M Doc/c-api/intro.rst
M Doc/c-api/refcounting.rst
M Doc/c-api/reflection.rst
M Doc/c-api/structures.rst
M Doc/c-api/typeobj.rst
M Doc/c-api/weakref.rst
M Doc/data/refcounts.dat
M Doc/glossary.rst
M Include/object.h

diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
index bdaae44e240a0..a91b3c7c9505f 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -482,7 +482,8 @@ API Functions
    *min* and no more than *max*; *min* and *max* may be equal.  Additional
    arguments must be passed to the function, each of which should be a pointer to a
    :c:type:`PyObject*` variable; these will be filled in with the values from
-   *args*; they will contain borrowed references.  The variables which correspond
+   *args*; they will contain :term:`borrowed references <borrowed reference>`.
+   The variables which correspond
    to optional parameters not given by *args* will not be filled in; these should
    be initialized by the caller. This function returns true on success and false if
    *args* is not a tuple or contains the wrong number of elements; an exception
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index 3ce689203a817..3d18bb3f0b9d8 100644
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -1077,7 +1077,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
 
    Get the current frame of the Python thread state *tstate*.
 
-   Return a strong reference. Return ``NULL`` if no frame is currently
+   Return a :term:`strong reference`. Return ``NULL`` if no frame is currently
    executing.
 
    See also :c:func:`PyEval_GetFrame`.
diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst
index 7ca8693afab79..bae5ce11b73c4 100644
--- a/Doc/c-api/intro.rst
+++ b/Doc/c-api/intro.rst
@@ -326,7 +326,7 @@ when it's no longer needed---or passing on this responsibility (usually to its
 caller). When a function passes ownership of a reference on to its caller, the
 caller is said to receive a *new* reference.  When no ownership is transferred,
 the caller is said to *borrow* the reference. Nothing needs to be done for a
-borrowed reference.
+:term:`borrowed reference`.
 
 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
diff --git a/Doc/c-api/refcounting.rst b/Doc/c-api/refcounting.rst
index b15c0e6aecc89..391907c8c2976 100644
--- a/Doc/c-api/refcounting.rst
+++ b/Doc/c-api/refcounting.rst
@@ -13,10 +13,14 @@ objects.
 
 .. c:function:: void Py_INCREF(PyObject *o)
 
-   Increment the reference count for object *o*.  The object must not be ``NULL``; if
-   you aren't sure that it isn't ``NULL``, use :c:func:`Py_XINCREF`.
+   Increment the reference count for object *o*.
 
-   See also :c:func:`Py_NewRef`.
+   This function is usually used to convert a :term:`borrowed reference` to a
+   :term:`strong reference` in-place. The :c:func:`Py_NewRef` function can be
+   used to create a new :term:`strong reference`.
+
+   The object must not be ``NULL``; if you aren't sure that it isn't
+   ``NULL``, use :c:func:`Py_XINCREF`.
 
 
 .. c:function:: void Py_XINCREF(PyObject *o)
@@ -29,9 +33,14 @@ objects.
 
 .. c:function:: PyObject* Py_NewRef(PyObject *o)
 
-   Increment the reference count of the object *o* and return the object *o*.
+   Create a new :term:`strong reference` to an object: increment the reference
+   count of the object *o* and return the object *o*.
+
+   When the :term:`strong reference` is no longer needed, :c:func:`Py_DECREF`
+   should be called on it to decrement the object reference count.
 
-   The object *o* must not be ``NULL``.
+   The object *o* must not be ``NULL``; use :c:func:`Py_XNewRef` if *o* can be
+   ``NULL``.
 
    For example::
 
@@ -42,6 +51,8 @@ objects.
 
        self->attr = Py_NewRef(obj);
 
+   See also :c:func:`Py_INCREF`.
+
    .. versionadded:: 3.10
 
 
@@ -56,10 +67,16 @@ objects.
 
 .. c:function:: void Py_DECREF(PyObject *o)
 
-   Decrement the reference count for object *o*.  The object must not be ``NULL``; if
-   you aren't sure that it isn't ``NULL``, use :c:func:`Py_XDECREF`.  If the reference
-   count reaches zero, the object's type's deallocation function (which must not be
-   ``NULL``) is invoked.
+   Decrement the reference count for object *o*.
+
+   If the reference count reaches zero, the object's type's deallocation
+   function (which must not be ``NULL``) is invoked.
+
+   This function is usually used to delete a :term:`strong reference` before
+   exiting its scope.
+
+   The object must not be ``NULL``; if you aren't sure that it isn't ``NULL``,
+   use :c:func:`Py_XDECREF`.
 
    .. warning::
 
diff --git a/Doc/c-api/reflection.rst b/Doc/c-api/reflection.rst
index 9207d86012c8b..64ce4d1d0c34d 100644
--- a/Doc/c-api/reflection.rst
+++ b/Doc/c-api/reflection.rst
@@ -35,7 +35,7 @@ Reflection
 
    Get the *frame* next outer frame.
 
-   Return a strong reference, or ``NULL`` if *frame* has no outer frame.
+   Return a :term:`strong reference`, or ``NULL`` if *frame* has no outer frame.
 
    *frame* must not be ``NULL``.
 
@@ -46,7 +46,7 @@ Reflection
 
    Get the *frame* code.
 
-   Return a strong reference.
+   Return a :term:`strong reference`.
 
    *frame* must not be ``NULL``. The result (frame code) cannot be ``NULL``.
 
diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst
index a9e1c6fbcc3f9..03fe479165ffa 100644
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -66,7 +66,7 @@ the definition of all other Python objects.
 
    Get the type of the Python object *o*.
 
-   Return a borrowed reference.
+   Return a :term:`borrowed reference`.
 
    .. versionchanged:: 3.10
       :c:func:`Py_TYPE()` is changed to the inline static function.
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index ddcb8ae3d0950..32bbc7ba0a168 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -1213,8 +1213,9 @@ and :c:type:`PyType_Type` effectively act as defaults.)
    :func:`~gc.get_referents` function will include it.
 
    .. warning::
-       When implementing :c:member:`~PyTypeObject.tp_traverse`, only the members
-       that the instance *owns* (by having strong references to them) must be
+       When implementing :c:member:`~PyTypeObject.tp_traverse`, only the
+       members that the instance *owns* (by having :term:`strong references
+       <strong reference>` to them) must be
        visited. For instance, if an object supports weak references via the
        :c:member:`~PyTypeObject.tp_weaklist` slot, the pointer supporting
        the linked list (what *tp_weaklist* points to) must **not** be
diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst
index e3a9bda54d671..fb6628a1bbf02 100644
--- a/Doc/c-api/weakref.rst
+++ b/Doc/c-api/weakref.rst
@@ -57,10 +57,10 @@ as much as it can.
 
    .. note::
 
-      This function returns a **borrowed reference** to the referenced object.
+      This function returns a :term:`borrowed reference` to the referenced object.
       This means that you should always call :c:func:`Py_INCREF` on the object
-      except if you know that it cannot be destroyed while you are still
-      using it.
+      except it cannot be destroyed before the last usage of the borrowed
+      reference.
 
 
 .. c:function:: PyObject* PyWeakref_GET_OBJECT(PyObject *ref)
diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat
index d01e99ca5e319..8a6ee718a012d 100644
--- a/Doc/data/refcounts.dat
+++ b/Doc/data/refcounts.dat
@@ -3007,6 +3007,9 @@ Py_GetVersion:const char*:::
 Py_INCREF:void:::
 Py_INCREF:PyObject*:o:+1:
 
+Py_NewRef:void:::
+Py_NewRef:PyObject*:o:+1:
+
 Py_Initialize:void:::
 
 Py_IsInitialized:int:::
@@ -3028,6 +3031,9 @@ Py_XDECREF:PyObject*:o:-1:if o is not NULL
 Py_XINCREF:void:::
 Py_XINCREF:PyObject*:o:+1:if o is not NULL
 
+Py_XNewRef:void:::
+Py_XNewRef:PyObject*:o:+1:if o is not NULL
+
 _PyImport_Fini:void:::
 
 _PyObject_New:PyObject*::+1:
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index 506973e964b33..b410585ca818c 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -158,6 +158,18 @@ Glossary
       See also :term:`text file` for a file object able to read and write
       :class:`str` objects.
 
+   borrowed reference
+      In the Python's C API, a borrowed reference is a reference to an object.
+      It does not modify the object reference count. It becomes a dangling
+      pointer if the object is destroyed. For example, a garbage collection can
+      remove the last :term:`strong reference` to the object and so destroy it.
+
+      Calling :c:func:`Py_INCREF` on the :term:`borrowed reference` is
+      recommended to convert it to a :term:`strong reference` in-place, except
+      if the object cannot be destroyed before the last usage of the borrowed
+      reference. The :c:func:`Py_NewRef` function can be used to create a new
+      :term:`strong reference`.
+
    bytes-like object
       An object that supports the :ref:`bufferobjects` and can
       export a C-:term:`contiguous` buffer. This includes all :class:`bytes`,
@@ -1100,6 +1112,18 @@ Glossary
       an :term:`expression` or one of several constructs with a keyword, such
       as :keyword:`if`, :keyword:`while` or :keyword:`for`.
 
+   strong reference
+      In the Python's C API, a strong reference is a reference to an object
+      which increments object reference count when it is created and
+      decrements the object reference count when it is deleted.
+
+      The :c:func:`Py_NewRef` function can be used to create a strong reference
+      to an object. Usually, the :c:func:`Py_DECREF` function must be called on
+      the strong reference before exiting the scope of the strong reference, to
+      avoid leaking one reference.
+
+      See also :term:`borrowed reference`.
+
    text encoding
       A codec which encodes Unicode strings to bytes.
 
diff --git a/Include/object.h b/Include/object.h
index 835d9de01fb72..eab3228f3abe4 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -526,10 +526,11 @@ they can have object code that is not dependent on Python compilation flags.
 PyAPI_FUNC(void) Py_IncRef(PyObject *);
 PyAPI_FUNC(void) Py_DecRef(PyObject *);
 
-// Increment the reference count of the object and return the object.
+// Create a new strong reference to an object:
+// increment the reference count of the object and return the object.
 PyAPI_FUNC(PyObject*) Py_NewRef(PyObject *obj);
 
-// Similar to Py_NewRef() but the object can be NULL.
+// Similar to Py_NewRef(), but the object can be NULL.
 PyAPI_FUNC(PyObject*) Py_XNewRef(PyObject *obj);
 
 static inline PyObject* _Py_NewRef(PyObject *obj)



More information about the Python-checkins mailing list