@@ -3617,14 +3617,11 @@ def test_copy(self):
36173617 self .assertEqual (bar .z , 2 ** 33 )
36183618
36193619
3620+ @unittest .skipUnless (HAS_SHMEM , "requires multiprocessing.shared_memory" )
36203621class _TestSharedMemory (BaseTestCase ):
36213622
36223623 ALLOWED_TYPES = ('processes' ,)
36233624
3624- def setUp (self ):
3625- if not HAS_SHMEM :
3626- self .skipTest ("requires multiprocessing.shared_memory" )
3627-
36283625 @staticmethod
36293626 def _attach_existing_shmem_then_write (shmem_name , binary_data ):
36303627 local_sms = shared_memory .SharedMemory (shmem_name )
@@ -3637,106 +3634,100 @@ def test_shared_memory_basics(self):
36373634 flags = shared_memory .O_CREX ,
36383635 size = 512
36393636 )
3640- try :
3641- # Verify attributes are readable.
3642- self .assertEqual (sms .name , 'test01_tsmb' )
3643- self .assertGreaterEqual (sms .size , 512 )
3644- self .assertGreaterEqual (len (sms .buf ), sms .size )
3645- self .assertEqual (sms .mode , 0o600 )
3646-
3647- # Modify contents of shared memory segment through memoryview.
3648- sms .buf [0 ] = 42
3649- self .assertEqual (sms .buf [0 ], 42 )
3650-
3651- # Attach to existing shared memory segment.
3652- also_sms = shared_memory .SharedMemory ('test01_tsmb' )
3653- self .assertEqual (also_sms .buf [0 ], 42 )
3654- also_sms .close ()
3655-
3656- if isinstance (sms , shared_memory .PosixSharedMemory ):
3657- # Posix Shared Memory can only be unlinked once. Here we
3658- # test an implementation detail that is not observed across
3659- # all supported platforms (since WindowsNamedSharedMemory
3660- # manages unlinking on its own and unlink() does nothing).
3661- # True release of shared memory segment does not necessarily
3662- # happen until process exits, depending on the OS platform.
3663- with self .assertRaises (shared_memory .ExistentialError ):
3664- sms_uno = shared_memory .SharedMemory (
3665- 'test01_dblunlink' ,
3666- flags = shared_memory .O_CREX ,
3667- size = 5000
3668- )
3669-
3670- try :
3671- self .assertGreaterEqual (sms_uno .size , 5000 )
3637+ self .addCleanup (sms .unlink )
3638+
3639+ # Verify attributes are readable.
3640+ self .assertEqual (sms .name , 'test01_tsmb' )
3641+ self .assertGreaterEqual (sms .size , 512 )
3642+ self .assertGreaterEqual (len (sms .buf ), sms .size )
3643+ self .assertEqual (sms .mode , 0o600 )
3644+
3645+ # Modify contents of shared memory segment through memoryview.
3646+ sms .buf [0 ] = 42
3647+ self .assertEqual (sms .buf [0 ], 42 )
3648+
3649+ # Attach to existing shared memory segment.
3650+ also_sms = shared_memory .SharedMemory ('test01_tsmb' )
3651+ self .assertEqual (also_sms .buf [0 ], 42 )
3652+ also_sms .close ()
3653+
3654+ if isinstance (sms , shared_memory .PosixSharedMemory ):
3655+ # Posix Shared Memory can only be unlinked once. Here we
3656+ # test an implementation detail that is not observed across
3657+ # all supported platforms (since WindowsNamedSharedMemory
3658+ # manages unlinking on its own and unlink() does nothing).
3659+ # True release of shared memory segment does not necessarily
3660+ # happen until process exits, depending on the OS platform.
3661+ with self .assertRaises (shared_memory .ExistentialError ):
3662+ sms_uno = shared_memory .SharedMemory (
3663+ 'test01_dblunlink' ,
3664+ flags = shared_memory .O_CREX ,
3665+ size = 5000
3666+ )
36723667
3673- sms_duo = shared_memory .SharedMemory ('test01_dblunlink' )
3674- sms_duo .unlink () # First shm_unlink() call.
3675- sms_duo .close ()
3676- sms_uno .close ()
3668+ try :
3669+ self .assertGreaterEqual (sms_uno .size , 5000 )
36773670
3678- finally :
3679- sms_uno .unlink () # A second shm_unlink() call is bad.
3671+ sms_duo = shared_memory .SharedMemory ('test01_dblunlink' )
3672+ sms_duo .unlink () # First shm_unlink() call.
3673+ sms_duo .close ()
3674+ sms_uno .close ()
36803675
3681- # Enforcement of `mode` and `read_only` is OS platform dependent
3682- # and as such will not be tested here .
3676+ finally :
3677+ sms_uno . unlink () # A second shm_unlink() call is bad .
36833678
3684- with self .assertRaises (shared_memory .ExistentialError ):
3685- # Attempting to create a new shared memory segment with a
3686- # name that is already in use triggers an exception.
3687- there_can_only_be_one_sms = shared_memory .SharedMemory (
3688- 'test01_tsmb' ,
3689- flags = shared_memory .O_CREX ,
3690- size = 512
3691- )
3679+ # Enforcement of `mode` and `read_only` is OS platform dependent
3680+ # and as such will not be tested here.
36923681
3693- # Requesting creation of a shared memory segment with the option
3694- # to attach to an existing segment, if that name is currently in
3695- # use, should not trigger an exception.
3696- # Note: Using a smaller size could possibly cause truncation of
3697- # the existing segment but is OS platform dependent. In the
3698- # case of MacOS/darwin, requesting a smaller size is disallowed.
3699- ok_if_exists_sms = shared_memory .SharedMemory (
3682+ with self .assertRaises (shared_memory .ExistentialError ):
3683+ # Attempting to create a new shared memory segment with a
3684+ # name that is already in use triggers an exception.
3685+ there_can_only_be_one_sms = shared_memory .SharedMemory (
37003686 'test01_tsmb' ,
3701- flags = shared_memory .O_CREAT ,
3702- size = sms . size if sys . platform != 'darwin' else 0
3687+ flags = shared_memory .O_CREX ,
3688+ size = 512
37033689 )
3704- self .assertEqual (ok_if_exists_sms .size , sms .size )
3705- ok_if_exists_sms .close ()
37063690
3707- # Attempting to attach to an existing shared memory segment when
3708- # no segment exists with the supplied name triggers an exception.
3709- with self .assertRaises (shared_memory .ExistentialError ):
3710- nonexisting_sms = shared_memory .SharedMemory ('test01_notthere' )
3711- nonexisting_sms .unlink () # Error should occur on prior line.
3691+ # Requesting creation of a shared memory segment with the option
3692+ # to attach to an existing segment, if that name is currently in
3693+ # use, should not trigger an exception.
3694+ # Note: Using a smaller size could possibly cause truncation of
3695+ # the existing segment but is OS platform dependent. In the
3696+ # case of MacOS/darwin, requesting a smaller size is disallowed.
3697+ ok_if_exists_sms = shared_memory .SharedMemory (
3698+ 'test01_tsmb' ,
3699+ flags = shared_memory .O_CREAT ,
3700+ size = sms .size if sys .platform != 'darwin' else 0
3701+ )
3702+ self .assertEqual (ok_if_exists_sms .size , sms .size )
3703+ ok_if_exists_sms .close ()
37123704
3713- sms .close ()
3705+ # Attempting to attach to an existing shared memory segment when
3706+ # no segment exists with the supplied name triggers an exception.
3707+ with self .assertRaises (shared_memory .ExistentialError ):
3708+ nonexisting_sms = shared_memory .SharedMemory ('test01_notthere' )
3709+ nonexisting_sms .unlink () # Error should occur on prior line.
37143710
3715- finally :
3716- # Prevent test failures from leading to a dangling segment.
3717- sms .unlink ()
3711+ sms .close ()
37183712
37193713 def test_shared_memory_across_processes (self ):
37203714 sms = shared_memory .SharedMemory (
37213715 'test02_tsmap' ,
37223716 flags = shared_memory .O_CREX ,
37233717 size = 512
37243718 )
3719+ self .addCleanup (sms .unlink )
37253720
3726- try :
3727- p = self .Process (
3728- target = self ._attach_existing_shmem_then_write ,
3729- args = (sms .name , b'howdy' )
3730- )
3731- p .daemon = True
3732- p .start ()
3733- p .join ()
3734- self .assertEqual (bytes (sms .buf [:5 ]), b'howdy' )
3735-
3736- sms .close ()
3721+ p = self .Process (
3722+ target = self ._attach_existing_shmem_then_write ,
3723+ args = (sms .name , b'howdy' )
3724+ )
3725+ p .daemon = True
3726+ p .start ()
3727+ p .join ()
3728+ self .assertEqual (bytes (sms .buf [:5 ]), b'howdy' )
37373729
3738- finally :
3739- sms .unlink ()
3730+ sms .close ()
37403731
37413732 def test_shared_memory_SharedMemoryManager_basics (self ):
37423733 smm1 = shared_memory .SharedMemoryManager ()
@@ -3774,75 +3765,72 @@ def test_shared_memory_ShareableList_basics(self):
37743765 sl = shared_memory .ShareableList (
37753766 ['howdy' , b'HoWdY' , - 273.154 , 100 , None , True , 42 ]
37763767 )
3768+ self .addCleanup (sl .shm .unlink )
37773769
3778- try :
3779- # Verify attributes are readable.
3780- self .assertEqual (sl .format , '8s8sdqxxxxxx?xxxxxxxx?q' )
3781-
3782- # Exercise len().
3783- self .assertEqual (len (sl ), 7 )
3784-
3785- # Exercise index().
3786- with warnings .catch_warnings ():
3787- # Suppress BytesWarning when comparing against b'HoWdY'.
3788- warnings .simplefilter ('ignore' )
3789- with self .assertRaises (ValueError ):
3790- sl .index ('100' )
3791- self .assertEqual (sl .index (100 ), 3 )
3792-
3793- # Exercise retrieving individual values.
3794- self .assertEqual (sl [0 ], 'howdy' )
3795- self .assertEqual (sl [- 2 ], True )
3796-
3797- # Exercise iterability.
3798- self .assertEqual (
3799- tuple (sl ),
3800- ('howdy' , b'HoWdY' , - 273.154 , 100 , None , True , 42 )
3801- )
3770+ # Verify attributes are readable.
3771+ self .assertEqual (sl .format , '8s8sdqxxxxxx?xxxxxxxx?q' )
38023772
3803- # Exercise modifying individual values.
3804- sl [3 ] = 42
3805- self .assertEqual (sl [3 ], 42 )
3806- sl [4 ] = 'some' # Change type at a given position.
3807- self .assertEqual (sl [4 ], 'some' )
3808- self .assertEqual (sl .format , '8s8sdq8sxxxxxxx?q' )
3773+ # Exercise len().
3774+ self .assertEqual (len (sl ), 7 )
3775+
3776+ # Exercise index().
3777+ with warnings .catch_warnings ():
3778+ # Suppress BytesWarning when comparing against b'HoWdY'.
3779+ warnings .simplefilter ('ignore' )
38093780 with self .assertRaises (ValueError ):
3810- sl [4 ] = 'far too many' # Exceeds available storage.
3811- self .assertEqual (sl [4 ], 'some' )
3812-
3813- # Exercise count().
3814- with warnings .catch_warnings ():
3815- # Suppress BytesWarning when comparing against b'HoWdY'.
3816- warnings .simplefilter ('ignore' )
3817- self .assertEqual (sl .count (42 ), 2 )
3818- self .assertEqual (sl .count (b'HoWdY' ), 1 )
3819- self .assertEqual (sl .count (b'adios' ), 0 )
3820-
3821- # Exercise creating a duplicate.
3822- sl_copy = sl .copy (name = 'test03_duplicate' )
3823- try :
3824- self .assertNotEqual (sl .shm .name , sl_copy .shm .name )
3825- self .assertEqual ('test03_duplicate' , sl_copy .shm .name )
3826- self .assertEqual (list (sl ), list (sl_copy ))
3827- self .assertEqual (sl .format , sl_copy .format )
3828- sl_copy [- 1 ] = 77
3829- self .assertEqual (sl_copy [- 1 ], 77 )
3830- self .assertNotEqual (sl [- 1 ], 77 )
3831- sl_copy .shm .close ()
3832- finally :
3833- sl_copy .shm .unlink ()
3781+ sl .index ('100' )
3782+ self .assertEqual (sl .index (100 ), 3 )
3783+
3784+ # Exercise retrieving individual values.
3785+ self .assertEqual (sl [0 ], 'howdy' )
3786+ self .assertEqual (sl [- 2 ], True )
38343787
3835- # Obtain a second handle on the same ShareableList.
3836- sl_tethered = shared_memory .ShareableList (name = sl .shm .name )
3837- self .assertEqual (sl .shm .name , sl_tethered .shm .name )
3838- sl_tethered [- 1 ] = 880
3839- self .assertEqual (sl [- 1 ], 880 )
3840- sl_tethered .shm .close ()
3788+ # Exercise iterability.
3789+ self .assertEqual (
3790+ tuple (sl ),
3791+ ('howdy' , b'HoWdY' , - 273.154 , 100 , None , True , 42 )
3792+ )
38413793
3794+ # Exercise modifying individual values.
3795+ sl [3 ] = 42
3796+ self .assertEqual (sl [3 ], 42 )
3797+ sl [4 ] = 'some' # Change type at a given position.
3798+ self .assertEqual (sl [4 ], 'some' )
3799+ self .assertEqual (sl .format , '8s8sdq8sxxxxxxx?q' )
3800+ with self .assertRaises (ValueError ):
3801+ sl [4 ] = 'far too many' # Exceeds available storage.
3802+ self .assertEqual (sl [4 ], 'some' )
3803+
3804+ # Exercise count().
3805+ with warnings .catch_warnings ():
3806+ # Suppress BytesWarning when comparing against b'HoWdY'.
3807+ warnings .simplefilter ('ignore' )
3808+ self .assertEqual (sl .count (42 ), 2 )
3809+ self .assertEqual (sl .count (b'HoWdY' ), 1 )
3810+ self .assertEqual (sl .count (b'adios' ), 0 )
3811+
3812+ # Exercise creating a duplicate.
3813+ sl_copy = sl .copy (name = 'test03_duplicate' )
3814+ try :
3815+ self .assertNotEqual (sl .shm .name , sl_copy .shm .name )
3816+ self .assertEqual ('test03_duplicate' , sl_copy .shm .name )
3817+ self .assertEqual (list (sl ), list (sl_copy ))
3818+ self .assertEqual (sl .format , sl_copy .format )
3819+ sl_copy [- 1 ] = 77
3820+ self .assertEqual (sl_copy [- 1 ], 77 )
3821+ self .assertNotEqual (sl [- 1 ], 77 )
3822+ sl_copy .shm .close ()
38423823 finally :
3843- # Prevent test failures from leading to a dangling segment.
3844- sl .shm .unlink ()
3845- sl .shm .close ()
3824+ sl_copy .shm .unlink ()
3825+
3826+ # Obtain a second handle on the same ShareableList.
3827+ sl_tethered = shared_memory .ShareableList (name = sl .shm .name )
3828+ self .assertEqual (sl .shm .name , sl_tethered .shm .name )
3829+ sl_tethered [- 1 ] = 880
3830+ self .assertEqual (sl [- 1 ], 880 )
3831+ sl_tethered .shm .close ()
3832+
3833+ sl .shm .close ()
38463834
38473835 # Exercise creating an empty ShareableList.
38483836 empty_sl = shared_memory .ShareableList ()
0 commit comments