Сценарий использования довольно прост:
- У меня есть объект (представленный как Obj< /code>), который проверен;
- Obj взаимодействует с внешним сервером;
- В целях тестирования внешний сервер имитируется с помощью multiprocessing.Process();
- Obj использует ProcessPoolExecutor для выполнения некоторых операций, связанных с процессором;
import concurrent.futures
import http.server
import multiprocessing
import pytest
import pytest_asyncio
# This does not work, as mock_server is not pickable...
# multiprocessing.set_start_method("spawn")
def hello_world():
print("Hello, World!")
class Obj():
def __init__(self):
self.pool = concurrent.futures.ProcessPoolExecutor(max_workers=1)
asyncio.get_running_loop().run_in_executor(self.pool, hello_world)
@pytest_asyncio.fixture
async def obj_to_test():
return Obj()
@pytest.fixture
def mock_server(tmpdir):
def server(path, host, port):
os.chdir(path)
httpd = http.server.HTTPServer(
(host, port),
http.server.SimpleHTTPRequestHandler
)
httpd.serve_forever()
process = multiprocessing.Process(target=server, args=(".", "127.0.0.1", 9999))
process.start()
yield process
process.terminate()
process.join()
def test_something(obj_to_test, mock_server):
# normally obj_to_test will interact here with mock_server
pass
Моя среда:
платформа Linux – Python 3.12.3, pytest-8.2.0, pluggy-1.5.0
плагины: asyncio-0.23.6
Я использую установку Python из этого образа Docker: python:3.12-slim@sha256:2be8daddbb82756f7d1f2c7ece706aadcb284bf6ab6d769ea695cc3ed6016743
pip install pytest==8.2.0 pytest-asyncio==0.23.6
После вышеизложенного я получаю следующее предупреждение, которое хочу исправить:
/usr/local/ lib/python3.12/multiprocessing/popen_fork.py:66: DeprecationWarning: этот процесс (pid=523) является многопоточным, использование fork() может привести к взаимоблокировкам в дочернем элементе.
< /blockquote>
Использование multiprocessing.set_start_method("spawn") не помогает.
Мне удалось воспроизвести DeprecationWarning также вне среды pytest:
import concurrent.futures
import multiprocessing
import time
pool = concurrent.futures.ProcessPoolExecutor(max_workers=1)
job = pool.submit(lambda: time.sleep(5))
process = multiprocessing.Process(target=lambda: None_)
process.start()
process.terminate()
и его запуск:
PYTHONWARNINGS=default python3 t5.py
/usr/local/lib/python3.12/multiprocessing/popen_fork.py:66: DeprecationWarning: This process (pid=1024) is multi-threaded, use of fork() may lead to deadlocks in the child.
self.pid = os.fork()
Подробнее здесь: https://stackoverflow.com/questions/785 ... sing-proce