title: Is it safe to combine 'with' and 'yield' in python?
body: <p>It's a common idiom in python to use context manager to automatically close files:</p>
  
  <pre><code>with open('filename') as my_file:
      # do something with my_file
  
  # my_file gets automatically closed after exiting 'with' block
  </code></pre>
  
  <p>Now I want to read contents of several files. Consumer of the data does not know or care if data comes from files or not-files. It does not want to check if the objects it received can be open or not. It just wants to get something to read lines from. So I create an iterator like this:</p>
  
  <pre><code>def select_files():
      """Yields carefully selected and ready-to-read-from files"""
      file_names = [.......]
      for fname in file_names:
          with open(fname) as my_open_file:
              yield my_open_file
  </code></pre>
  
  <p>This iterator may be used like this:</p>
  
  <pre><code>for file_obj in select_files():
      for line in file_obj:
          # do something useful
  </code></pre>
  
  <p>(Note, that the same code could be used to consume not the open files, but lists of strings - that's cool!)</p>
  
  <p><strong>The question is: is it safe to yield open files?</strong></p>
  
  <p>Looks like "why not?". Consumer calls iterator, iterator opens file, yields it to consumer. Consumer processes the file and comes back to iterator for next one. Iterator code resumes, we exit 'with' block, the <code>my_open_file</code> object gets closed, go to next file, etc.</p>
  
  <p>But what if consumer never comes back to iterator for the next file? F.e. an exception occurred inside the consumer. Or consumer found something very exciting in one of the files and happily returned the results to whoever called it?</p>
  
  <p>Iterator code would never resume in this case, we would never come to the end of 'with' block, and the <code>my_open_file</code> object would never get closed!</p>
  
  <p>Or would it?</p>