Skip to content

Commit feba9b5

Browse files
test: Add tests for trailing null preservation and multi-byte UTF-8 in ShareableList
Add test_shared_memory_ShareableList_trailing_nulls covering gh-106939 (bytes/str values with trailing null bytes preserved correctly) and test_shared_memory_ShareableList_multibyte_utf8 covering gh-145261 (multi-byte UTF-8 strings stored and retrieved without corruption). Both tests include cross-process verification via name-based attachment.
1 parent e3b5fd3 commit feba9b5

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

Lib/test/_test_multiprocessing.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4899,6 +4899,58 @@ def test_shared_memory_ShareableList_pickling_dead_object(self):
48994899
with self.assertRaises(FileNotFoundError):
49004900
pickle.loads(serialized_sl)
49014901

4902+
def test_shared_memory_ShareableList_trailing_nulls(self):
4903+
# gh-106939: ShareableList should preserve trailing null bytes
4904+
# in bytes and str values.
4905+
sl = shared_memory.ShareableList([
4906+
b'\x03\x02\x01\x00\x00\x00',
4907+
'?\x00',
4908+
b'\x00\x00\x00',
4909+
b'',
4910+
b'no nulls',
4911+
])
4912+
self.addCleanup(sl.shm.unlink)
4913+
self.addCleanup(sl.shm.close)
4914+
4915+
self.assertEqual(sl[0], b'\x03\x02\x01\x00\x00\x00')
4916+
self.assertEqual(sl[1], '?\x00')
4917+
self.assertEqual(sl[2], b'\x00\x00\x00')
4918+
self.assertEqual(sl[3], b'')
4919+
self.assertEqual(sl[4], b'no nulls')
4920+
4921+
sl2 = shared_memory.ShareableList(name=sl.shm.name)
4922+
self.addCleanup(sl2.shm.close)
4923+
self.assertEqual(sl2[0], b'\x03\x02\x01\x00\x00\x00')
4924+
self.assertEqual(sl2[1], '?\x00')
4925+
self.assertEqual(sl2[2], b'\x00\x00\x00')
4926+
self.assertEqual(sl2[3], b'')
4927+
self.assertEqual(sl2[4], b'no nulls')
4928+
4929+
def test_shared_memory_ShareableList_multibyte_utf8(self):
4930+
# gh-145261: ShareableList should correctly handle multi-byte
4931+
# UTF-8 strings without corruption or spillage.
4932+
sl = shared_memory.ShareableList([
4933+
'ascii', # 1-byte per char (5 bytes)
4934+
'café', # 2-byte char: é (5 bytes)
4935+
'中文测试', # 3-byte per char (12 bytes)
4936+
'𐀀𐀁', # 4-byte per char (8 bytes)
4937+
])
4938+
self.addCleanup(sl.shm.unlink)
4939+
self.addCleanup(sl.shm.close)
4940+
4941+
self.assertEqual(sl[0], 'ascii')
4942+
self.assertEqual(sl[1], 'café')
4943+
self.assertEqual(sl[2], '中文测试')
4944+
self.assertEqual(sl[3], '𐀀𐀁')
4945+
4946+
# Verify cross-process access via name-based attachment.
4947+
sl2 = shared_memory.ShareableList(name=sl.shm.name)
4948+
self.addCleanup(sl2.shm.close)
4949+
self.assertEqual(sl2[0], 'ascii')
4950+
self.assertEqual(sl2[1], 'café')
4951+
self.assertEqual(sl2[2], '中文测试')
4952+
self.assertEqual(sl2[3], '𐀀𐀁')
4953+
49024954
def test_shared_memory_cleaned_after_process_termination(self):
49034955
cmd = '''if 1:
49044956
import os, time, sys

0 commit comments

Comments
 (0)