[Python-ideas] __enter__ and __exit__ on generators

Nathaniel Smith njs at pobox.com
Tue Jul 5 10:56:11 EDT 2016

Hi all,

This might be too trivial for python-ideas even, but... I recently stumbled
slightly over the way that generators define a close method (the one that
injects a GeneratorExit), but don't directly implement the context manager
protocol. So if you want a generator's internal resources to be cleaned up
promptly, you can't write

  with genfunc() as it:
      for obj in it:

but instead have to write

  with contextlib.closing(genfunc()) as it:
      for obj in it:

Is there any particular reason for this, or is it just an oversight?

(Why is it important to close generators? Consider a generator that holds
an open file descriptor:

  def genfunc():
      with open(...) as f:
          for line in f:
              yield ...

Python these days very much encourages you to use a "with" statement for
the file open, with ResourceWarnings and all that. But in this case, the
file won't be closed until someone calls generator.close(), so the with
statement above is only really effective if genfunc's caller also uses a
"with" statement. Unfortunately, having the "with" statement inside genfunc
*is* enough to unconditionally hide the ResourceWarning, even if it's
otherwise ineffective, because the warning is triggered when file.__del__
calls file.__close__, and here we have generator.__del__ calling

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160705/01fb3f11/attachment.html>

More information about the Python-ideas mailing list