Skip to content

Commit 9c8d18d

Browse files
Round up the allocated size instead of rejecting the exact fit
Allocating one extra alignment block for a value whose encoded size is a multiple of the alignment made a copy of the list wider than the original. Round the size up instead, so that it is the same for the same value, and keep allowing a value which fills the slot exactly: rejecting it broke setting an 8-byte string in a slot of an integer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 7abde77 commit 9c8d18d

3 files changed

Lines changed: 7 additions & 6 deletions

File tree

Lib/multiprocessing/shared_memory.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ def __init__(self, sequence=None, *, name=None):
319319
self._types_mapping[type(item)]
320320
if not isinstance(item, (str, bytes))
321321
else self._types_mapping[type(item)] % (
322-
self._alignment * (len(self._encode_value(item)) // self._alignment + 1),
322+
self._alignment * ((len(self._encode_value(item)) - 1) // self._alignment + 1),
323323
)
324324
for item in sequence
325325
]
@@ -471,7 +471,7 @@ def __setitem__(self, position, value):
471471
allocated_length = self._allocated_offsets[position + 1] - item_offset
472472

473473
encoded_value = self._encode_value(value)
474-
if len(encoded_value) >= allocated_length:
474+
if len(encoded_value) > allocated_length:
475475
raise ValueError("bytes/str item exceeds available storage")
476476
if current_format[-1] == "s":
477477
new_format = current_format

Lib/test/_test_multiprocessing.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5018,11 +5018,12 @@ def test_shared_memory_ShareableList_basics(self):
50185018
"exceeds available storage"):
50195019
sl[4] = 'far too many'
50205020
self.assertEqual(sl[4], 'some')
5021-
sl[0] = 'encodé'
5022-
self.assertEqual(sl[0], 'encodé') # no spillage
5021+
sl[0] = 'éncodé' # Exactly 8 bytes of UTF-8 data
5022+
self.assertEqual(sl[0], 'éncodé')
5023+
self.assertEqual(sl[1], b'HoWdY') # no spillage
50235024
with self.assertRaisesRegex(ValueError,
50245025
"exceeds available storage"):
5025-
sl[0] = 'encodés' # Exactly 8 bytes of UTF-8 data
5026+
sl[0] = 'éncodés' # Exactly 9 bytes of UTF-8 data
50265027
self.assertEqual(sl[1], b'HoWdY')
50275028
with self.assertRaisesRegex(ValueError,
50285029
"exceeds available storage"):
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Fix UnicodeDecodeError with multibyte utf8 characters in ShareableList.
1+
Fix UnicodeDecodeError with multibyte utf8 characters in ShareableList.

0 commit comments

Comments
 (0)