Skip to content

bpo-42294: Add borrowed/strong reference to doc glossary #23206

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

Merged
merged 2 commits into from
Nov 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Doc/c-api/arg.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Doc/c-api/init.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
2 changes: 1 addition & 1 deletion Doc/c-api/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
35 changes: 26 additions & 9 deletions Doc/c-api/refcounting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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::

Expand All @@ -42,6 +51,8 @@ objects.

self->attr = Py_NewRef(obj);

See also :c:func:`Py_INCREF`.

.. versionadded:: 3.10


Expand All @@ -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::

Expand Down
4 changes: 2 additions & 2 deletions Doc/c-api/reflection.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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``.

Expand All @@ -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``.

Expand Down
2 changes: 1 addition & 1 deletion Doc/c-api/structures.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 3 additions & 2 deletions Doc/c-api/typeobj.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions Doc/c-api/weakref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions Doc/data/refcounts.dat
Original file line number Diff line number Diff line change
Expand Up @@ -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:::
Expand All @@ -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:
Expand Down
24 changes: 24 additions & 0 deletions Doc/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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`,
Expand Down Expand Up @@ -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.

Expand Down
5 changes: 3 additions & 2 deletions Include/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down