[Python-Dev] PEP 550 v4: coroutine policy
Yury Selivanov
yselivanov.ml at gmail.com
Tue Aug 29 16:20:21 EDT 2017
On Tue, Aug 29, 2017 at 4:10 PM, Antoine Pitrou <antoine at python.org> wrote:
[..]
>> "await bar()" and "await wait_for(bar())" are actually quite
>> different. Let me illustrate with an example:
>>
>> b1 = bar()
>> # bar() is not running yet
>> await b1
>>
>> b2 = wait_for(bar())
>> # bar() was wrapped into a Task and is being running right now
>> await b2
>>
>> Usually this difference is subtle, but in asyncio it's perfectly fine
>> to never await on b2, just let it run until it completes. If you
>> don't "await b1" -- b1 simply will never run.
>
> Perhaps... But still, why doesn't bar() inherit the LC *at the point
> where it was instantiated* (i.e. foo()'s LC in the examples)? The fact
> that it's *later* passed to wait_for() shouldn't matter, right? Or
> should it?
bar() will inherit the lookup chain. Two examples:
1)
gvar = new_context_var()
var = new_context_var()
async def bar():
# EC = [current_thread_LC_copy, Task_foo_LC]
var.set(42)
assert gvar.get() == 'aaaa'
async def foo():
# EC = [current_thread_LC_copy, Task_foo_LC]
gvar.set('aaaa')
await bar()
assert var.get() == 42 # with previous PEP 550 semantics
assert gvar.get() == 'aaaa'
# EC = [current_thread_LC]
run_until_complete(foo()) # Task_foo
2)
gvar = new_context_var()
var = new_context_var()
async def bar():
# EC = [current_thread_LC_copy, Task_foo_LC_copy, Task_wait_for_LC]
var.set(42)
assert gvar.get() == 'aaaa'
async def foo():
# EC = [current_thread_LC_copy, Task_foo_LC]
await wait_for(bar(), 1) # bar() is wrapped into
Task_wait_for implicitly
assert gvar.get() == 'aaaa' # OK
assert var.get() == 42 # AssertionError !!!
# EC = [current_thread_LC]
run_until_complete(foo()) # Task_foo
The key difference:
In example (1), bar() will have the LC of the Task that runs foo().
Both "foo()" and "bar()" will *share* the same LC. That's why foo()
will see changes made in bar().
In example (2), bar() will have the LC of wait_for() task, and foo()
will have a different LC.
Yury
More information about the Python-Dev
mailing list