typeshed
typeshed copied to clipboard
Incorrect return type for asyncio.gather?
asyncio.gather
return type from tasks.pyi
seem to be different from the actual runtime type.
example.py
import asyncio
from typing import List
async def five() -> int:
return 5
async def runner() -> List[int]:
fives = await asyncio.gather(five(), five(), five())
print(type(fives)) # prints `<class 'list'>`
print(fives) # prints `[5, 5, 5]`
return fives
loop = asyncio.get_event_loop()
result: List[int] = loop.run_until_complete(runner())
$ python3 --version
Python 3.6.6
$ python3 example.py
<class 'list'>
[5, 5, 5]
$ mypy --version
mypy 0.641
$ mypy example.py
example.py:11: error: Incompatible return value type (got "Tuple[int, int, int]", expected "List[int]")
By looking at tasks.pyi
I see no overload or any case where gather
does not return a Tuple
.
Looking at the implementation of gather()
in both Python 3.5 and 3.7, it seems to always return a list future. The problem is that there is no way to annotate it to return a list with different types at each position. Philosophically, gather()
should return a tuple.
All fixes I can see have other downsides. -> List[Any]
and -> List[Union[_T1, _T2]]
etc. lose type and length information. The latter also makes it cumbersome to retrieve values in the general case, where _T1 != _T2
.
Can't think of any better solution right now. I feel like it is better to lose type information than have it wrong. Were there any similar issues in the past?
I've just ran into this one, and I agree that List[Any]
would be a better solution here. I understand that it loses typing information, but it's better than having an incorrect type altogether. It seems that MyPy agrees to this, as the current return type as reported by reveal_type
there is asyncio.Future[builtins.list[Any]]
.
Is the base issue here that the return type of gather
changed after Python 3.7, which means supporting the correct typing would break compatibility with those versions?
Nevermind, I poked around about in tasks.pyi and I see that the problem I'm getting locally has to do with my interpreter version running LSP not being the version I expect, I see the issue.
Would TypeVarTuple
help with this now? https://peps.python.org/pep-0646/#implications
Once mypy supports it of course https://github.com/python/mypy/issues/12280
No, because TypeVarTuple can't be used to type a heterogeneous list.