https://github.com/python/cpython/commit/78e5d109f54351bb2360a32e1cdcdd6a09b08791
commit: 78e5d109f54351bb2360a32e1cdcdd6a09b08791
branch: 3.14
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: encukou <encu...@gmail.com>
date: 2025-07-08T08:03:03+02:00
summary:

[3.14] gh-135913: Document ob_refcnt, ob_type, ob_size (GH-135914) (GH-136377)

gh-135913: Document ob_refcnt, ob_type, ob_size (GH-135914)

* gh-135913: Document ob_refcnt, ob_type, ob_size

In `typeobj.rst`, instead of `:c:member:` it would be better to
use `.. c:member::` with a `:no-index:` option, see:

See ref. 
https://www.sphinx-doc.org/en/master/usage/domains/index.html#basic-markup

However, `c:member` currently does not support `:no-index:`.
(cherry picked from commit 73e1207a4ebdb3b43d597cd6c288dae6d7d1dbdb)

Co-authored-by: Petr Viktorin <encu...@gmail.com>

files:
M Doc/c-api/structures.rst
M Doc/c-api/typeobj.rst

diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst
index 987bc167c68d6c..58dd915e04f619 100644
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -28,18 +28,52 @@ under :ref:`reference counting <countingrefs>`.
    object.  In a normal "release" build, it contains only the object's
    reference count and a pointer to the corresponding type object.
    Nothing is actually declared to be a :c:type:`PyObject`, but every pointer
-   to a Python object can be cast to a :c:expr:`PyObject*`.  Access to the
-   members must be done by using the macros :c:macro:`Py_REFCNT` and
-   :c:macro:`Py_TYPE`.
+   to a Python object can be cast to a :c:expr:`PyObject*`.
+
+   The members must not be accessed directly; instead use macros such as
+   :c:macro:`Py_REFCNT` and :c:macro:`Py_TYPE`.
+
+   .. c:member:: Py_ssize_t ob_refcnt
+
+      The object's reference count, as returned by :c:macro:`Py_REFCNT`.
+      Do not use this field directly; instead use functions and macros such as
+      :c:macro:`!Py_REFCNT`, :c:func:`Py_INCREF` and :c:func:`Py_DecRef`.
+
+      The field type may be different from ``Py_ssize_t``, depending on
+      build configuration and platform.
+
+   .. c:member:: PyTypeObject* ob_type
+
+      The object's type.
+      Do not use this field directly; use :c:macro:`Py_TYPE` and
+      :c:func:`Py_SET_TYPE` instead.
 
 
 .. c:type:: PyVarObject
 
-   This is an extension of :c:type:`PyObject` that adds the 
:c:member:`~PyVarObject.ob_size`
-   field.  This is only used for objects that have some notion of *length*.
-   This type does not often appear in the Python/C API.
-   Access to the members must be done by using the macros
-   :c:macro:`Py_REFCNT`, :c:macro:`Py_TYPE`, and :c:macro:`Py_SIZE`.
+   An extension of :c:type:`PyObject` that adds the
+   :c:member:`~PyVarObject.ob_size` field.
+   This is intended for objects that have some notion of *length*.
+
+   As with :c:type:`!PyObject`, the members must not be accessed directly;
+   instead use macros such as :c:macro:`Py_SIZE`, :c:macro:`Py_REFCNT` and
+   :c:macro:`Py_TYPE`.
+
+   .. c:member:: Py_ssize_t ob_size
+
+      A size field, whose contents should be considered an object's internal
+      implementation detail.
+
+      Do not use this field directly; use :c:macro:`Py_SIZE` instead.
+
+      Object creation functions such as :c:func:`PyObject_NewVar` will
+      generally set this field to the requested size (number of items).
+      After creation, arbitrary values can be stored in :c:member:`!ob_size`
+      using :c:macro:`Py_SET_SIZE`.
+
+      To get an object's publicly exposed length, as returned by
+      the Python function :py:func:`len`, use :c:func:`PyObject_Length`
+      instead.
 
 
 .. c:macro:: PyObject_HEAD
