From cc9cac11a4db35e3dca2bde078f6816876d8d68e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Fri, 22 Nov 2024 16:54:08 +0100 Subject: [PATCH] Avoid the multiprocessing forkserver method Python 3.14 changed the default multiprocessing method for POSIX (sans macOS) from fork to forkserver. This causes errors like: TypeError: cannot pickle 'select.epoll' object when serializing dict item '_poller' when serializing pyftpdlib.ioloop.Epoll state when serializing pyftpdlib.ioloop.Epoll object when serializing dict item 'ioloop' when serializing pyftpdlib.servers.MultiprocessFTPServer state when serializing pyftpdlib.servers.MultiprocessFTPServer object when serializing tuple item 0 when serializing method reconstructor arguments when serializing method object when serializing dict item '_target' when serializing multiprocessing.context.Process state when serializing multiprocessing.context.Process object See https://github.com/python/cpython/issues/125714 --- pyftpdlib/servers.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pyftpdlib/servers.py b/pyftpdlib/servers.py index 32c0db02..3dfc39c6 100644 --- a/pyftpdlib/servers.py +++ b/pyftpdlib/servers.py @@ -579,6 +579,13 @@ class MultiprocessFTPServer(_SpawnerBase): _lock = multiprocessing.Lock() _exit = multiprocessing.Event() + # Python 3.14 changed the non-macOS POSIX default to forkserver + # but the code in this module does not work with it + # 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 _start_task(self, *args, **kwargs): - return multiprocessing.Process(*args, **kwargs) + return self._mp_context.Process(*args, **kwargs)