https://github.com/python/cpython/commit/1e4d32aa5d660832439aa79155a8b5f8e6761ebf
commit: 1e4d32aa5d660832439aa79155a8b5f8e6761ebf
branch: 3.15
author: Miss Islington (bot) <[email protected]>
committer: methane <[email protected]>
date: 2026-11-04T13:40:22Z
summary:

docs: Correct ctypes examples and outdated descriptions (GH-161303)

(cherry picked from commit 6fa6d098b59d14f9389c86fc24efb62e0db8664b)

Co-authored-by: Inada Naoki <[email protected]>

files:
M Doc/library/ctypes.rst

diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
index 3326df34d9ad45..340e114bd4dfc4 100644
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -424,7 +424,7 @@ string objects are immutable)::
    >>> print(c_s)
    c_wchar_p(139966785747344)
    >>> print(c_s.value)
-   Hello World
+   Hello, World
    >>> c_s.value = "Hi, there"
    >>> print(c_s)              # the memory location has changed
    c_wchar_p(139966783348904)
@@ -809,9 +809,8 @@ compiler does it.  It is possible to override this behavior 
entirely by specifyi
 :attr:`~Structure._layout_` class attribute in the subclass definition; see
 the attribute documentation for details.
 
-It is possible to specify the maximum alignment for the fields and/or for the
-structure itself by setting the class attributes :attr:`~Structure._pack_`
-and/or :attr:`~Structure._align_`, respectively.
+The :attr:`~Structure._align_` class attribute specifies the minimum alignment
+for the structure itself.
 See the attribute documentation for details.
 
 :mod:`!ctypes` uses the native byte order for Structures and Unions.  To build
@@ -1032,10 +1031,10 @@ to synchronize access to memory:
       >>> lock = threading.Lock()
       >>> # Thread 1
       >>> with lock:
-      ...    pointer_a.contents = 24
+      ...    pointer_a[0] = 24
       >>> # Thread 2
       >>> with lock:
-      ...    pointer_b.contents = 42
+      ...    pointer_b[0] = 42
 
 
 .. _ctypes-type-conversions:
@@ -1166,7 +1165,7 @@ other, and finally follow the pointer chain a few times::
    ...     print(p.name, end=" ")
    ...     p = p.next[0]
    ...
-   foo bar foo bar foo bar foo bar
+   b'foo' b'bar' b'foo' b'bar' b'foo' b'bar' b'foo' b'bar'
    >>>
 
 
@@ -1302,17 +1301,13 @@ api::
    0x30c00a0
 
 An extended example which also demonstrates the use of pointers accesses the
-:c:data:`PyImport_FrozenModules` pointer exported by Python.
-
-Quoting the docs for that value:
+``_PyImport_FrozenBootstrap`` pointer exported by Python. It points to an array
+of :c:struct:`_frozen` records describing frozen modules used during startup,
+terminated by one whose members are all ``NULL`` or zero. This is similar to
+the :c:data:`PyImport_FrozenModules` table, which third-party code can use to
+provide additional frozen modules.
 
-   This pointer is initialized to point to an array of :c:struct:`_frozen`
-   records, terminated by one whose members are all ``NULL`` or zero.  When a 
frozen
-   module is imported, it is searched in this table.  Third-party code could 
play
-   tricks with this to provide a dynamically created collection of frozen 
modules.
-
-So manipulating this pointer could even prove useful. To restrict the example
-size, we show only how this table can be read with :mod:`!ctypes`::
+We can read this table with :mod:`!ctypes`::
 
    >>> from ctypes import *
    >>>
@@ -1320,7 +1315,7 @@ size, we show only how this table can be read with 
:mod:`!ctypes`::
    ...     _fields_ = [("name", c_char_p),
    ...                 ("code", POINTER(c_ubyte)),
    ...                 ("size", c_int),
-   ...                 ("get_code", POINTER(c_ubyte)),  # Function pointer
+   ...                 ("is_package", c_int),
    ...                ]
    ...
    >>>
@@ -1348,9 +1343,9 @@ hit the ``NULL`` entry::
    zipimport 12345
    >>>
 
-The fact that standard Python has a frozen module and a frozen package
-(indicated by the negative ``size`` member) is not well known, it is only used
-for testing. Try it out with ``import __hello__`` for example.
+Frozen packages are indicated by a nonzero ``is_package`` member. Python also
+includes frozen modules and packages used for testing, such as ``__hello__``
+and ``__phello__``, in a separate table, ``_PyImport_FrozenTest``.
 
 
 .. _ctypes-surprises:
@@ -1927,8 +1922,8 @@ in :mod:`!ctypes`) which inherits from the private 
:class:`_CFuncPtr` class:
       :meth:`~_CData.from_param` class method of the items in the 
