Skip to content

"Awaitable" is insufficiently expressive, as one may await something other than Futures #542

@glyph

Description

@glyph

In the wild, today, if you await something, there are several potentially valid things to bubble back out from the innermost await

  • an asyncio.Future
  • a curio "trap" (which I gather is defined as something like Tuple[curio.traps.Traps, Any, ...])
  • a Trio trap, (which I gather is defined as something like Iterable[WaitTaskRescheduled] although I haven't quite found the bottom of that stack)
  • a Deferred

Not all of these are mutually compatible. However, Awaitable is parameterized only on one type - the type of its result. This results in code like this:

def some_deferred() -> Awaitable[int]: ...
def some_future() -> Awaitable[int]: ...

async def x() -> Awaitable[List[int]]:
    y = []
    y.append(await some_deferred())
    y.append(await some_future())
    return y

type-checking even though it should fail.

I'd like to be able to express this as

def some_deferred() -> Awaitable[int, Deferred]: ...
def some_future() -> Awaitable[int]: ... # presumably Future is the default

async def x() -> Awaitable[List[int]]:
    y = []
    y.append(await some_deferred()) # <-- automatically specialize to `Awaitable[List[int], Deferred]` here, if possible?
    y.append(await some_future()) # <-- type error!
    return y

This is made slightly more complex by the fact that some awaitables are mutually intelligible - for example, anything that awaits a Deferred should eventually be able to await a Future directly, once we've made a few more changes to Twisted. We could also do this in the other direction if __await__ were changed to pass the loop along. Whereas, some of these types are incompatible by design; my understanding is that await implies a completely different, and somewhat higher-level, scheduling protocol in Trio, for example.

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: featureDiscussions about new features for Python's type annotations

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions