Skip to content

Conversation

@cjwatson
Copy link
Contributor

list is invariant, which made this type inconvenient in practice. Each of the routes is either a pattern or another router.

@cjwatson
Copy link
Contributor Author

CC @huynguyengl99

@github-actions

This comment has been minimized.

@huynguyengl99
Copy link
Contributor

I think it makes sense to migrate from list to Collection. If you have time, could you also help check whether other places or functionalities could be updated to use Collection as well?

`list` is invariant, which made this type inconvenient in practice.
Each of the routes is either a pattern or another router.
@cjwatson cjwatson force-pushed the channels-routing-sequence branch from ff63966 to 89dcb62 Compare November 25, 2025 10:06
@cjwatson cjwatson changed the title [channels] Make URLRouter.routes a Sequence [channels] Make URLRouter.routes a Collection Nov 25, 2025
@cjwatson
Copy link
Contributor Author

Good point - this is only iterated over, not indexed, so Collection is enough.

I only found a couple of other places in stubs/channels/ where I was confident in weakening list parameter types to something covariant. One of them could be a Collection, while the other really did need to be a Sequence since it's indexed.

@cjwatson cjwatson force-pushed the channels-routing-sequence branch from 9a80b21 to 79675e2 Compare November 25, 2025 10:12
@github-actions
Copy link
Contributor

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

@huynguyengl99
Copy link
Contributor

Looks good to me now.

@huynguyengl99
Copy link
Contributor

To make it easier for the core developers to track and approve this PR, could you create an issue and link this PR to it, @cjwatson?

@huynguyengl99
Copy link
Contributor

And I think you can make the title a bit more generic since the changes are varied.

Copy link
Collaborator

@srittau srittau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Notes below.

Comment on lines +23 to +25
routes: Collection[_ExtendedURLPattern | URLRouter]

def __init__(self, routes: list[_ExtendedURLPattern | URLRouter]) -> None: ...
def __init__(self, routes: Collection[_ExtendedURLPattern | URLRouter]) -> None: ...
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The typeshed standard for for ... in loops is Iterable. In fact, Collection won't work:

from collections.abc import Container

x: Container[int] = []

for y in x:  # error: "Container[int]" has no attribute "__iter__" (not iterable)
    reveal_type(y)  # note: Revealed type is "Any"

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]],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the return value of dispatch is ignored, it can be an arbitrary value and doesn't have to be None:

Suggested change
dispatch: Callable[[dict[str, Any]], Awaitable[None]],
dispatch: Callable[[dict[str, Any]], Awaitable[object]],

@@ -1,13 +1,19 @@
from collections.abc import Collection
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above.

@srittau
Copy link
Collaborator

srittau commented Nov 26, 2025

I only found a couple of other places in stubs/channels/ where I was confident in weakening list parameter types to something covariant. One of them could be a Collection, while the other really did need to be a Sequence since it's indexed.

For reference, we try to cut back on the use of pseudo-protocols like Mapping and Sequence and use protocols (like Collection or Iterable or one of the custom protocols from _typeshed) instead. This particular case would really benefit from having protocol intersections to be able to easily combine the Iterable and SupportsGetItem protocols. But for now the most pragmatic solution is to just use Sequence like you did.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants