This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: ContextVar get value is unexpected
Type: behavior Stage: resolved
Components: asyncio Versions: Python 3.8
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: asvetlov, chenzep, yselivanov
Priority: normal Keywords:

Created on 2020-09-06 13:41 by chenzep, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (2)
msg376464 - (view) Author: Jason Chen (chenzep) Date: 2020-09-06 13:41
import asyncio
from contextvars import *

var = ContextVar('VarTest', default=None)

def get_var(tag=None):
    obj = var.get()
    if obj is None:
        obj = object()
        var.set(obj)
    print(f'{tag=}: get_var result is {obj=}')
    return obj

async def get_var_object(tag):
    return get_var(tag)

async def asyncio_main():
    await asyncio.gather(*[get_var_object(id) for id in range(2)])

def test(get_var_before_run=False):
    print(f'{get_var_before_run=}')
    if get_var_before_run:
        get_var()
    asyncio.run(asyncio_main())
    print()


if __name__ == '__main__':
    test(get_var_before_run=False)
    test(get_var_before_run=True)


---- Output:-------

tag=0: get_var result is obj=<object object at 0x7f194571d210>
tag=1: get_var result is obj=<object object at 0x7f194571d200>

get_var_before_run=True
tag=None: get_var result is obj=<object object at 0x7f194571d210>
tag=0: get_var result is obj=<object object at 0x7f194571d210>
tag=1: get_var result is obj=<object object at 0x7f194571d210>


--- my question: ------
-- all objects in get_var_before_run=True are same.
-- my expected result is all objects should be different, because the code runs in different context.
msg376589 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2020-09-08 18:44
> my expected result is all objects should be different, because the code runs in different context.

Contexts "branch", so if you store something in the context before asyncio.run it will store it in the current thread state. And then asyncio.run will pick it up.

Also I'd recommend using something else than object IDs - those can be reused and can be very confusing when browsing logs -- it might look like it was the same object, but in fact it could be to different objects sharing the same ID at different points of time.
History
Date User Action Args
2022-04-11 14:59:35adminsetgithub: 85899
2020-09-08 18:44:39yselivanovsetstatus: open -> closed
type: behavior
messages: + msg376589

resolution: not a bug
stage: resolved
2020-09-06 13:41:11chenzepcreate