Closed ZeeD closed 2 years ago
aclosing(thing)
expects a thing
that has a aclose()
method:
Yet AsyncGenerator
objects do have such an aclose()
method:
$ python -m asyncio
>>> async def agen():
... yield 0
...
>>> g = agen()
>>> g.aclose
<built-in method aclose of async_generator object at 0x10734da60>
And they are also spec'd as having one:
https://docs.python.org/3/library/collections.abc.html
ABC | Inherits from | Abstract Methods | Mixin Methods |
---|---|---|---|
AsyncGenerator | AsyncIterator | asend, athrow | aclose, aiter, anext |
This alternative snippet (independent of trio-typing
) seems to say that the problem is not with the presence of aclose()
, but with its signature…
from typing import Protocol, AsyncContextManager, AsyncGenerator, Awaitable
class _AsyncCloseable(Protocol):
async def aclose(self) -> None:
...
def aclosing(obj: _AsyncCloseable) -> AsyncContextManager[_AsyncCloseable]:
...
async def agen() -> AsyncGenerator[int, None]:
yield 0
async def main() -> None:
async with aclosing(agen()) as _: # error
pass
example.py:18: error: Argument 1 to "aclosing" has incompatible type "AsyncGenerator[int, None]"; expected "_AsyncCloseable"
example.py:18: note: Following member(s) of "AsyncGenerator[int, None]" have conflicts:
example.py:18: note: Expected:
example.py:18: note: def aclose(self) -> Coroutine[Any, Any, None]
example.py:18: note: Got:
example.py:18: note: def aclose(self) -> Awaitable[None]
Found 1 error in 1 file (checked 1 source file)
So it seems _AsyncClosable
should actually be this…?
class _AsyncCloseable(Protocol):
def aclose(self) -> Awaitable[None]:
...
Which would work with both async generators, and arbitrary classes that have an async def aclose(self) -> None
method…
class A:
async def aclose(self) -> None:
pass
async def agen() -> AsyncGenerator[int, None]:
yield 0
async def main() -> None:
async with aclosing(agen()) as _: # OK
pass
async with aclosing(A()) as _: # OK
pass
The reason is that Awaitable
, which is what an async generator's aclose()
returns, is a parent of Coroutine
, which is what a regular async def () -> None
returns.
ABC | Inherits from | Abstract Methods | Mixin Methods |
---|---|---|---|
Awaitable | await | ||
Coroutine | Awaitable | send, throw | close |
I don't know why async generator's aclose()
are typed as returning an Awaitable
, but heh…
I don't know why async generator's aclose() are typed as returning an Awaitable, but heh… here's the def: https://github.com/python/typeshed/blob/2b64f54008f6dbaded7970336e26c4f02fa82fd9/stdlib/types.pyi#L192
it's an abc so needs to be as wide as possible to support any subclasses
I tried to make a simple snippet to reproduce the error
running mypy I have this error:
I'm using
Python 3.8.0
,mypy 0.800
,async-generator 1.10
,trio-typing 0.5.0
and mymypy.ini
is