Skip to content
Open
Prev Previous commit
Next Next commit
docs: Update ShareableList documentation for fixed trailing null bug
The bug where ShareableList stripped trailing null bytes has been fixed
in Python 3.15. Update documentation to:
- Note the fix with versionchanged directive
- Update doctest to show correct behavior (nulls preserved)
- Clarify workaround is only needed for Python 3.14 and earlier
- Reference both original issue #106939 and fix issue #145261

Fixes failing doctest in CI where expected output showed old buggy
behavior instead of corrected behavior.
  • Loading branch information
stefanzetzsche committed Feb 27, 2026
commit 3f874bc648b58eead1857d1e1f4baff6fdc478e3
27 changes: 17 additions & 10 deletions Doc/library/multiprocessing.shared_memory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -313,26 +313,33 @@ finishes execution.

.. note::

A known issue exists for :class:`bytes` and :class:`str` values.
If they end with ``\x00`` nul bytes or characters, those may be
.. versionchanged:: 3.15
Fixed a bug where :class:`bytes` and :class:`str` values ending with
``\x00`` nul bytes or characters were silently stripped when fetching
them by index. Trailing nulls are now preserved correctly.
See :gh:`106939` and :gh:`145261`.

In Python 3.14 and earlier, a bug exists where :class:`bytes` and
:class:`str` values ending with ``\x00`` nul bytes or characters may be
*silently stripped* when fetching them by index from the
:class:`!ShareableList`. This ``.rstrip(b'\x00')`` behavior is
considered a bug and may go away in the future. See :gh:`106939`.
:class:`!ShareableList`. This ``.rstrip(b'\x00')`` behavior has been
fixed in Python 3.15.

For applications where rstripping of trailing nulls is a problem,
work around it by always unconditionally appending an extra non-0
byte to the end of such values when storing and unconditionally
removing it when fetching:
For applications that need to work with Python 3.14 and earlier where
rstripping of trailing nulls is a problem, work around it by always
unconditionally appending an extra non-0 byte to the end of such values
when storing and unconditionally removing it when fetching:

.. doctest::

>>> from multiprocessing import shared_memory
>>> nul_bug_demo = shared_memory.ShareableList(['?\x00', b'\x03\x02\x01\x00\x00\x00'])
>>> nul_bug_demo[0]
'?'
'?\x00'
>>> nul_bug_demo[1]
b'\x03\x02\x01'
b'\x03\x02\x01\x00\x00\x00'
>>> nul_bug_demo.shm.unlink()
>>> # Workaround for Python 3.14 and earlier (not needed in 3.15+):
>>> padded = shared_memory.ShareableList(['?\x00\x07', b'\x03\x02\x01\x00\x00\x00\x07'])
>>> padded[0][:-1]
'?\x00'
Expand Down
Loading