Skip to content

Commit 7b162a4

Browse files
encukoumiss-islington
authored andcommitted
pythongh-129675: Update documentation for tp_basicsize & tp_itemsize (pythonGH-129850)
* Update documentation for tp_basicsize & tp_itemsize - Add alignment requirement - Mention that ob_size is unreliable if you don't control it - Add some links for context - basicsize should include the base type in generaly not just PyObject This adds a “by-the-way” link to `PyObject_New`, which shouldn't be used for GC types. In order to be comfortable linking to it, I also add a link to `PyObject_GC_New` from its docs. And the same for `*Var` variants, while I'm here. * Strongly suggest Py_SIZE & Py_SET_SIZE (cherry picked from commit ad0f618) Co-authored-by: Petr Viktorin <encukou@gmail.com>
1 parent 33605da commit 7b162a4

File tree

3 files changed

+83
-30
lines changed

3 files changed

+83
-30
lines changed

Doc/c-api/allocation.rst

+8
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ Allocating Objects on the Heap
3535
The size of the memory allocation is determined from the
3636
:c:member:`~PyTypeObject.tp_basicsize` field of the type object.
3737
38+
Note that this function is unsuitable if *typeobj* has
39+
:c:macro:`Py_TPFLAGS_HAVE_GC` set. For such objects,
40+
use :c:func:`PyObject_GC_New` instead.
41+
3842
3943
.. c:macro:: PyObject_NewVar(TYPE, typeobj, size)
4044
@@ -49,6 +53,10 @@ Allocating Objects on the Heap
4953
fields into the same allocation decreases the number of allocations,
5054
improving the memory management efficiency.
5155
56+
Note that this function is unsuitable if *typeobj* has
57+
:c:macro:`Py_TPFLAGS_HAVE_GC` set. For such objects,
58+
use :c:func:`PyObject_GC_NewVar` instead.
59+
5260
5361
.. c:function:: void PyObject_Del(void *op)
5462

Doc/c-api/type.rst

+3
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,9 @@ The following functions and structs are used to create
397397
class need *in addition* to the superclass.
398398
Use :c:func:`PyObject_GetTypeData` to get a pointer to subclass-specific
399399
memory reserved this way.
400+
For negative :c:member:`!basicsize`, Python will insert padding when
401+
needed to meet :c:member:`~PyTypeObject.tp_basicsize`'s alignment
402+
requirements.
400403
401404
.. versionchanged:: 3.12
402405

Doc/c-api/typeobj.rst

+72-30
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,9 @@ PyVarObject Slots
559559
initialized to zero. For :ref:`dynamically allocated type objects
560560
<heap-types>`, this field has a special internal meaning.
561561

562+
This field should be accessed using the :c:func:`Py_SIZE()` and
563+
:c:func:`Py_SET_SIZE()` macros.
564+
562565
**Inheritance:**
563566

564567
This field is not inherited by subtypes.
@@ -609,47 +612,86 @@ and :c:data:`PyType_Type` effectively act as defaults.)
609612

610613

611614
.. c:member:: Py_ssize_t PyTypeObject.tp_basicsize
612-
Py_ssize_t PyTypeObject.tp_itemsize
615+
Py_ssize_t PyTypeObject.tp_itemsize
613616
614617
These fields allow calculating the size in bytes of instances of the type.
615618

616619
There are two kinds of types: types with fixed-length instances have a zero
617-
:c:member:`~PyTypeObject.tp_itemsize` field, types with variable-length instances have a non-zero
618-
:c:member:`~PyTypeObject.tp_itemsize` field. For a type with fixed-length instances, all
619-
instances have the same size, given in :c:member:`~PyTypeObject.tp_basicsize`.
620+
:c:member:`!tp_itemsize` field, types with variable-length instances have a non-zero
621+
:c:member:`!tp_itemsize` field. For a type with fixed-length instances, all
622+
instances have the same size, given in :c:member:`!tp_basicsize`.
623+
(Exceptions to this rule can be made using
624+
:c:func:`PyUnstable_Object_GC_NewWithExtraData`.)
620625

