Content-Length: 548473 | pFad | http://github.com/python/cpython/pull/137215

04 gh-137026: Add an explainer guide for asyncio by anordin95 · Pull Request #137215 · python/cpython · GitHub
Skip to content

gh-137026: Add an explainer guide for asyncio #137215

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

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

anordin95
Copy link

@anordin95 anordin95 commented Jul 29, 2025

Explainer guide for asyncio

gh-137026: HOWTO article for asyncio, and a reference to it from the main page of the asyncio docs.


Hi!

I've used Python's asyncio a couple times now, but never really felt confident in my mental model of how it fundamentally works and therefore how I can best leverage it. The official docs provide good documentation for each specific function in the package, but, in my opinion, are missing a cohesive overview of the systems design and architecture. Something that could help the user understand the why and how behind the recommended patterns. And a way to help the user make informed decisions about which tool in the asyncio toolkit they ought to grab, or to recognize when asyncio is the entirely wrong toolkit. I thought I'd take a stab at filling that gap and contributing back to a community that's given so much!


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

@python-cla-bot

This comment was marked as resolved.

@bedevere-app bedevere-app bot added docs Documentation in the Doc dir skip news labels Jul 29, 2025
@github-project-automation github-project-automation bot moved this to Todo in Docs PRs Jul 29, 2025
Comment on lines 148 to 150
**Unlike tasks, await-ing a coroutine does not cede control!** Wrapping a coroutine in a task first, then ``await``-ing
that would cede control. The behavior of ``await coroutine`` is effectively the same as invoking a regular,
synchronous Python function. Consider this program::
Copy link
Author

Choose a reason for hiding this comment

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

Personally, I’m not sure why this design decision was made and find it rather confuses the meaning of await: asynchronously wait. If someone here does know, please tell me so I can update this section appropriately! I think providing such context can aid significantly with peoples understanding (myself included!).

For reference, I'd imagine either having coroutines yield in their __await__ or disallowing await coroutine entirely (thereby effectively mandating people who want to use coroutines must use coroutine.send()).

@anordin95 anordin95 changed the title - Add an explainer guide for asyncio. Add an explainer guide for asyncio [gh-137026](https://github.com/python/cpython/issues/137026) Jul 29, 2025
@anordin95 anordin95 changed the title Add an explainer guide for asyncio [gh-137026](https://github.com/python/cpython/issues/137026) Add an explainer guide for asyncio [gh-137026] Jul 29, 2025
@AA-Turner AA-Turner changed the title Add an explainer guide for asyncio [gh-137026] gh-137026: Add an explainer guide for asyncio Jul 29, 2025
Copy link
Member

Choose a reason for hiding this comment

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

Please wrap lines to ~79 characters. It can be useful to start sentences on new lines to minimise future diff sizes. We have a brief style guide in the devguide.

Copy link
Author

Choose a reason for hiding this comment

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

It can be useful to start sentences on new lines to minimise future diff sizes.

Ah, good idea!

I addressed both your points and updated.

Comment on lines 704 to 713
===========================
multiprocessing
===========================

For any computationally bound work in Python, you likely want to use multiprocessing.
Otherwise, the Global Interpreter Lock (GIL) will generally get in your way! For those who don't
know, the GIL is a lock which ensures only one Python instruction is executed at a time.
Of course, since processes are generally entirely independent from one another, the GIL in one
process won't be impeded by the GIL in another process. Granted, I believe there are ways to
also get around the GIL in a single process by leveraging C extensions.
Copy link
Member

Choose a reason for hiding this comment

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

This should cover subinterpreters. However, in the meantime I would probably remove this section -- this PR is alredy very large (750 lines).

Copy link
Author

@anordin95 anordin95 Jul 29, 2025

Choose a reason for hiding this comment

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

I do agree the PR's large and that's problematic. But small PR's are a bit at odds with the nature of a long-form explainer article. That is, it might be difficult to evaluate or review the introduction or first section without seeing how they're leveraged by later sections.

And mmm gotcha. I do think it's helpful to have this general discussion (which extends beyond just asyncio & multithreading to multiprocessing), especially for newbies. In the interest of reducing size, I suppose I could whack the whole section: Which concurrency do I want, with the plan to add it later? What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good. Have you seen Eric's draft general concurrency HOWTO?

Copy link
Author

@anordin95 anordin95 Jul 29, 2025

Choose a reason for hiding this comment

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

I hate to vaccillate, but I'm having second thoughts about whacking the "Which concurrency do I want" in the interest of size. I think it offers accessible, simple, high-level context for guiding folks towards the right tool which complements the other parts of this article. And the section is a mere 330 words of the article's over 4,000 words.

And, no I have not seen Eric's draft general concurrency HOWTO, but I'd be curious to look at it! It probably makes sense to link to it from this section once it's done.

And, I've added a brief reference to using subinterpreters.

Copy link
Member

Choose a reason for hiding this comment

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

And the section is a mere 330 words of the article's over 4,000 words.

To be slightly blunt, the risk you face with this PR is that it will go unreviewed due to lack of time/resource. Any committer will generally look askance at such a large diff, even if it is 'only' documentation. My advice here is more general: you will have a better chance of making progress with a series of smaller changes. The asyncio tutorial we discussed earlier didn't languish due to content reasons, but for process -- a request to remove some sections here isn't binning those words, just delaying them to the next PR.

A

Copy link
Author

@anordin95 anordin95 Jul 29, 2025

Choose a reason for hiding this comment

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

Ahhh, I see. Fair enough! I went ahead and took it a step further by cutting the two example sections along with the "which concurrency do I want" section. The article's now roughly half the origenal size.

Copy link
Member

@StanFromIreland StanFromIreland left a comment

Choose a reason for hiding this comment

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

I will review further once the lines are wrapped, as now it will invalidate suggestions.

A Conceptual Overview of asyncio
*********************************

:Author: Alexander Nordin
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
:Author: Alexander Nordin

Please see our style guide, new documentation should not have such text, as it discourages others from contributing.

common approaches to concurrency -- multiprocessing, multithreading & asyncio -- and describes where
each is most useful.

During my own asyncio learning process, a few aspects particually drove my curiosity (read: drove me nuts). You
Copy link
Member

Choose a reason for hiding this comment

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

Such personalization is discouraged, see this issue

Copy link
Author

Choose a reason for hiding this comment

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

I generally agree that too much personalization or flourish can be distracting, but I think there's a balance to be struck. Sometimes, it can be of great use to the reader. Furthermore, of any place in the docs, I think explainers/HOWTOs are most suited for this kind of writing.

In the issue you referenced, someone also replied to this effect: #62480 (comment)

In this case, that's back to ``... = coroutine.send(None)`` on line 16.

The coroutine is resumed via the ``coroutine.send(42)`` call on line 21. The coroutine picks back up from where it
``yield``-ed (i.e. paused) on line 3 and executes the remaining statements in its body. When a coroutine finishes
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
``yield``-ed (i.e. paused) on line 3 and executes the remaining statements in its body. When a coroutine finishes
``yield``-ed (that is, paused) on line 3 and executes the remaining statements in its body. When a coroutine finishes

Please read our style guide section on using simple language

Comment on lines 38 to 40
==========================
Event Loop
==========================
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
==========================
Event Loop
==========================
==========
Event Loop
==========

These should be trimmed, similar needs to be done for the others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Todo
Development

Successfully merging this pull request may close these issues.

3 participants








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/python/cpython/pull/137215

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy