Issue 3206: Multiprocessing Array and sharedctypes.Array error in docs/implementation (original) (raw)
multiprocessing.sharedctypes.Array and multiprocessing.sharedctypes.Value if used according to documentation fail with AssertionError.
Python 3.0b1+ (py3k:64518, Jun 25 2008, 12:52:38) [GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2 Type "help", "copyright", "credits" or "license" for more information.
from multiprocessing import sharedctypes sharedctypes.Array('i', 1, lock=True) Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.0/multiprocessing/sharedctypes.py", line 88, in Array assert hasattr(lock, 'acquire') AssertionError sharedctypes.Array('i', 1, lock=False) Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.0/multiprocessing/sharedctypes.py", line 88, in Array assert hasattr(lock, 'acquire') AssertionError sharedctypes.Array('i', 1, lock=None) <SynchronizedArray wrapper for <multiprocessing.sharedctypes.c_long_Array_1 object at 0x83214f4>> Value('i', lock=True) Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.0/multiprocessing/init.py", line 246, in Value return Value(typecode_or_type, *args, **kwds) File "/usr/local/lib/python3.0/multiprocessing/sharedctypes.py", line 75, in Value assert hasattr(lock, 'acquire') AssertionError
The same goes for multiprocessing.Array and multiprocessing.Value.
Comparing code to documentation it's obvious that lock argument can be one of Lock, RLock or None objects (or any object with "acquire" attribute), but not True or False. Also, looking at the code it seems strange to me that 'lock' is a keyword-only argument. Why not use simple default argument "lock=None" for Array() function? Proposed patch tries to address these issues.
Note that if the error is in the documentation semantics, and not in the implementation, then the benchmark code in the documentation is also broken, and should be change to not use lock=True/False respectively...
I'm not sure if the patch here is good or rather lock=True/False should be the right API and the implementation should be changed along this lines:
diff --git a/Lib/multiprocessing/sharedctypes.py b/Lib/multiprocessing/sharedctypes.py index b94cd52..2f68e74 100644 --- a/Lib/multiprocessing/sharedctypes.py +++ b/Lib/multiprocessing/sharedctypes.py @@ -79,10 +79,11 @@ def Array(typecode_or_type, size_or_initializer, **kwds): if kwds: raise ValueError('unrecognized keyword argument(s): %s' % list(kwds.keys())) obj = RawArray(typecode_or_type, size_or_initializer)
- if lock is None:
- if lock is True: lock = RLock()
- assert hasattr(lock, 'acquire')
- return synchronized(obj, lock)
return synchronized(obj, lock)
- return obj
def copy(obj): new_obj = _new_value(type(obj))