Skip to content

BaseEventLoop.create_server overload doesn't allow passing host with port=None #16157

Description

@timabroad

The type stubs for BaseEventLoop.create_server (here) consist over two overloads:

# The first one specifies:
host: str | Sequence[str] | None = None,
port: int = ...,
sock: None = None,

# The second one specifies:
host: None = None,
port: None = None,
sock: socket = ...,

But the first of these causes a typing error if you pass None for the port (pyright playground), despite succeeding at runtime:

import asyncio

async def start():
    loop = asyncio.get_running_loop()

    await loop.create_server(asyncio.Protocol)
    await loop.create_server(asyncio.Protocol, 'localhost')
    await loop.create_server(asyncio.Protocol, 'localhost', 8080)
    await loop.create_server(asyncio.Protocol, 'localhost')
    await loop.create_server(asyncio.Protocol, 'localhost', None) # Argument of type "None" cannot be assigned to parameter "port" of type "int" in function "create_server".

This is documented as being valid as far back as Python 3.9. For some reason the 3.8 and earlier docs don't provide any details for the port parameter, though I'm not aware of any changes.

Activity

  1. srittau commented on Aug 7, 2026

    @srittau
    Collaborator

    This doesn't make sense indeed. The reason for the two overloads is probably to ensure that exactly one of host/port and sock are specified. We just need a third overload (..., host: str | Sequence[str], port: int | None = None, ..., sock: None = None, ...) and the need to remove the default to port in the existing overload.

    This is also one of the rare cases where having tests seems useful.

    PR welcome!

  2. added
    help wantedAn actionable problem of low to medium complexity where a PR would be very welcome
    on Aug 7, 2026
  3. nightcityblade commented on Aug 9, 2026

    @nightcityblade
    Contributor

    Hi, I'd like to work on this. I'll submit a PR shortly.

  4. nightcityblade commented on Aug 9, 2026

    @nightcityblade
    Contributor

    I took a closer look at the three version-specific overload sets and won't be able to complete this within my current small-change window. Releasing it for someone else—sorry for the noise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedAn actionable problem of low to medium complexity where a PR would be very welcomestubs: false positiveType checkers report false errorstopic: asyncioAsyncio-related issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions