From f72c7c6528291da00dabb26fad89d60dfbc2adc4 Mon Sep 17 00:00:00 2001 From: Alessandro Molina Date: Thu, 16 Apr 2020 23:42:52 +0200 Subject: [PATCH 1/4] bpo-40307: Preserve manager Client in multiprocessing managers --- Lib/multiprocessing/managers.py | 17 ++++++++++++----- Lib/test/_test_multiprocessing.py | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index 91bcf243e78e5b..cfb6be9a49048f 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -531,8 +531,7 @@ def connect(self): ''' Connect manager object to the server process ''' - Listener, Client = listener_client[self._serializer] - conn = Client(self._address, authkey=self._authkey) + conn = self._Client(self._address, authkey=self._authkey) dispatch(conn, None, 'dummy') self._state.value = State.STARTED @@ -786,8 +785,13 @@ def __init__(self, token, serializer, manager=None, self._token = token self._id = self._token.id self._manager = manager - self._serializer = serializer - self._Client = listener_client[serializer][1] + + if manager is not None: + self._serializer = manager._serializer + self._Client = manager._Client + else: + self._serializer = serializer + self._Client = listener_client[serializer][1] # Should be set to True only when a proxy object is being created # on the manager server; primary use case: nested proxy objects. @@ -989,7 +993,10 @@ def AutoProxy(token, serializer, manager=None, authkey=None, ''' Return an auto-proxy for `token` ''' - _Client = listener_client[serializer][1] + if manager is not None: + _Client = manager._Client + else: + _Client = listener_client[serializer][1] if exposed is None: conn = _Client(token.address, authkey=authkey) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index cc07062eee6f98..29708254608a50 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -3517,6 +3517,30 @@ def test_remote(self): # Make queue finalizer run before the server is stopped del queue + def test_client_propagation(self): + authkey = os.urandom(32) + + manager = QueueManager( + address=(socket_helper.HOST, 0), authkey=authkey, serializer=SERIALIZER, + shutdown_timeout=SHUTDOWN_TIMEOUT) + manager.start() + self.addCleanup(manager.shutdown) + + manager2 = QueueManager2( + address=manager.address, authkey=authkey, serializer=SERIALIZER, + shutdown_timeout=SHUTDOWN_TIMEOUT) + + def MyXmlClient(*args, **kwargs): + return manager._Client(*args, **kwargs) + + manager2._Client = MyXmlClient + manager2.connect() + queue = manager2.get_queue() + + self.assertIsNot(queue._Client, manager._Client) + self.assertIs(queue._Client, manager2._Client) + + del queue @hashlib_helper.requires_hashdigest('sha256') class _TestManagerRestart(BaseTestCase): From bd9db86357a4133e23b06409a2f9c80a82b20641 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2020 10:40:55 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2020-04-20-10-40-54.bpo-40307.b4YXXY.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2020-04-20-10-40-54.bpo-40307.b4YXXY.rst diff --git a/Misc/NEWS.d/next/Library/2020-04-20-10-40-54.bpo-40307.b4YXXY.rst b/Misc/NEWS.d/next/Library/2020-04-20-10-40-54.bpo-40307.b4YXXY.rst new file mode 100644 index 00000000000000..1e7f6fffe615f5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-04-20-10-40-54.bpo-40307.b4YXXY.rst @@ -0,0 +1 @@ +``multiprocessing.Manager`` and its proxies, are going to use the client picked at the time the manager was created to guarantee consistent behaviour across the while manager life span. \ No newline at end of file From ed43e0bdd5ddf9051e14e7e4734aebe2d47f5936 Mon Sep 17 00:00:00 2001 From: Alessandro Molina Date: Mon, 20 Apr 2020 15:46:32 +0200 Subject: [PATCH 3/4] Update Misc/NEWS.d/next/Library/2020-04-20-10-40-54.bpo-40307.b4YXXY.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Rémi Lapeyre --- .../next/Library/2020-04-20-10-40-54.bpo-40307.b4YXXY.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2020-04-20-10-40-54.bpo-40307.b4YXXY.rst b/Misc/NEWS.d/next/Library/2020-04-20-10-40-54.bpo-40307.b4YXXY.rst index 1e7f6fffe615f5..a68f9434d03273 100644 --- a/Misc/NEWS.d/next/Library/2020-04-20-10-40-54.bpo-40307.b4YXXY.rst +++ b/Misc/NEWS.d/next/Library/2020-04-20-10-40-54.bpo-40307.b4YXXY.rst @@ -1 +1 @@ -``multiprocessing.Manager`` and its proxies, are going to use the client picked at the time the manager was created to guarantee consistent behaviour across the while manager life span. \ No newline at end of file +:class:`multiprocessing.Manager` and its proxies now uses the client picked at the time the manager was created to guarantee consistent behaviour across the whole manager life span. From dc3b8930187043928894bbbb8e6aa91ab7273185 Mon Sep 17 00:00:00 2001 From: Alessandro Molina Date: Fri, 27 Feb 2026 18:38:17 +0100 Subject: [PATCH 4/4] adapt other tests pattern and ignore the warning --- Lib/test/_test_multiprocessing.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 29708254608a50..2f39f5b5ac3846 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -3517,6 +3517,8 @@ def test_remote(self): # Make queue finalizer run before the server is stopped del queue + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() + @support.skip_if_sanitizer('TSan: leaks threads', thread=True) def test_client_propagation(self): authkey = os.urandom(32)