New submission from Kyle Stanley <aeros...@gmail.com>:

For context, I decided to open this issue after receiving a substantial volume 
of very similar questions and misconceptions from users of asyncio and trio 
about what `await` does, mostly within a dedicated "async" topical help chat 
(in the "Python Discord" community). For the most part, the brief explanation 
provided in the language reference docs 
(https://docs.python.org/3/reference/expressions.html#await-expression) did not 
help to clear up their understanding.

Also, speaking from personal experience, I did not have a clear understanding 
of what `await` actually did until I gained some experience working with 
asyncio. When I read the language reference definition for the await expression 
for the first time, it did not make much sense to me either.

As a result, I think the documentation for the `await` expression could be made 
significantly more clear. To users that are already familiar with asynchronous 
programming it likely makes more sense, but I don't think it's as helpful as it 
could be for those who are trying to fundamentally understand how `await` works 
(without having prior experience):

"Suspend the execution of coroutine on an awaitable object. Can only be used 
inside a coroutine function."

(https://docs.python.org/3/reference/expressions.html#await-expression)

(Also, note that there's a typo in the current version, "of coroutine" should 
probably be "of a coroutine")

While this explanation is technically accurate, it also looks to be the 
_shortest_ one out of all of the defined expressions on the page. To me, this 
doesn't seem right considering that the await expression is not the easiest one 
to learn or understand.

The vast majority of the questions and misunderstandings on `await` that I've 
seen typically fall under some variation of one of the following:

1) What exactly is being suspended?
2) When is it resumed/unsuspended?
3) How is it useful?

>From what I can tell, (1) is unclear to them is partly because the awaitable 
>object that is after the `await` can be a coroutine object. It's not at all 
>uncommon to see "await some_coro()".

I think this would be much more clear if it were to instead be something along 
the lines of one the following (changes indicated with *):

1) "Suspend the execution of *the current coroutine function* on an awaitable 
object. Can only be used inside a coroutine function."

Where "the current coroutine function" is the coroutine function that contains 
the await expression. I think this would help to clear up the first question, 
"What exactly is being suspended?".

2) "Suspend the execution of *the current coroutine function* on an awaitable 
object. *The coroutine function is resumed when the awaitable object is 
completed and returns its result*. Can only be used inside a coroutine 
function."

This would likely help to clear up "When is it resumed/unsuspended?".

Optimally, this definition could also include some form of example code like 
several of the other expressions have. It's not particularly easy to use a 
demonstrable example without using an async library (such as asyncio), but 
using a specific async library would not make sense to have in this location of 
the docs because the language reference is supposed to be as implementation 
agnostic as possible.

However, I think a very brief visual example with some explanation could still 
be useful for explaining the basics of how await works:

3) ```
async def coro():
    # before await
    await some_awaitable
    # after await

When the coroutine function `coro()` is executed, it will behave roughly the 
same as any subroutine function in the "before await" section. However, upon 
reaching `await some_awaitable`, the execution of `coro()` will be suspended on 
`some_awaitable`, preventing the execution of anything in the "after await" 
section until `some_awaitable` is completed. This process is repeated with 
successive await expressions. Also, multiple coroutines can be suspended at the 
same time.

Suspension can be used to indicate that other coroutines can be executed in the 
meantime. This can be used to write asynchronous and concurrent programs 
without the usage of callbacks.
```

Including the brief example and explanation would likely help to further clear 
up all three of the questions.

The present version has a high degree of technical accuracy, but I don't think 
its as helpful as it could be for furthering the understanding of users or 
providing an introduction to the await expression. I'm sure that there will 
still be some questions regarding `await` even if any of these changes are 
made, but it would at least provide a good place to link to for an informative 
explanation of `await` that's entirely agnostic from any specific 
implementation.

I'm entirely open to any alternative suggestions, or making a change that's 
some combination or variation of the above three ideas. Alternatively, if there 
are determined to be no suitable changes that would be both technically 
accurate and more helpful to users, I could just apply a fix to the typo.

If any of these ideas are approved, I'll likely open a PR.

----------
assignee: aeros
components: Documentation, asyncio
messages: 358610
nosy: aeros, asvetlov, njs, yselivanov
priority: normal
severity: normal
status: open
title: Improve docs for await expression
type: enhancement
versions: Python 3.8, Python 3.9

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue39085>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to