title: Returning value when exiting python context manager
body: <p>Maybe this is a stupid (and indeed not very practical) question but I'm asking it because I can't wrap my head around it.</p>
  
  <p>While researching if a <code>return</code> statement inside a call to a context manager would prevent <code>__exit__</code> from being called (no it doesn't), I found that it seems common to make an analogy between <code>__exit__</code> and <code>finally</code> in a <code>try/finally</code> block (for example here: <a href="https://stackoverflow.com/a/9885287/3471881">https://stackoverflow.com/a/9885287/3471881</a>) because:</p>
  
  <pre><code>def test():
      try:
          return True
      finally:
          print("Good bye")
  </code></pre>
  
  <p>Would execute the same as:</p>
  
  <pre><code>class MyContextManager:
  
      def __enter__(self):
          return self
  
      def __exit__(self, *args):
          print('Good bye')
  
  def test():
      with MyContextManager():
          return True
  </code></pre>
  
  <p>This really helped me understand how cm:s work but after playing around a bit I realised that this analogy wont work if we are returning something rather than printing.</p>
  
  <pre><code>def test():
      try:
          return True
      finally:
          return False
  test()    
  --&gt; False
  </code></pre>
  
  <p>While <code>__exit__</code> seemingly wont return at all:</p>
  
  <pre><code>class MyContextManager:
  
      def __enter__(self):
          return self
  
      def __exit__(self, *args):
          return False
  
  def test():
      with MyContextManager():
          return True
  
  test()
  --&gt; True
  </code></pre>
  
  <p>This lead me to think that perhaps you can't actually return anything inside <code>__exit__</code>, but you can:</p>
  
  <pre><code>class MyContextManager:
  
      def __enter__(self):
          return self
  
      def __exit__(self, *args):
          return self.last_goodbye()
  
      def last_goodbye(self):
          print('Good bye')
  
  def test():
      with MyContextManager():
          return True
  test()
  --&gt; Good bye
  --&gt; True
  </code></pre>
  
  <p>Note that it doesn't matter if we don't return anything inside the <code>test()</code> function.</p>
  
  <p>This leads me to my question:</p>
  
  <ul>
  <li>Is it impossible to return a value from inside <code>__exit__</code> and if so, why?</li>
  </ul>