621626
For a type with variable-length instances, the instances must have an
622-
:c:member:`~PyVarObject.ob_size` field, and the instance size is :c:member:`~PyTypeObject.tp_basicsize` plus N
623-
times :c:member:`~PyTypeObject.tp_itemsize`, where N is the "length" of the object. The value of
624-
N is typically stored in the instance's :c:member:`~PyVarObject.ob_size` field. There are
625-
exceptions: for example, ints use a negative :c:member:`~PyVarObject.ob_size` to indicate a
626-
negative number, and N is ``abs(ob_size)`` there. Also, the presence of an
627-
:c:member:`~PyVarObject.ob_size` field in the instance layout doesn't mean that the instance
628-
structure is variable-length (for example, the structure for the list type has
629-
fixed-length instances, yet those instances have a meaningful :c:member:`~PyVarObject.ob_size`
630-
field).
631-
632-
The basic size includes the fields in the instance declared by the macro
633-
:c:macro:`PyObject_HEAD` or :c:macro:`PyObject_VAR_HEAD` (whichever is used to
634-
declare the instance struct) and this in turn includes the :c:member:`~PyObject._ob_prev` and
635-
:c:member:`~PyObject._ob_next` fields if they are present. This means that the only correct
636-
way to get an initializer for the :c:member:`~PyTypeObject.tp_basicsize` is to use the
637-
``sizeof`` operator on the struct used to declare the instance layout.
638-
The basic size does not include the GC header size.
627+
:c:member:`~PyVarObject.ob_size` field, and the instance size is
628+
:c:member:`!tp_basicsize` plus N times :c:member:`!tp_itemsize`,
629+
where N is the "length" of the object.
630+
631+
Functions like :c:func:`PyObject_NewVar` will take the value of N as an
632+
argument, and store in the instance's :c:member:`~PyVarObject.ob_size` field.
633+
Note that the :c:member:`~PyVarObject.ob_size` field may later be used for
634+
other purposes. For example, :py:type:`int` instances use the bits of
635+
:c:member:`~PyVarObject.ob_size` in an implementation-defined
636+
way; the underlying storage and its size should be acessed using
637+
:c:func:`PyLong_Export`.
638+
639+
.. note::
639640

640-
A note about alignment: if the variable items require a particular alignment,
641-
this should be taken care of by the value of :c:member:`~PyTypeObject.tp_basicsize`. Example:
642-
suppose a type implements an array of ``double``. :c:member:`~PyTypeObject.tp_itemsize` is
643-
``sizeof(double)``. It is the programmer's responsibility that
644-
:c:member:`~PyTypeObject.tp_basicsize` is a multiple of ``sizeof(double)`` (assuming this is the
645-
alignment requirement for ``double``).
641+
The :c:member:`~PyVarObject.ob_size` field should be accessed using
642+
the :c:func:`Py_SIZE()` and :c:func:`Py_SET_SIZE()` macros.
646643

647-
For any type with variable-length instances, this field must not be ``NULL``.
644+
Also, the presence of an :c:member:`~PyVarObject.ob_size` field in the
645+
instance layout doesn't mean that the instance structure is variable-length.
646+
For example, the :py:type:`list` type has fixed-length instances, yet those
647+
instances have a :c:member:`~PyVarObject.ob_size` field.
648+
(As with :py:type:`int`, avoid reading lists' :c:member:`!ob_size` directly.
649+
Call :c:func:`PyList_Size` instead.)
650+
651+
The :c:member:`!tp_basicsize` includes size needed for data of the type's
652+
:c:member:`~PyTypeObject.tp_base`, plus any extra data needed
653+
by each instance.
654+
655+
The correct way to set :c:member:`!tp_basicsize` is to use the
656+
``sizeof`` operator on the struct used to declare the instance layout.
657+
This struct must include the struct used to declare the base type.
658+
In other words, :c:member:`!tp_basicsize` must be greater than or equal
659+
to the base's :c:member:`!tp_basicsize`.
660+
661+
Since every type is a subtype of :py:type:`object`, this struct must
662+
include :c:type:`PyObject` or :c:type:`PyVarObject` (depending on
663+
whether :c:member:`~PyVarObject.ob_size` should be included). These are
664+
usually defined by the macro :c:macro:`PyObject_HEAD` or
665+
:c:macro:`PyObject_VAR_HEAD`, respectively.
666+
667+
The basic size does not include the GC header size, as that header is not
668+
part of :c:macro:`PyObject_HEAD`.
669+
670+
For cases where struct used to declare the base type is unknown,
671+
see :c:member:`PyType_Spec.basicsize` and :c:func:`PyType_FromMetaclass`.
672+
673+
Notes about alignment:
674+
675+
- :c:member:`!tp_basicsize` must be a multiple of ``_Alignof(PyObject)``.
676+
When using ``sizeof`` on a ``struct`` that includes
677+
:c:macro:`PyObject_HEAD`, as recommended, the compiler ensures this.
678+
When not using a C ``struct``, or when using compiler
679+
extensions like ``__attribute__((packed))``, it is up to you.
680+
- If the variable items require a particular alignment,
681+
:c:member:`!tp_basicsize` and :c:member:`!tp_itemsize` must each be a
682+
multiple of that alignment.
683+
For example, if a type's variable part stores a ``double``, it is
684+
your responsibility that both fields are a multiple of
685+
``_Alignof(double)``.
648686

649687
**Inheritance:**
650688

651-
These fields are inherited separately by subtypes. If the base type has a
652-
non-zero :c:member:`~PyTypeObject.tp_itemsize`, it is generally not safe to set
689+
These fields are inherited separately by subtypes.
690+
(That is, if the field is set to zero, :c:func:`PyType_Ready` will copy
691+
the value from the base type, indicating that the instances do not
692+
need additional storage.)
693+
694+
If the base type has a non-zero :c:member:`~PyTypeObject.tp_itemsize`, it is generally not safe to set
653695
:c:member:`~PyTypeObject.tp_itemsize` to a different non-zero value in a subtype (though this
654696
depends on the implementation of the base type).
655697

0 commit comments

Comments
 (0)