[New-bugs-announce] [issue22374] Replace contextmanager example and improve explanation

Terry J. Reedy report at bugs.python.org
Tue Sep 9 22:58:12 CEST 2014


New submission from Terry J. Reedy:

https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager
The current html contextmanager example is 'not recommended' for actual use, because there are better ways to accomplish the same goal.  To me, is also unsatifactory in that the context management is only metaphorical (conceptual) and not actual.

I propose the following as a replacement. It actually manages context and is, I believe, both useful and currently* the best way to accomplish the goal of temporarily monkeypatching a module,  It was directly inspired by #20752, see msg226657, though there have been other issues where monkeypatching as a solution has been discussed.

---
from contextlib import contextmanager
import itertools as its

@contextmanager
def mp(ob, attr, new):
    old = getattr(ob, attr)
    setattr(ob, attr, new)
    yield
    setattr(ob, attr, old)

def f(): pass

print(its.count, its.cycle)
with mp(its, 'count', f), mp(its, 'cycle', f):
    print(its.count, its.cycle)
print(its.count, its.cycle)

# <class 'itertools.count'>
# <function f at 0x00000000035A91E0>
# <class 'itertools.count'>
---

I am aware that the above does not follow the current style, which I dislike, of confusingly mixing together batch file code and interactive input code.  I think the above is how the example should be written.  It would work even better if Sphinx gave comment lines a different background color. (A '##' prefix could be used to differentiate code comments from commented-out output lines.)

In the same section, I find the following paragraph a bit confusing (perhaps is tries to say too much):

"contextmanager() uses ContextDecorator so the context managers it creates can be used as decorators as well as in with statements. When used as a decorator, a new generator instance is implicitly created on each function call (this allows the otherwise “one-shot” context managers created by contextmanager() to meet the requirement that context managers support multiple invocations in order to be used as decorators)."

I am guessing that this means, among other things, that ContextDecorator is necessary and sufficient to use mp twice in one with statement.  I intentionally added the double use to the example to make this possibility clear.

* The only better way I know of would be if mp (spelled out as 'monkeypatch' were considered useful enough to be added to contextlib.

----------
assignee: docs at python
components: Documentation
messages: 226661
nosy: docs at python, ncoghlan, terry.reedy
priority: normal
severity: normal
status: open
title: Replace contextmanager example and improve explanation
versions: Python 2.7, Python 3.4, Python 3.5

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue22374>
_______________________________________


More information about the New-bugs-announce mailing list