This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Add try-finally contextlib.contextmanager example
Type: enhancement Stage: resolved
Components: Documentation Versions: Python 3.8, Python 3.7, Python 3.6, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: ncoghlan Nosy List: mbussonn, ncoghlan, petr.viktorin, serhiy.storchaka, taleinat
Priority: normal Keywords: patch

Created on 2018-05-11 22:31 by ncoghlan, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 7816 merged mbussonn, 2018-06-20 08:06
PR 8425 merged miss-islington, 2018-07-23 21:11
PR 8426 merged miss-islington, 2018-07-23 21:12
PR 8427 merged taleinat, 2018-07-23 21:18
Messages (12)
msg316416 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2018-05-11 22:31
The current example for contextlib.contextmanager doesn't use try/finally, which sets folks up for writing resource management context managers that don't clean up after exceptions properly.

There's an example with try/finally down in the contextlib.closing docs, but I'm thinking it would be worthwhile to change the presentation of contextmanager itself.
msg320035 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-06-20 08:19
It doesn't look as a good example. It is not always good to write a closing tag if an error was occurred while write an inner content. In many cases it is better to stop writing after error.
msg320069 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2018-06-20 11:23
Right, the HTML example was always a bit cutesy (hence the disclaimer in the header), but it's hard to come up with a good illustrative example that isn't already a native context manager in the standard library.

Perhaps it would make sense to change the example text completely, and write something entirely abstract like:

    from contextlib import contextmanager

    @contextmanager
    def managed_resource(*args, **kwds):
        # Code to acquire resource, e.g.:
        resource = acquire_resource(*args, **kwds)
        try:
            yield resource
        finally:
             # Code to release resource, e.g.:
             release_resource(resource)

    >>> with managed_resource(*args, **kwds) as resource:
    ...     # Resource is released at the end of this block,
    ...     # even if code in the block raises an exception

Then the introductory text could be updated to say something like "While many objects natively support use in with statements, sometimes a resource needs to be managed that isn't a context manager in its own right, and doesn't implement a ``close()`` method for use with ``contextlib.closing``.".
msg320365 - (view) Author: Tal Einat (taleinat) * (Python committer) Date: 2018-06-24 08:13
A possible concrete example: Capturing sys.stdout and/or sys.stderr for testing, as in test.support.captured_output.
msg320367 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2018-06-24 09:05
Similar to closing, we have dedicated context managers for stdout and stderr redirection now: https://docs.python.org/3/library/contextlib.html#contextlib.redirect_stdout

Redirecting stdin could be a good example though, since we've so far chosen not to provide a standard context manager for that (it's a sufficiently uncommon use case that we haven't seen the need to add it directly).
msg320369 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-06-24 12:05
The entirely abstract example LGTM.

As for concrete real word examples, the possible one is changing the current working directory:

    cwd = os.getcwd()
    try:
        os.chdir(target_dir)
        yield
    finally:
        os.chdir(cwd)
msg320781 - (view) Author: Tal Einat (taleinat) * (Python committer) Date: 2018-06-30 13:38
Nick's abstract example LGTM as well.
msg322258 - (view) Author: Tal Einat (taleinat) * (Python committer) Date: 2018-07-23 21:10
New changeset bde782bb594edffeabe978abeee2b7082ab9bc2a by Tal Einat (Matthias Bussonnier) in branch 'master':
bpo-33468: Add try-finally contextlib.contextmanager example (GH-7816)
https://github.com/python/cpython/commit/bde782bb594edffeabe978abeee2b7082ab9bc2a
msg322261 - (view) Author: Tal Einat (taleinat) * (Python committer) Date: 2018-07-23 21:38
New changeset 4e166ffd29b675238ccd94964743f6cb206d2235 by Tal Einat (Miss Islington (bot)) in branch '3.7':
bpo-33468: Add try-finally contextlib.contextmanager example (GH-7816) (GH-8425)
https://github.com/python/cpython/commit/4e166ffd29b675238ccd94964743f6cb206d2235
msg322262 - (view) Author: Tal Einat (taleinat) * (Python committer) Date: 2018-07-23 21:38
New changeset 5b3643d1a5114551350a9d17fb0aaab2d503c290 by Tal Einat (Miss Islington (bot)) in branch '3.6':
bpo-33468: Add try-finally contextlib.contextmanager example (GH-7816) (GH-8426)
https://github.com/python/cpython/commit/5b3643d1a5114551350a9d17fb0aaab2d503c290
msg322263 - (view) Author: Tal Einat (taleinat) * (Python committer) Date: 2018-07-23 21:38
New changeset f7e60a69485097dc28f000c55615038278f84333 by Tal Einat in branch '2.7':
[2.7] bpo-33468: Add try-finally contextlib.contextmanager example (GH-7816) (GH-8427)
https://github.com/python/cpython/commit/f7e60a69485097dc28f000c55615038278f84333
msg322264 - (view) Author: Tal Einat (taleinat) * (Python committer) Date: 2018-07-23 21:41
Thanks for the PR, Matthias Bussonnier!
History
Date User Action Args
2022-04-11 14:59:00adminsetgithub: 77649
2018-07-26 05:37:12berker.peksaglinkissue22374 superseder
2018-07-23 21:41:42taleinatsetstatus: open -> closed

versions: + Python 2.7
nosy: + mbussonn

messages: + msg322264
resolution: fixed
stage: patch review -> resolved
2018-07-23 21:38:36taleinatsetmessages: + msg322263
2018-07-23 21:38:26taleinatsetmessages: + msg322262
2018-07-23 21:38:21taleinatsetmessages: + msg322261
2018-07-23 21:18:21taleinatsetpull_requests: + pull_request7953
2018-07-23 21:12:08miss-islingtonsetpull_requests: + pull_request7952
2018-07-23 21:11:06miss-islingtonsetpull_requests: + pull_request7951
2018-07-23 21:10:58taleinatsetmessages: + msg322258
2018-06-30 13:38:53taleinatsetmessages: + msg320781
2018-06-24 12:05:39serhiy.storchakasetmessages: + msg320369
2018-06-24 09:06:00ncoghlansetmessages: + msg320367
2018-06-24 08:13:30taleinatsetnosy: + taleinat
messages: + msg320365
2018-06-20 11:23:01ncoghlansetmessages: + msg320069
2018-06-20 08:19:00serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg320035
2018-06-20 08:06:24mbussonnsetkeywords: + patch
stage: needs patch -> patch review
pull_requests: + pull_request7424
2018-05-20 16:34:16petr.viktorinsetnosy: + petr.viktorin
2018-05-11 22:31:27ncoghlancreate