classification
Title: contextlib.closing documentation should use a new example
Type: Stage:
Components: Documentation Versions: Python 3.6, Python 3.4, Python 3.5
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: abarnert, docs@python, martin.panter, mjpieters, rhettinger
Priority: normal Keywords:

Created on 2014-10-28 22:40 by mjpieters, last changed 2014-11-01 07:08 by rhettinger.

Messages (4)
msg230184 - (view) Author: Martijn Pieters (mjpieters) * Date: 2014-10-28 22:40
urllib.request.urlopen() now always produces a context manager (either a HTTPResponse or addinfourl object). The example for contextlib.closing still uses urllib.request.urlopen as an example for the context manager wrapper, see

    https://docs.python.org/3/library/contextlib.html#contextlib.closing

This is confusing users that now expect the object not to be a context manager, see:

    http://stackoverflow.com/questions/26619404/with-and-closing-of-files-in-python

Can a different example be chosen?
msg230185 - (view) Author: Andrew Barnert (abarnert) * Date: 2014-10-28 23:02
It may be pretty hard to come up with a good example for closing in the stdlib that shouldn't just be turned into a context manager… 

There are some types where using it in a with statement is sensible, but unusual enough that you might want to make it explicit (maybe logging.Handler?), but does that make a good example?
msg230186 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2014-10-28 23:07
One exception that comes to mind is generators. According to Issue 13814, it is deliberate that you have to call close(), so perhaps someone could come up with an example based on that.
msg230430 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2014-11-01 07:08
> Can a different example be chosen?

The traditional examples (urllib, socket, StringIO) grow context manager support as soon as the need becomes apparent.  So, that leaves only user-defined classes, third-party classes, generators, and cases where we already have a competing context manager that does something other than close.

A reasonable candidate is an sqlite connection.  It is a legitimate use case for contextlib.closing() since connections need to be closed after use, and because they already are context managers that do something different than closing (the commit or rollback transactions).

A generator example would work, but closing generators is a rare and esoteric need (not many people even realize than you *can* close a generator), so this would make a bad example.

A user defined class can add its own __enter__ and __exit__ to close if needed, so it isn't common to use contextlib.closing() on your own classes.   The primary use case is for third-party classes where you don't control the source code and a closing context manager isn't present; however, those make for bad examples because they aren't in the standard library (i.e. aren't familiar) and because the better maintained modules are also adding context manager support.

Out of all of these, only the sqlite connection example seems to be durable (won't go away) and familiar (in the standard library and not an exotic feature).

That said, I think it would be best to stick with the simplest and most familiar possible examples even if they are no longer needed.   The purpose of the example is to show how closing() works.  We can use the surrounding text to indicate that the example is no longer necessary and that the most common remain uses are to add closing() behavior to third-party code you don't control (if you do control the code, then adding CM support directly to the class would be preferable).
History
Date User Action Args
2014-11-01 07:08:57rhettingersetnosy: + rhettinger
messages: + msg230430
2014-10-28 23:07:44martin.pantersetnosy: + martin.panter
messages: + msg230186
2014-10-28 23:02:16abarnertsetnosy: + abarnert
messages: + msg230185
2014-10-28 22:40:52mjpieterscreate