From 1af635b53200fc14966a4aba780bee7e1d481da2 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Mon, 16 Feb 2026 23:02:34 +0100 Subject: [PATCH] Resolve bind sockets in _serve instead of startup Move the bind socket resolution from startup() to _serve() so startup doesn't need to know about config.bind. The resolved sockets flow into both startup and shutdown through the existing parameter. --- uvicorn/server.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/uvicorn/server.py b/uvicorn/server.py index 7236b71b..d8efde1f 100644 --- a/uvicorn/server.py +++ b/uvicorn/server.py @@ -77,6 +77,9 @@ class Server: if not config.loaded: config.load() + if sockets is None and config.bind is not None: + sockets = config.bind_sockets() + self.lifespan = config.lifespan_class(config) message = "Started server process [%d]" @@ -101,9 +104,6 @@ class Server: config = self.config - if sockets is None and config.bind is not None: - sockets = config.bind_sockets() - def create_protocol( _loop: asyncio.AbstractEventLoop | None = None, ) -> asyncio.Protocol: @@ -121,9 +121,7 @@ class Server: # Explicitly passed a list of open sockets. # We use this when the server is run from a Gunicorn worker. - def _share_socket( - sock: socket.SocketType, - ) -> socket.SocketType: # pragma py-not-win32 + def _share_socket(sock: socket.SocketType) -> socket.SocketType: # pragma py-not-win32 # Windows requires the socket be explicitly shared across # multiple workers (processes). from socket import fromshare # type: ignore[attr-defined]