1

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?

Rudziankoŭ
  • 10,681
  • 20
  • 92
  • 192
  • 3
    In an async program, no switch will occur without an `await`. Also the GIL is not an issue in async programs. Or do you use multithreading? – VPfB Sep 17 '21 at 12:18

1 Answers1

2

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.

jsbueno
  • 99,910
  • 10
  • 151
  • 209