title: How do I write consistent stateful context managers?
body: <p>EDIT: As pointed out by <a href="https://stackoverflow.com/users/550094">Thierry Lathuille</a>, <a href="https://www.python.org/dev/peps/pep-0567" rel="nofollow noreferrer">PEP567</a>, where <code>ContextVar</code> was introduced, was not designed to address generators (unlike the withdrawn <a href="https://www.python.org/dev/peps/pep-0550" rel="nofollow noreferrer">PEP550</a>). Still, the main question remains. How do I write stateful context managers that behave correctly with multiple threads, generators and <code>asyncio</code> tasks?</p>
  
  <hr>
  
  <p>I have a library with some functions that can work in different "modes", so their behavior can be altered by a local context. I am looking at the <a href="https://docs.python.org/3/library/contextvars.html" rel="nofollow noreferrer"><code>contextvars</code></a> module to implement this reliably, so I can use it from different threads, asynchronous contexts, etc. However, I am having trouble getting a simple example working right. Consider this minimal setup:</p>
  
  <pre><code>from contextlib import contextmanager
  from contextvars import ContextVar
  
  MODE = ContextVar('mode', default=0)
  
  @contextmanager
  def use_mode(mode):
      t = MODE.set(mode)
      try:
          yield
      finally:
          MODE.reset(t)
  
  def print_mode():
     print(f'Mode {MODE.get()}')
  </code></pre>
  
  <p>Here is a small test with a generator function:</p>
  
  <pre><code>def first():
      print('Start first')
      print_mode()
      with use_mode(1):
          print('In first: with use_mode(1)')
          print('In first: start second')
          it = second()
          next(it)
          print('In first: back from second')
          print_mode()
          print('In first: continue second')
          next(it, None)
          print('In first: finish')
  
  def second():
      print('Start second')
      print_mode()
      with use_mode(2):
          print('In second: with use_mode(2)')
          print('In second: yield')
          yield
          print('In second: continue')
          print_mode()
          print('In second: finish')
  
  first()
  </code></pre>
  
  <p>I get the following output:</p>
  
  <pre class="lang-none prettyprint-override"><code>Start first
  Mode 0
  In first: with use_mode(1)
  In first: start second
  Start second
  Mode 1
  In second: with use_mode(2)
  In second: yield
  In first: back from second
  Mode 2
  In first: continue second
  In second: continue
  Mode 2
  In second: finish
  In first: finish
  </code></pre>
  
  <p>In the section:</p>
  
  <pre class="lang-none prettyprint-override"><code>In first: back from second
  Mode 2
  In first: continue second
  </code></pre>
  
  <p>It should be <code>Mode 1</code> instead of <code>Mode 2</code>, because this was printed from <code>first</code>, where the applying context should be, as I understand it, <code>use_mode(1)</code>. However, it seems that the <code>use_mode(2)</code> of <code>second</code> is stacked over it until the generator finishes. Are generators not supported by <code>contextvars</code>? If so, is there any way to support stateful context managers reliably? By reliably, I mean it should behave consistently whether I use:</p>
  
  <ul>
  <li>Multiple threads.</li>
  <li>Generators.</li>
  <li><code>asyncio</code></li>
  </ul>