Skip to content

Conversation

anordin95
Copy link
Contributor

@anordin95 anordin95 commented Aug 22, 2025

anordin95 and others added 3 commits August 23, 2025 15:04
:mod:`!asyncio` automatically associates tasks with the event loop for you.
Typically there's only one event loop, so that's quite straightforward.
It's uncommon, but some applications use multithreading and :mod:`!asyncio`
together, where there's one event loop per thread, stored in thread-local
Copy link
Contributor

@kumaraditya303 kumaraditya303 Aug 24, 2025

Choose a reason for hiding this comment

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

"stored in thread-local" is unnecesary implemenetation detail for the reader, just per thread seems sufficient.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See discussion here: #138073 (comment)

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 also be OK with just "per thread". But, I don't totally understand the rationale to clarify thread-locality here -- what was wrong with the original wording?

Copy link
Contributor Author

@anordin95 anordin95 Aug 25, 2025

Choose a reason for hiding this comment

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

This paragraph states asyncio automatically associates tasks with the event loop so you, the user, don't need to specify the loop in the asyncio.create_task constructor (nor are you even allowed to). The "per thread" part implies there can be multiple event loops (via multithreading) in the same memory space.

I think it's quite natural to then wonder how tasks will be associated with event loops when there are multiple event loops to choose from. And how you, the user, could manage which loop a task is assigned to. I see that as an easy way for the reader to get confused. The point of this article is to be explanatory.

While, yes, it is an implementation detail, it's not some arcane, fragile aspect. It's a fundamental design pattern exposed by the OS. And, it appears this usage of thread-local hasn't changed in the 12 years that asyncio has been around.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thread locality is an implementation detail and should stay as an implementation detail, -1 for adding this.

Copy link
Contributor Author

@anordin95 anordin95 Aug 26, 2025

Choose a reason for hiding this comment

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

Yes, that is largely what you wrote the first time around. The logical gap I highlighted would still exist and potentially confuse readers. I agree, implementation details should generally be kept in the code, but not always. Sparsely and judiciously exposing broad ideas can ultimately create more explanatory and helpful docs, as opposed to making many vague, abstract statements, especially since this is a HOWTO, not reference, doc. Could you clarify some of the reasoning behind why you feel this way?

Like I mentioned in the prior PR, perhaps you can see how it's difficult to productively engage with this style of feedback and discussion?

Copy link
Member

Choose a reason for hiding this comment

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

Alex, I sympathize with thread-locality being quite confusing, but I'm going to side with Kumar here. asyncio really isn't about multithreading at all, and as you said, this is an explanatory HOWTO article. We should try to avoid bringing up niche use-cases that make the reader think "oh, asyncio and multithreading are friends, let's do that more".

As a compromise for now, would you mind reverting these changes and putting them in a follow-up PR so we can argue about it there? The rest of the changes in this PR look good to me, and it would better for those to not be blocked by discussions about this.

(We really do value your article as a contribution, please don't take this the wrong way!)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mhm fair enough :). Will do.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See: #138200

@@ -251,6 +253,10 @@ different ways::
In a crucial way, the behavior of ``await`` depends on the type of object
being awaited.

^^^^^^^^^^
await task
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
await task
Awaiting Tasks

Copy link
Contributor Author

@anordin95 anordin95 Aug 24, 2025

Choose a reason for hiding this comment

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

I prefer the original for two reasons.

The titles come from the references made in the broader await section intro.

And they fit more naturally in the broader table of contents:

image

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
await task
Awaiting tasks

@@ -282,6 +288,10 @@ This is a basic, yet reliable mental model.
In practice, the control handoffs are slightly more complex, but not by much.
In part 2, we'll walk through the details that make this possible.

^^^^^^^^^^^^^^^
await coroutine
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
await coroutine
Awaiting Coroutines

Copy link
Member

Choose a reason for hiding this comment

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

Use sentence case for headers:

https://devguide.python.org/documentation/style-guide/#capitalization

Suggested change
await coroutine
Awaiting coroutines

(We could also fixA Conceptual Overview of asyncio" -> "A conceptual overview of asyncio" and "Event Loop" -> "Event loop".)

image

:mod:`!asyncio` automatically associates tasks with the event loop for you.
Typically there's only one event loop, so that's quite straightforward.
It's uncommon, but some applications use multithreading and :mod:`!asyncio`
together, where there's one event loop per thread, stored in thread-local
Copy link
Contributor

Choose a reason for hiding this comment

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

Thread locality is an implementation detail and should stay as an implementation detail, -1 for adding this.

@bedevere-app
Copy link

bedevere-app bot commented Aug 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.

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