Skip to content

gh-69011: ctypes.create_*_buffer clarify NUL termination character inclusion #132858

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
79 changes: 64 additions & 15 deletions Doc/library/ctypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2031,35 +2031,84 @@ Utility functions
pointer.


.. function:: create_string_buffer(init_or_size, size=None)
.. function:: create_string_buffer(init, size=None)
create_string_buffer(size)

This function creates a mutable character buffer. The returned object is a
ctypes array of :class:`c_char`.

*init_or_size* must be an integer which specifies the size of the array, or a
bytes object which will be used to initialize the array items.
If *size* is given (and not ``None``), it must be an :class:`int`.
It specifies the size of the returned array.

If a bytes object is specified as first argument, the buffer is made one item
larger than its length so that the last element in the array is a NUL
termination character. An integer can be passed as second argument which allows
specifying the size of the array if the length of the bytes should not be used.
If the *init* argument is given, it must be :class:`bytes`. It is used
to initialize the array items. Bytes not initialized this way are
set to zero (NUL).

If *size* is not given (or if it is ``None``), the buffer is made one byte
larger than *init*, effectively adding a NUL termination byte.

If both arguments are given, *size* must not be less than ``len(init)``.

.. warning::

If *size* is equal to ``len(init)``, a NUL terminator is
not added. Do not treat such a buffer as a C string.

For example::

>>> bytes(create_string_buffer(2))
b'\x00\x00'
>>> bytes(create_string_buffer(b'ab'))
b'ab\x00'
>>> bytes(create_string_buffer(b'ab', 2))
b'ab'
>>> bytes(create_string_buffer(b'ab', 4))
b'ab\x00\x00'
>>> bytes(create_string_buffer(b'abcdef', 2))
Traceback (most recent call last):
...
ValueError: byte string too long

.. audit-event:: ctypes.create_string_buffer init,size ctypes.create_string_buffer


.. function:: create_unicode_buffer(init_or_size, size=None)
.. function:: create_unicode_buffer(init, size=None)
create_unicode_buffer(size)

This function creates a mutable unicode character buffer. The returned object is
a ctypes array of :class:`c_wchar`.

*init_or_size* must be an integer which specifies the size of the array, or a
string which will be used to initialize the array items.
If *size* is given (and not ``None``), it must be an :class:`int`.
It specifies the size of the returned array.

If the *init* argument is given, it must be a string. It is used
to initialize the array items. Bytes not initialized this way are
set to zero (NUL).

If *size* is not given (or if it is ``None``), the buffer is made one byte
larger than *init*, effectively adding a NUL termination byte.

If both arguments are given, *size* must not be less than ``len(init)``.

.. warning::

If *size* is equal to ``len(init)``, a NUL terminator is
not added. Do not treat such a buffer as a C string.

For example::

If a string is specified as first argument, the buffer is made one item
larger than the length of the string so that the last element in the array is a
NUL termination character. An integer can be passed as second argument which
allows specifying the size of the array if the length of the string should not
be used.
>>> bytes(create_unicode_buffer(2))
b'\x00\x00\x00\x00\x00\x00\x00\x00'
>>> bytes(create_unicode_buffer('ab'))
b'a\x00\x00\x00b\x00\x00\x00\x00\x00\x00\x00'
>>> bytes(create_unicode_buffer('ab', 2))
b'a\x00\x00\x00b\x00\x00\x00'
>>> bytes(create_unicode_buffer('ab', 4))
b'a\x00\x00\x00b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> bytes(create_unicode_buffer('abcdef', 2))
Traceback (most recent call last):
...
ValueError: string too long

.. audit-event:: ctypes.create_unicode_buffer init,size ctypes.create_unicode_buffer

Expand Down
Loading