:attr:`argtypes`
       tuple, this method allows adapting the actual argument to an object that
       the foreign function accepts.  For example, a :class:`c_char_p` item in
-      the :attr:`argtypes` tuple will convert a string passed as argument into
-      a bytes object using ctypes conversion rules.
+      the :attr:`argtypes` tuple will adapt a bytes object passed as an 
argument
+      to a C pointer to its contents. It does not accept a :class:`str` object.
 
       New: It is now possible to put items in argtypes which are not ctypes
       types, but each item must have a :meth:`~_CData.from_param` method which 
returns a
@@ -2633,7 +2628,7 @@ Fundamental data types
       and :c:expr:`time_t` C types are the same, then :class:`c_long`,
       :class:`c_longlong` and :class:`c_time_t` all refer to a single class,
       :class:`c_long`, whose :attr:`_type_` code is ``'l'``.
-      The ``'L'`` code will be unused.
+      The ``'q'`` code will be unused.
 
       .. seealso::
 
@@ -2645,10 +2640,8 @@ Fundamental data types
 Fundamental data types, when returned as foreign function call results, or, for
 example, by retrieving structure field members or array items, are 
transparently
 converted to native Python types.  In other words, if a foreign function has a
-:attr:`~_CFuncPtr.restype` of :class:`c_char_p`, you will always receive a 
Python bytes
-object, *not* a :class:`c_char_p` instance.
-
-.. XXX above is false, it actually returns a Unicode string
+:attr:`~_CFuncPtr.restype` of :class:`c_char_p`, you will receive a Python 
bytes
+object or ``None`` for a ``NULL`` pointer, *not* a :class:`c_char_p` instance.
 
 Subclasses of fundamental data types do *not* inherit this behavior. So, if a
 foreign functions :attr:`!restype` is a subclass of :class:`c_void_p`, you will
@@ -3358,7 +3351,7 @@ fields, or any other data types containing pointer type 
fields.
    Concrete structure and union types must be created by subclassing one of 
these
    types, and at least define a :attr:`_fields_` class variable. 
:mod:`!ctypes` will
    create :term:`descriptor`\s which allow reading and writing the fields by 
direct
-   attribute accesses.  These are the
+   attribute accesses.
 
 
    .. attribute:: _fields_
@@ -3388,8 +3381,8 @@ fields, or any other data types containing pointer type 
fields.
       Later assignments will raise an :exc:`AttributeError`.
 
       Additionally, the :attr:`!_fields_` class variable must be defined before
-      the structure or union type is first used: an instance or subclass is
-      created, :func:`sizeof` is called on it, and so on.
+      the structure or union type is first used, for example when an instance
+      or subclass is created.
       Later assignments to :attr:`!_fields_` will raise an 
:exc:`AttributeError`.
       If :attr:`!_fields_` has not been set before such use,
       the structure or union will have no own fields, as if :attr:`!_fields_`
@@ -3486,15 +3479,17 @@ fields, or any other data types containing pointer type 
fields.
 
       Here is an example type (Windows)::
 
+         class TYPEDESC(Structure):
+             pass
+
          class _U(Union):
              _fields_ = [("lptdesc", POINTER(TYPEDESC)),
                          ("lpadesc", POINTER(ARRAYDESC)),
                          ("hreftype", HREFTYPE)]
 
-         class TYPEDESC(Structure):
-             _anonymous_ = ("u",)
-             _fields_ = [("u", _U),
-                         ("vt", VARTYPE)]
+         TYPEDESC._anonymous_ = ("u",)
+         TYPEDESC._fields_ = [("u", _U),
+                             ("vt", VARTYPE)]
 
 
       The ``TYPEDESC`` structure describes a COM data type, the ``vt`` field
@@ -3504,10 +3499,11 @@ fields, or any other data types containing pointer type 
fields.
       are equivalent, but the former is faster since it does not need to create
       a temporary union instance::
 
+         some_type = TYPEDESC()
          td = TYPEDESC()
          td.vt = VT_PTR
-         td.lptdesc = POINTER(some_type)
-         td.u.lptdesc = POINTER(some_type)
+         td.lptdesc = pointer(some_type)
+         td.u.lptdesc = pointer(some_type)
 
    It is possible to define sub-subclasses of structures, they inherit the
    fields of the base class.  If the subclass definition has a separate
@@ -3602,7 +3598,7 @@ fields, or any other data types containing pointer type 
fields.
       :attr:`~CField.byte_offset`.
 
       To get the field's value, read the storage unit as an integer,
-      :ref:`shift left <shifting>` by :attr:`!bit_offset` and
+      :ref:`shift right <shifting>` by :attr:`!bit_offset` and
       take the :attr:`!bit_size` least significant bits.
 
       For non-bitfields, :attr:`!bit_offset` is zero

_______________________________________________
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