From 0d165cf053e2d640c71f73953fdb81de265478dd Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 24 Nov 2025 22:23:53 +0000 Subject: [PATCH 1/2] [channels] Make URLRouter.routes a Collection `list` is invariant, which made this type inconvenient in practice. Each of the routes is either a pattern or another router. --- stubs/channels/channels/routing.pyi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stubs/channels/channels/routing.pyi b/stubs/channels/channels/routing.pyi index d2a0655d43ce..2010a84935ff 100644 --- a/stubs/channels/channels/routing.pyi +++ b/stubs/channels/channels/routing.pyi @@ -1,3 +1,4 @@ +from collections.abc import Collection from typing import Any, type_check_only from asgiref.typing import ASGIReceiveCallable, ASGISendCallable, Scope @@ -19,9 +20,9 @@ class _ExtendedURLPattern(URLPattern): callback: _ASGIApplicationProtocol | URLRouter class URLRouter: - routes: list[_ExtendedURLPattern | URLRouter] + routes: Collection[_ExtendedURLPattern | URLRouter] - def __init__(self, routes: list[_ExtendedURLPattern | URLRouter]) -> None: ... + def __init__(self, routes: Collection[_ExtendedURLPattern | URLRouter]) -> None: ... async def __call__(self, scope: Scope, receive: ASGIReceiveCallable, send: ASGISendCallable) -> None: ... class ChannelNameRouter: From 79675e2f027b9bf2c516c6d3e5d90f5084d796dd Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 25 Nov 2025 10:05:56 +0000 Subject: [PATCH 2/2] [channels] Weaken a couple of other list parameter types --- stubs/channels/channels/utils.pyi | 5 +++-- stubs/channels/channels/worker.pyi | 10 ++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/stubs/channels/channels/utils.pyi b/stubs/channels/channels/utils.pyi index 0e0818abbbb6..3e1862723268 100644 --- a/stubs/channels/channels/utils.pyi +++ b/stubs/channels/channels/utils.pyi @@ -1,4 +1,4 @@ -from collections.abc import Awaitable, Callable +from collections.abc import Awaitable, Callable, Sequence from typing import Any, Protocol, type_check_only from typing_extensions import TypeAlias @@ -6,7 +6,8 @@ from asgiref.typing import ASGIApplication, ASGIReceiveCallable def name_that_thing(thing: object) -> str: ... async def await_many_dispatch( - consumer_callables: list[Callable[[], Awaitable[ASGIReceiveCallable]]], dispatch: Callable[[dict[str, Any]], Awaitable[None]] + consumer_callables: Sequence[Callable[[], Awaitable[ASGIReceiveCallable]]], + dispatch: Callable[[dict[str, Any]], Awaitable[None]], ) -> None: ... # Defines a generic ASGI middleware protocol. diff --git a/stubs/channels/channels/worker.pyi b/stubs/channels/channels/worker.pyi index a20b5feec275..3bf5c76b8d71 100644 --- a/stubs/channels/channels/worker.pyi +++ b/stubs/channels/channels/worker.pyi @@ -1,13 +1,19 @@ +from collections.abc import Collection + from asgiref.server import StatelessServer from channels.layers import BaseChannelLayer from channels.utils import _ChannelApplication class Worker(StatelessServer): - channels: list[str] + channels: Collection[str] channel_layer: BaseChannelLayer def __init__( - self, application: _ChannelApplication, channels: list[str], channel_layer: BaseChannelLayer, max_applications: int = 1000 + self, + application: _ChannelApplication, + channels: Collection[str], + channel_layer: BaseChannelLayer, + max_applications: int = 1000, ) -> None: ... async def handle(self) -> None: ... async def listener(self, channel: str) -> None: ...