Skip to content

Commit 0530a85

Browse files
ekanshulclaude
andcommitted
asyncio: allow port=None in create_server when a host is given
create_server passes port straight to getaddrinfo, which accepts None, so create_server(proto, "localhost", None) works at runtime but the stub rejected it because the non-sock overload declared port: int. Widen that parameter to int | None in the six create_server overloads (three version gates each in base_events.pyi and events.pyi) and add test cases covering the host/port/sock combinations. create_connection also has port: int = ..., but it is left alone here: its port is not optional in the same way. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent f8938c2 commit 0530a85

3 files changed

Lines changed: 36 additions & 6 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from __future__ import annotations
2+
3+
import asyncio
4+
import socket
5+
from typing_extensions import assert_type
6+
7+
8+
async def check_create_server(loop: asyncio.AbstractEventLoop, base_loop: asyncio.BaseEventLoop) -> None:
9+
# `port` is optional whenever a host is given: the runtime passes it straight
10+
# to getaddrinfo, which treats None as "any port".
11+
assert_type(await loop.create_server(asyncio.Protocol, "localhost"), asyncio.Server)
12+
assert_type(await loop.create_server(asyncio.Protocol, "localhost", 8080), asyncio.Server)
13+
assert_type(await loop.create_server(asyncio.Protocol, "localhost", None), asyncio.Server)
14+
assert_type(await loop.create_server(asyncio.Protocol, ["localhost", "127.0.0.1"], 8080), asyncio.Server)
15+
16+
# A port with no host binds every interface.
17+
assert_type(await loop.create_server(asyncio.Protocol, None, 8080), asyncio.Server)
18+
assert_type(await loop.create_server(asyncio.Protocol, port=8080), asyncio.Server)
19+
20+
assert_type(await base_loop.create_server(asyncio.Protocol, "localhost", None), asyncio.Server)
21+
assert_type(await base_loop.create_server(asyncio.Protocol, port=8080), asyncio.Server)
22+
23+
24+
async def check_create_server_sock(loop: asyncio.AbstractEventLoop, sock: socket.socket) -> None:
25+
assert_type(await loop.create_server(asyncio.Protocol, sock=sock), asyncio.Server)
26+
27+
# The runtime rejects host/port together with sock:
28+
# ValueError: host/port and sock can not be specified at the same time
29+
await loop.create_server(asyncio.Protocol, "localhost", sock=sock) # type: ignore
30+
await loop.create_server(asyncio.Protocol, None, 8080, sock=sock) # type: ignore

stdlib/asyncio/base_events.pyi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ class BaseEventLoop(AbstractEventLoop):
244244
self,
245245
protocol_factory: _ProtocolFactory,
246246
host: str | Sequence[str] | None = None,
247-
port: int = ...,
247+
port: int | None = None,
248248
*,
249249
family: int = 0,
250250
flags: int = 1,
@@ -283,7 +283,7 @@ class BaseEventLoop(AbstractEventLoop):
283283
self,
284284
protocol_factory: _ProtocolFactory,
285285
host: str | Sequence[str] | None = None,
286-
port: int = ...,
286+
port: int | None = None,
287287
*,
288288
family: int = AddressFamily.AF_UNSPEC,
289289
flags: int = AddressInfo.AI_PASSIVE,
@@ -320,7 +320,7 @@ class BaseEventLoop(AbstractEventLoop):
320320
self,
321321
protocol_factory: _ProtocolFactory,
322322
host: str | Sequence[str] | None = None,
323-
port: int = ...,
323+
port: int | None = None,
324324
*,
325325
family: int = AddressFamily.AF_UNSPEC,
326326
flags: int = AddressInfo.AI_PASSIVE,

stdlib/asyncio/events.pyi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ class AbstractEventLoop:
299299
self,
300300
protocol_factory: _ProtocolFactory,
301301
host: str | Sequence[str] | None = None,
302-
port: int = ...,
302+
port: int | None = None,
303303
*,
304304
family: int = AddressFamily.AF_UNSPEC,
305305
flags: int = AddressInfo.AI_PASSIVE,
@@ -340,7 +340,7 @@ class AbstractEventLoop:
340340
self,
341341
protocol_factory: _ProtocolFactory,
342342
host: str | Sequence[str] | None = None,
343-
port: int = ...,
343+
port: int | None = None,
344344
*,
345345
family: int = AddressFamily.AF_UNSPEC,
346346
flags: int = AddressInfo.AI_PASSIVE,
@@ -379,7 +379,7 @@ class AbstractEventLoop:
379379
self,
380380
protocol_factory: _ProtocolFactory,
381381
host: str | Sequence[str] | None = None,
382-
port: int = ...,
382+
port: int | None = None,
383383
*,
384384
family: int = AddressFamily.AF_UNSPEC,
385385
flags: int = AddressInfo.AI_PASSIVE,

0 commit comments

Comments
 (0)