@@ -103,9 +137,8 @@ under :ref:`reference counting <countingrefs>`.
 
    Get the type of the Python object *o*.
 
-   Return a :term:`borrowed reference`.
-
-   Use the :c:func:`Py_SET_TYPE` function to set an object type.
+   The returned reference is :term:`borrowed <borrowed reference>` from *o*.
+   Do not release it with :c:func:`Py_DECREF` or similar.
 
    .. versionchanged:: 3.11
       :c:func:`Py_TYPE()` is changed to an inline static function.
@@ -122,16 +155,26 @@ under :ref:`reference counting <countingrefs>`.
 
 .. c:function:: void Py_SET_TYPE(PyObject *o, PyTypeObject *type)
 
-   Set the object *o* type to *type*.
+   Set the type of object *o* to *type*, without any checking or reference
+   counting.
+
+   This is a very low-level operation.
+   Consider instead setting the Python attribute :attr:`~object.__class__`
+   using :c:func:`PyObject_SetAttrString` or similar.
+
+   Note that assigning an incompatible type can lead to undefined behavior.
+
+   If *type* is a :ref:`heap type <heap-types>`, the caller must create a
+   new reference to it.
+   Similarly, if the old type of *o* is a heap type, the caller must release
+   a reference to that type.
 
    .. versionadded:: 3.9
 
 
 .. c:function:: Py_ssize_t Py_SIZE(PyVarObject *o)
 
-   Get the size of the Python object *o*.
-
-   Use the :c:func:`Py_SET_SIZE` function to set an object size.
+   Get the :c:member:`~PyVarObject.ob_size` field of *o*.
 
    .. versionchanged:: 3.11
       :c:func:`Py_SIZE()` is changed to an inline static function.
@@ -140,7 +183,7 @@ under :ref:`reference counting <countingrefs>`.
 
 .. c:function:: void Py_SET_SIZE(PyVarObject *o, Py_ssize_t size)
 
-   Set the object *o* size to *size*.
+   Set the :c:member:`~PyVarObject.ob_size` field of *o* to *size*.
 
    .. versionadded:: 3.9
 
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index af2bead3bb5004..060d6f60174b41 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -492,9 +492,9 @@ metatype) initializes 
:c:member:`~PyTypeObject.tp_itemsize`, which means that it
 type objects) *must* have the :c:member:`~PyVarObject.ob_size` field.
 
 
-.. c:member:: Py_ssize_t PyObject.ob_refcnt
+:c:member:`PyObject.ob_refcnt`
 
-   This is the type object's reference count, initialized to ``1`` by the
+   The type object's reference count is initialized to ``1`` by the
    ``PyObject_HEAD_INIT`` macro.  Note that for :ref:`statically allocated type
    objects <static-types>`, the type's instances (objects whose 
:c:member:`~PyObject.ob_type`
    points back to the type) do *not* count as references.  But for
@@ -506,7 +506,7 @@ type objects) *must* have the 
:c:member:`~PyVarObject.ob_size` field.
    This field is not inherited by subtypes.
 
 
-.. c:member:: PyTypeObject* PyObject.ob_type
+:c:member:`PyObject.ob_type`
 
    This is the type's type, in other words its metatype.  It is initialized by 
the
    argument to the ``PyObject_HEAD_INIT`` macro, and its value should normally 
be
@@ -532,14 +532,13 @@ type objects) *must* have the 
:c:member:`~PyVarObject.ob_size` field.
 PyVarObject Slots
 -----------------
 
-.. c:member:: Py_ssize_t PyVarObject.ob_size
+:c:member:`PyVarObject.ob_size`
 
    For :ref:`statically allocated type objects <static-types>`, this should be
    initialized to zero. For :ref:`dynamically allocated type objects
    <heap-types>`, this field has a special internal meaning.
 
-   This field should be accessed using the :c:func:`Py_SIZE()` and
-   :c:func:`Py_SET_SIZE()` macros.
+   This field should be accessed using the :c:func:`Py_SIZE()` macro.
 
    **Inheritance:**
 

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: arch...@mail-archive.com

Reply via email to