Skip to content

Conversation

@sergey-miryanov
Copy link
Contributor

@sergey-miryanov sergey-miryanov commented Nov 23, 2025

Added section about best practices for async generators.


📚 Documentation preview 📚: https://cpython-previews--141885.org.readthedocs.build/

@sergey-miryanov
Copy link
Contributor Author

@kumaraditya303 Could you please take a look?

sergey-miryanov and others added 2 commits November 24, 2025 10:32
Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com>
@kumaraditya303 kumaraditya303 self-assigned this Nov 24, 2025
Asynchronous generators best practices
======================================

By :term:`asynchronous generator` in this section we will mean
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems obvious, by generator we typically mean the generator object not the function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw this clarification in few places (e.g. https://docs.python.org/3/glossary.html#term-asynchronous-generator), so I thought it was worth mentioning. I'm OK to remove this if you think so.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my experience, the term "generator" is used equally for a generator function and for the iterator returned by calling a generator function. If you really only use it for the latter, then this clarification makes sense.

Manually close the generator
----------------------------

If an asynchronous generator happens to exit early by :keyword:`break`, the caller
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels too heavy for start, I would start it as "It is recommended to manually close the generator... " then in second para describe the issue with breaking early.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, will fix this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC the scenario(s) you are trying to describe is where the code iterating over the generator doesn't iterate till the end. If you're iterating over it using a for-loop (there are other ways!) that could be a break in that for-loop, or the task containing that for-loop getting canceled, or indeed an exception being raised in the for-loop body. But I'm not sure it's helpful to try to list all the reasons why this can happen -- maybe the most useful one to mention is an exception being raised during that for-loop?

(The example code clarifies a lot!)

@kumaraditya303
Copy link
Contributor

I would appreciate a review from @willingc and @gvanrossum on this.

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's great to add these explicitly to the docs!

I hope you don't mind that I have tried to correct your English grammar somewhat (mostly adding or subtracting "the").

======================================

By :term:`asynchronous generator` in this section we will mean
an :term:`asynchronous generator iterator` that returned by
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
an :term:`asynchronous generator iterator` that returned by
an :term:`asynchronous generator iterator` that is returned by an

Asynchronous generators best practices
======================================

By :term:`asynchronous generator` in this section we will mean
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my experience, the term "generator" is used equally for a generator function and for the iterator returned by calling a generator function. If you really only use it for the latter, then this clarification makes sense.



Asynchronous generators best practices
======================================
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd insert some friendly words here introducing the reader to the purpose of this section. Right now it looks rather stern.

Manually close the generator
----------------------------

If an asynchronous generator happens to exit early by :keyword:`break`, the caller
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC the scenario(s) you are trying to describe is where the code iterating over the generator doesn't iterate till the end. If you're iterating over it using a for-loop (there are other ways!) that could be a break in that for-loop, or the task containing that for-loop getting canceled, or indeed an exception being raised in the for-loop body. But I'm not sure it's helpful to try to list all the reasons why this can happen -- maybe the most useful one to mention is an exception being raised during that for-loop?

(The example code clarifies a lot!)

Comment on lines +265 to +266
will run and possibly raise exceptions or access context variables in an
unexpected context--perhaps after the lifetime of tasks it depends, or
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
will run and possibly raise exceptions or access context variables in an
unexpected context--perhaps after the lifetime of tasks it depends, or
will run in an unexpected context -- perhaps after the lifetime of tasks it depends on, or

Comment on lines +297 to +298
Then it is recomended to create async generators only after the event loop
has already been created.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow how it follows from the previous paragraph (which describes that finalization of an async generator-iterator may be delayed if its body hasn't finished yet) to the recommendation of creating them only after an event loop exists.

Avoid iterating and closing the same generator concurrently
-----------------------------------------------------------

The async generators allow to be reentered while another
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The async generators allow to be reentered while another
Async generators may to be reentered while another

-----------------------------------------------------------

The async generators allow to be reentered while another
:meth:`~agen.aclose`/:meth:`~agen.aclose`/:meth:`~agen.aclose` call is in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is :meth:`~agen.aclose` repeated three times here?

The async generators allow to be reentered while another
:meth:`~agen.aclose`/:meth:`~agen.aclose`/:meth:`~agen.aclose` call is in
progress. This may lead to an inconsistent state of the async generator
and cause errors.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
and cause errors.
and can cause errors.

Comment on lines +350 to +351
Therefore, it is recommended to avoid using the async generators in parallel
tasks or in the multiple event loops.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Therefore, it is recommended to avoid using the async generators in parallel
tasks or in the multiple event loops.
Therefore, it is recommended to avoid using async generators in parallel
tasks or from multiple event loops.

@bedevere-app
Copy link

bedevere-app bot commented Nov 26, 2025

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@gvanrossum
Copy link
Member

I'd also love to get @willingc's view on how to make this section have the right tone so as not to scare beginners away.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting changes docs Documentation in the Doc dir skip news

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

4 participants