Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error with asyncio.sleep(): Argument type is partially unknown #3475

Closed
wch opened this issue May 18, 2022 · 3 comments
Closed

Error with asyncio.sleep(): Argument type is partially unknown #3475

wch opened this issue May 18, 2022 · 3 comments
Labels
as designed Not a bug, working as intended

Comments

@wch
Copy link

wch commented May 18, 2022

I'm not sure if this is an issue with pyright or with typeshed, so please let me know if it belongs in typeshed.

With the latest version of pyright (1.1.247), this code results in an error:

from typing import Awaitable, TypeVar
import asyncio
T = TypeVar("T")

async def wrap(coro: Awaitable[T]) -> T:
    return await coro

async def wrap_sleep() -> None:
    await wrap(asyncio.sleep(0))

The result when I run pyright on it:

Found 1 source file
/..../test/test.py
  /..../test/test.py:9:16 - error: Argument type is partially unknown
    Argument corresponds to parameter "coro" in function "wrap"
    Argument type is "Coroutine[Any, Any, Unknown]" (reportUnknownArgumentType)
1 error, 0 warnings, 0 informations 

However, if result is specified, it passes:

async def wrap_sleep1() -> None:
    await wrap(asyncio.sleep(0, result=None))

Similarly, if I create a wrapper function for asyncio.sleep() where the return type is explicitly set to None, it passes:

async def sleep0() -> None:
    await asyncio.sleep(0)

async def wrap_sleep2() -> None:
    await wrap(sleep0())
@JelleZijlstra
Copy link
Contributor

For reference, sleep() is defined here: https://github.com/python/typeshed/blob/master/stdlib/asyncio/tasks.pyi#L273:

async def sleep(delay: float, result: _T = ...) -> _T: ...

So it makes sense that pyright can't infer the return value if the result parameter is not provided. We should instead use overloads: one with one param that returns None, and one with two params that returns _T.

@erictraut
Copy link
Collaborator

erictraut commented May 18, 2022

Yeah, I agree with Jelle that the definition for sleep should use an overload to avoid an unsolvable TypeVar. Here's how that would look:

    @overload
    async def sleep(delay: float) -> None: ...
    @overload
    async def sleep(delay: float, result: _T) -> _T: ...

Please file a bug (or even better, a PR!) in the typeshed project. Pyright regularly picks up updates to typeshed stubs.

In the meantime, you can work around the problem by adding an explicit argument for the result parameter.

@erictraut erictraut added the as designed Not a bug, working as intended label May 18, 2022
@wch
Copy link
Author

wch commented May 18, 2022

Thanks! I've filed an issue on typeshed.

JelleZijlstra pushed a commit to python/typeshed that referenced this issue May 18, 2022
Closes #7866. This adds an overload to `asyncio.sleep()`, so that when it is called _without_ `return=None`, the type checker knows that the return type is `None` instead of `unknown`.

Also related to microsoft/pyright#3475.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
as designed Not a bug, working as intended
Projects
None yet
Development

No branches or pull requests

3 participants