diff --git a/tests/test_config.py b/tests/test_config.py index 39fd74742..a2215aa5a 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -544,3 +544,22 @@ def test_bind_fd_works_with_reload_or_workers(reload, workers): # pragma: py-wi assert sock.getsockname() == "" sock.close() fdsock.close() + + +@pytest.mark.parametrize( + "reload, workers, expected", + [ + (True, 1, True), + (False, 2, True), + (False, 1, False), + ], + ids=[ + "--reload=True --workers=1", + "--reload=False --workers=2", + "--reload=False --workers=1", + ], +) +def test_config_use_subprocess(reload, workers, expected): + config = Config(app=asgi_app, reload=reload, workers=workers) + config.load() + assert config.use_subprocess == expected diff --git a/uvicorn/config.py b/uvicorn/config.py index c96f16691..9fad8f9a1 100644 --- a/uvicorn/config.py +++ b/uvicorn/config.py @@ -373,6 +373,10 @@ def asgi_version(self) -> Literal["2.0", "3.0"]: def is_ssl(self) -> bool: return bool(self.ssl_keyfile or self.ssl_certfile) + @property + def use_subprocess(self) -> bool: + return bool(self.reload or self.workers > 1) + def configure_logging(self) -> None: logging.addLevelName(TRACE_LOG_LEVEL, "TRACE") @@ -503,7 +507,7 @@ def load(self) -> None: def setup_event_loop(self) -> None: loop_setup: Optional[Callable] = import_from_string(LOOP_SETUPS[self.loop]) if loop_setup is not None: - loop_setup(reload=self.reload) + loop_setup(use_subprocess=self.use_subprocess) def bind_socket(self) -> socket.socket: logger_args: List[Union[str, int]] diff --git a/uvicorn/loops/asyncio.py b/uvicorn/loops/asyncio.py index 9a9ed6495..867545f2a 100644 --- a/uvicorn/loops/asyncio.py +++ b/uvicorn/loops/asyncio.py @@ -5,7 +5,6 @@ logger = logging.getLogger("uvicorn.error") -def asyncio_setup(reload: bool = False) -> None: # pragma: no cover - if sys.version_info >= (3, 8) and sys.platform == "win32" and reload: - logger.warning("The --reload flag should not be used in production on Windows.") +def asyncio_setup(use_subprocess: bool = False) -> None: # pragma: no cover + if sys.version_info >= (3, 8) and sys.platform == "win32" and use_subprocess: asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) diff --git a/uvicorn/loops/auto.py b/uvicorn/loops/auto.py index ff272c112..2285457bf 100644 --- a/uvicorn/loops/auto.py +++ b/uvicorn/loops/auto.py @@ -1,11 +1,11 @@ -def auto_loop_setup(reload: bool = False) -> None: +def auto_loop_setup(use_subprocess: bool = False) -> None: try: import uvloop # noqa except ImportError: # pragma: no cover from uvicorn.loops.asyncio import asyncio_setup as loop_setup - loop_setup(reload=reload) + loop_setup(use_subprocess=use_subprocess) else: # pragma: no cover from uvicorn.loops.uvloop import uvloop_setup - uvloop_setup(reload=reload) + uvloop_setup(use_subprocess=use_subprocess) diff --git a/uvicorn/loops/uvloop.py b/uvicorn/loops/uvloop.py index 119c9f28a..0e2fd1eb0 100644 --- a/uvicorn/loops/uvloop.py +++ b/uvicorn/loops/uvloop.py @@ -3,5 +3,5 @@ import uvloop -def uvloop_setup(reload: bool = False) -> None: +def uvloop_setup(use_subprocess: bool = False) -> None: asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())