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
typing docs are unclear on when AsyncIterator should be used in type hints as opposed to AsyncGenerator
#112866
Comments
|
What makes you think that >>> class Foo:
... def __init__(self):
... self.iterable = iter(range(5))
... def __aiter__(self):
... return self
... async def __anext__(self):
... try:
... return next(self.iterable)
... except StopIteration:
... raise StopAsyncIteration from None
...
>>> f = Foo()
>>> async for x in f:
... print(x)
...
0
1
2
3
4
>>> f = Foo()
>>> it = aiter(f)
>>> it.aclose
Traceback (most recent call last):
File "C:\Users\alexw\AppData\Local\Programs\Python\Python312\Lib\concurrent\futures\_base.py", line 449, in result
return self.__get_result()
^^^^^^^^^^^^^^^^^^^
File "C:\Users\alexw\AppData\Local\Programs\Python\Python312\Lib\concurrent\futures\_base.py", line 401, in __get_result
raise self._exception
File "C:\Users\alexw\AppData\Local\Programs\Python\Python312\Lib\asyncio\__main__.py", line 34, in callback
coro = func()
^^^^^^
File "<console>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'aclose'The pylance error you're receiving seems like a true positive to me. If you need to be able to use the |
|
Hello! |
Well, you know, I am just following the docs:
Thanks for your help, anyway. |
|
Hmm. Well, perhaps we could improve the docs there! What the docs are trying to say is "if you're not doing anything with the async generator that's specific to it being an async generator, you can just use the simpler type hint". In this case you are doing something that only async generators have, as opposed to other async iterators -- you're using the |
AsyncIterator should be used in type hints as opposed to AsyncGenerator
|
@H0R5E Would you like to send a PR with a docs update? ;) |
|
@Eclips4, my proposal for the docs update would be to delete everything from "Alternatively" onwards. It seems to me that just typing these as If that's OK, would I submit a PR to all the relevant branches for each Python version? |
|
I don't think we should delete the sentence, as there are solid reasons to prefer these annotations (you are free to change your implementation to a different kind of iterable later, and you don't have to think about a send type). A change should be submitted as a PR to the |
|
@JelleZijlstra, when you say "change your implementation to a different kind of iterable later," do you mean not use @Eclips4, I think the answer is 'no' then, as:
Thanks again for your help. Mat |
|
If you make a library, you could decide that the API you're exposing is an async iterable. An async iterable could be implemented as an async generator, but if you say in your type annotations that it's definitely an async generator, you guarantee to your users that you'll always keep returning an async generator, which means you can't change later to some other kind of async iterable. As an analogy, you could have an API that currently returns a list, but you might want to annotate it as Iterable so that you're free later to change it to return say a set or a generator. |


Bug report
Bug description:
Hi,
I have an issue with type checking for an aynchronous iterator that I break from for testing purposes. I call the
aclosemethod on the iterator to clean it up after the break. This works fine in practice, but typing complains that the method doesn't exist. See the example below (the comment shows the pylance output).In
collections.abctheaclosemethod is defined on anAsyncGenerator, butticker, above, does not fit that model.acloseworks on anAsyncIteratorso I think it should be defined as a method incollections.abcalso.Thanks for your help,
Mat
CPython versions tested on:
3.9
Operating systems tested on:
Windows
The text was updated successfully, but these errors were encountered: