From a8752032ef450053e75370d852064f39857d488f Mon Sep 17 00:00:00 2001 From: euri10 Date: Wed, 22 Jun 2022 10:04:44 +0200 Subject: [PATCH] Fix OSError: [WinError 87] The parameter is incorrect (#1454) * Fix OSError: [WinError 87] The parameter is incorrect * Added use_subprocess to be more generic * Black * Revert "Added use_subprocess to be more generic" This reverts commit d1b5f838 * Removed reload warning * Min diff, not sure where this came from * Min diff 2 * Redo use_subprocess --- tests/test_config.py | 19 +++++++++++++++++++ uvicorn/config.py | 6 +++++- uvicorn/loops/asyncio.py | 5 ++--- uvicorn/loops/auto.py | 6 +++--- uvicorn/loops/uvloop.py | 2 +- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index 39fd747428..a2215aa5a3 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 ce24154921..3e772ccab7 100644 --- a/uvicorn/config.py +++ b/uvicorn/config.py @@ -377,6 +377,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") @@ -507,7 +511,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 9a9ed64951..867545f2af 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 ff272c1125..2285457bf1 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 119c9f28a4..0e2fd1eb05 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())