bpo-35813: Added shared_memory submodule of multiprocessing.#11664
bpo-35813: Added shared_memory submodule of multiprocessing.#11664applio merged 8 commits intopython:masterfrom
Conversation
|
|
||
| def __init__(self, name, flags=None, mode=None, size=None, read_only=False): | ||
| if name is None: | ||
| name = f'wnsm_{os.getpid()}_{random.randrange(100000)}' |
There was a problem hiding this comment.
random.randrange(100000)
Why use a random number here?
There was a problem hiding this comment.
If the user does not supply a name for the shared memory segment, an attempt is made to create a hopefully unique name. There are system-imposed constraints on the length of the name used and (I believe) the use of only ascii characters in the name but the use of a number here is not a requirement. Are you thinking about suggesting a mixture of letters and numbers?
An accidental collision with an existing shared memory segment's name would likely result in unintended/undesirable behavior.
There was a problem hiding this comment.
Wouldn't using a UUID give better uniqueness here, or just using itertools.count() instead of a random renumber to number memory segments? The latter avoids conflicts in a single process, although there still might be conflicts between processes when old segments aren't cleaned up properly.
There was a problem hiding this comment.
Replaced by Neil's patch with a stronger solution in GH-11816.
|
@applio: Please replace |
|
ronaldoussoren
left a comment
There was a problem hiding this comment.
I haven't reviewed most of the Python code, due to lack of documentation it is unclear what the intended behaviour of of the code is.
|
|
||
| def __init__(self, name, flags=None, mode=None, size=None, read_only=False): | ||
| if name is None: | ||
| name = f'wnsm_{os.getpid()}_{random.randrange(100000)}' |
There was a problem hiding this comment.
Wouldn't using a UUID give better uniqueness here, or just using itertools.count() instead of a random renumber to number memory segments? The latter avoids conflicts in a single process, although there still might be conflicts between processes when old segments aren't cleaned up properly.
| pass | ||
|
|
||
|
|
||
| class PosixSharedMemory(_PosixSharedMemory): |
There was a problem hiding this comment.
Why is this class defined unconditionally when it relies on functionality from an optional C extension. I'd leave the class out entirely when running on platform that doesn't support the C extension because that makes it clearer that functionality is not present.
| self.close_fd() | ||
|
|
||
|
|
||
| class SharedMemory: |
There was a problem hiding this comment.
I personally don't like this pattern. This is basically a function call, and could also just be an alias. Something like:
if os.name == 'nt':
SharedMemory = WindowsSharedMemory
else:
SharedMemory = PosixSharedMemory
| ) | ||
| return f"{self.__class__.__name__}({', '.join(formatted_pairs)})" | ||
|
|
||
| #def __getstate__(self): |
There was a problem hiding this comment.
This is commented-out code and should be removed.
| packing format for any storable value must require no more than 8 | ||
| characters to describe its format.""" | ||
|
|
||
| # TODO: Adjust for discovered word size of machine. |
There was a problem hiding this comment.
Please actually adjust for different word sizes, if needed (another option is to require that the size of the C double is 8 bytes and that a 64-bit integer type is used for integers).
There was a problem hiding this comment.
Comment was moot and now removed in GH-11816.
| PyObject *module; | ||
| PyObject *module_dict; | ||
|
|
||
| // I call this in case I'm asked to create any random names. |
There was a problem hiding this comment.
This changes process global state. Please remove.
Furthermore creating random names in C code isn't needed anyway (see one of the earlier comments)
| PyModule_AddObject(module, "_PosixSharedMemory", (PyObject *)&SharedMemoryType); | ||
|
|
||
|
|
||
| PyModule_AddStringConstant(module, "__copyright__", "Copyright 2012 Philip Semanchuk, 2018-2019 Davin Potts"); |
There was a problem hiding this comment.
The only other files with a copyright attribute are parser, optparse and platform. I'd prefer to avoid adding new copyright attributes to stdlib modules.
| PyModule_AddIntConstant(module, "O_EXCL", O_EXCL); | ||
| PyModule_AddIntConstant(module, "O_CREX", O_CREAT | O_EXCL); | ||
| PyModule_AddIntConstant(module, "O_TRUNC", O_TRUNC); | ||
|
|
There was a problem hiding this comment.
These values are already attributes of the os module, don't add them to this module as well.
| else | ||
| PyDict_SetItemString(module_dict, "Error", pBaseException); | ||
|
|
||
| if (!(pPermissionsException = PyErr_NewException("_posixshmem.PermissionsError", pBaseException, NULL))) |
There was a problem hiding this comment.
Why not use PermissionsError instead of a specific error?
There was a problem hiding this comment.
+1 to using PermissionsError. I used a custom error in the original code for Python 2.x support.
| else | ||
| PyDict_SetItemString(module_dict, "PermissionsError", pPermissionsException); | ||
|
|
||
| if (!(pExistentialException = PyErr_NewException("_posixshmem.ExistentialError", pBaseException, NULL))) |
There was a problem hiding this comment.
Why not use FileNotFoundError instead of a specific exception?
| assert hasattr(self, "_proxied_type") | ||
| try: | ||
| existing_type.__init__(self, *args, **kwargs) | ||
| except: |
There was a problem hiding this comment.
bare except clause should be avoided (use except Exception: instead)
There was a problem hiding this comment.
Agreed! I have changed this in a097dbb as part of PR-11816.
Tests and docs are still absent. Some cleanup remains to be done in the code as well but all appears to be functional and stable across platforms since the sprint in September 2018.
https://bugs.python.org/issue35813