pythonasynchronousgilpython-contextvars

contextvars: get and set atomic


In documentation I didn't find anything about contextvars update.

I need to have following atomically:

context_metadata = contextvars.ContextVar("context_logger_metadata")
my_dict = context_metadata.get()
my_dict['appended'] = 'some_data'
context_metadata.set(my_dict)

Does python provide something like synchronization block? How can I be sure that GIL won't switch context between get and set?


Solution

  • As put in the comments: in an async program, the context switch only takes place at explicit points under developer control: no await for a call, no context switch. In your example code, your "read, change, set" sequence will take place with no interruptions.

    And I hope you have in mind that contextvars do not make object copies when getting or setting their contents: that is, the dictionary you retrieve with get is the same object that is the context_var value: when you update a key in it, there is no need to set the value back to the context var: the dictionary is already updated.

    If your code uses threads, or combine threads with async code, then, traditional threading.Lock usage around your atomic operations will work.