[Python-checkins] gh-106939: document ShareableList nul-strip quirk. (#107266)

gpshead webhook-mailer at python.org
Tue Jul 25 17:09:29 EDT 2023


https://github.com/python/cpython/commit/70dc00946938027d5a79bcb7b65038319040144e
commit: 70dc00946938027d5a79bcb7b65038319040144e
branch: main
author: Gregory P. Smith <greg at krypto.org>
committer: gpshead <greg at krypto.org>
date: 2023-07-25T14:09:25-07:00
summary:

gh-106939: document ShareableList nul-strip quirk. (#107266)

* gh-106939: document ShareableList nul-strip quirk.
* Mention the `int` size constraint.

files:
M Doc/library/multiprocessing.shared_memory.rst

diff --git a/Doc/library/multiprocessing.shared_memory.rst b/Doc/library/multiprocessing.shared_memory.rst
index 76046b34610ab..f453e6403d932 100644
--- a/Doc/library/multiprocessing.shared_memory.rst
+++ b/Doc/library/multiprocessing.shared_memory.rst
@@ -255,16 +255,17 @@ shared memory blocks created using that manager are all released when the
 :keyword:`with` statement's code block finishes execution.
 
 
-.. class:: ShareableList(sequence=None, *, name=None)
+.. class:: ShareableList(sequence=None, \*, name=None)
 
    Provides a mutable list-like object where all values stored within are
    stored in a shared memory block.  This constrains storable values to
-   only the ``int``, ``float``, ``bool``, ``str`` (less than 10M bytes each),
-   ``bytes`` (less than 10M bytes each), and ``None`` built-in data types.
-   It also notably differs from the built-in ``list`` type in that these
-   lists can not change their overall length (i.e. no append, insert, etc.)
-   and do not support the dynamic creation of new :class:`ShareableList`
-   instances via slicing.
+   only the ``int`` (signed 64-bit), ``float``, ``bool``, ``str`` (less
+   than 10M bytes each when encoded as utf-8), ``bytes`` (less than 10M
+   bytes each), and ``None`` built-in data types.  It also notably
+   differs from the built-in ``list`` type in that these lists can not
+   change their overall length (i.e. no append, insert, etc.) and do not
+   support the dynamic creation of new :class:`ShareableList` instances
+   via slicing.
 
    *sequence* is used in populating a new ``ShareableList`` full of values.
    Set to ``None`` to instead attach to an already existing
@@ -275,6 +276,35 @@ shared memory blocks created using that manager are all released when the
    existing ``ShareableList``, specify its shared memory block's unique
    name while leaving ``sequence`` set to ``None``.
 
+   .. note::
+
+      A known issue exists for :class:`bytes` and :class:`str` values.
+      If they end with ``\x00`` nul bytes or characters, those 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`.
+
+   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:
+
+   .. doctest::
+
+       >>> from multiprocessing import shared_memory
+       >>> nul_bug_demo = shared_memory.ShareableList(['?\x00', b'\x03\x02\x01\x00\x00\x00'])
+       >>> nul_bug_demo[0]
+       '?'
+       >>> nul_bug_demo[1]
+       b'\x03\x02\x01'
+       >>> nul_bug_demo.shm.unlink()
+       >>> padded = shared_memory.ShareableList(['?\x00\x07', b'\x03\x02\x01\x00\x00\x00\x07'])
+       >>> padded[0][:-1]
+       '?\x00'
+       >>> padded[1][:-1]
+       b'\x03\x02\x01\x00\x00\x00'
+       >>> padded.shm.unlink()
+
    .. method:: count(value)
 
       Returns the number of occurrences of ``value``.



More information about the Python-checkins mailing list