Index: Lib/multiprocessing/sharedctypes.py =================================================================== --- Lib/multiprocessing/sharedctypes.py (revision 67339) +++ Lib/multiprocessing/sharedctypes.py (working copy) @@ -69,9 +69,12 @@ if kwds: raise ValueError('unrecognized keyword argument(s): %s' % kwds.keys()) obj = RawValue(typecode_or_type, *args) - if lock is None: + if lock is False: + return obj + if lock in (True, None): lock = RLock() - assert hasattr(lock, 'acquire') + if not hasattr(lock, 'acquire'): + raise AttributeError("'%r' has no method 'acquire'" % lock) return synchronized(obj, lock) def Array(typecode_or_type, size_or_initializer, **kwds): @@ -82,9 +85,12 @@ if kwds: raise ValueError('unrecognized keyword argument(s): %s' % kwds.keys()) obj = RawArray(typecode_or_type, size_or_initializer) - if lock is None: + if lock is False: + return obj + if lock in (True, None): lock = RLock() - assert hasattr(lock, 'acquire') + if not hasattr(lock, 'acquire'): + raise AttributeError("'%r' has no method 'acquire'" % lock) return synchronized(obj, lock) def copy(obj): Index: Lib/test/test_multiprocessing.py =================================================================== --- Lib/test/test_multiprocessing.py (revision 67339) +++ Lib/test/test_multiprocessing.py (working copy) @@ -829,11 +829,17 @@ obj3 = val3.get_obj() self.assertEqual(lock, lock3) - arr4 = self.RawValue('i', 5) + arr4 = self.Value('i', 5, lock=False) self.assertFalse(hasattr(arr4, 'get_lock')) self.assertFalse(hasattr(arr4, 'get_obj')) + self.assertRaises(AttributeError, self.Value, 'i', 5, lock=None) + arr5 = self.RawValue('i', 5) + self.assertFalse(hasattr(arr5, 'get_lock')) + self.assertFalse(hasattr(arr5, 'get_obj')) + + class _TestArray(BaseTestCase): def f(self, seq): @@ -887,10 +893,17 @@ obj3 = arr3.get_obj() self.assertEqual(lock, lock3) - arr4 = self.RawArray('i', range(10)) + arr4 = self.Array('i', range(10), lock=False) self.assertFalse(hasattr(arr4, 'get_lock')) self.assertFalse(hasattr(arr4, 'get_obj')) + self.assertRaises(AttributeError, + self.Array, 'i', range(10), lock=None) + + arr5 = self.RawArray('i', range(10)) + self.assertFalse(hasattr(arr5, 'get_lock')) + self.assertFalse(hasattr(arr5, 'get_obj')) + # # # Index: Doc/library/multiprocessing.rst =================================================================== --- Doc/library/multiprocessing.rst (revision 67339) +++ Doc/library/multiprocessing.rst (working copy) @@ -835,7 +835,7 @@ It is possible to create shared objects using shared memory which can be inherited by child processes. -.. function:: Value(typecode_or_type[, *args, lock]]) +.. function:: Value(typecode_or_type, *args[, lock]) Return a :mod:`ctypes` object allocated from shared memory. By default the return value is actually a synchronized wrapper for the object. @@ -917,7 +917,7 @@ *typecode_or_type* determines the type of the returned object: it is either a ctypes type or a one character typecode of the kind used by the :mod:`array` - module. */*args* is passed on to the constructor for the type. + module. *\*args* is passed on to the constructor for the type. Note that setting and getting the value is potentially non-atomic -- use :func:`Value` instead to make sure that access is automatically synchronized @@ -927,7 +927,7 @@ attributes which allow one to use it to store and retrieve strings -- see documentation for :mod:`ctypes`. -.. function:: Array(typecode_or_type, size_or_initializer[, *args[, lock]]) +.. function:: Array(typecode_or_type, size_or_initializer, *args[, lock]) The same as :func:`RawArray` except that depending on the value of *lock* a process-safe synchronization wrapper may be returned instead of a raw ctypes