From 4f36a3345cdf3375d8251a62e42eeb0cea747daa Mon Sep 17 00:00:00 2001 From: Karolina Surma Date: Thu, 24 Apr 2025 09:56:24 +0200 Subject: [PATCH] Avoid the multiprocessing forkserver method The default method of creating new processes has been changed to forkserver. The test code spawns processes in a way that's not compatible with the change. Change the method back to fork on environments, where forkserver is the default. --- src/etcd/tests/integration/test_simple.py | 26 ++++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/etcd/tests/integration/test_simple.py b/src/etcd/tests/integration/test_simple.py index 631a14b..571dd65 100644 --- a/src/etcd/tests/integration/test_simple.py +++ b/src/etcd/tests/integration/test_simple.py @@ -244,6 +244,16 @@ def test_reconnet_fails(self): class TestWatch(EtcdIntegrationTest): + # On macOS and newly non-macOS POSIX systems (since Python 3.14), + # the default method has been changed to forkserver. + # The code in this test does not work with it, + # hence the explicit change to 'fork' + # See https://github.com/python/cpython/issues/125714 + if multiprocessing.get_start_method() == "forkserver": + _mp_context = multiprocessing.get_context(method="fork") + else: + _mp_context = multiprocessing.get_context() + def test_watch(self): """INTEGRATION: Receive a watch event from other process""" @@ -259,7 +269,7 @@ def watch_value(key, queue): c = etcd.Client(port=6001) queue.put(c.watch(key).value) - changer = multiprocessing.Process( + changer = self._mp_context.Process( target=change_value, args=( "/test-key", @@ -267,7 +277,7 @@ def watch_value(key, queue): ), ) - watcher = multiprocessing.Process(target=watch_value, args=("/test-key", queue)) + watcher = self._mp_context.Process(target=watch_value, args=("/test-key", queue)) watcher.start() time.sleep(1) @@ -301,7 +311,7 @@ def watch_value(key, index, queue): for i in range(0, 3): queue.put(c.watch(key, index=index + i).value) - proc = multiprocessing.Process( + proc = self._mp_context.Process( target=change_value, args=( "/test-key", @@ -309,7 +319,7 @@ def watch_value(key, index, queue): ), ) - watcher = multiprocessing.Process( + watcher = self._mp_context.Process( target=watch_value, args=("/test-key", original_index, queue) ) @@ -346,9 +356,9 @@ def watch_value(key, queue): event = next(c.eternal_watch(key)).value queue.put(event) - changer = multiprocessing.Process(target=change_value, args=("/test-key",)) + changer = self._mp_context.Process(target=change_value, args=("/test-key",)) - watcher = multiprocessing.Process(target=watch_value, args=("/test-key", queue)) + watcher = self._mp_context.Process(target=watch_value, args=("/test-key", queue)) watcher.start() changer.start() @@ -383,7 +393,7 @@ def watch_value(key, index, queue): for i in range(0, 3): queue.put(next(iterevents).value) - proc = multiprocessing.Process( + proc = self._mp_context.Process( target=change_value, args=( "/test-key", @@ -391,7 +401,7 @@ def watch_value(key, index, queue): ), ) - watcher = multiprocessing.Process( + watcher = self._mp_context.Process( target=watch_value, args=("/test-key", original_index, queue) )