summaryrefslogtreecommitdiffstats
path: root/Doc/lib/libcontextlib.tex
diff options
context:
space:
mode:
authorThomas Wouters <thomas@python.org>2006-04-21 10:40:58 (GMT)
committerThomas Wouters <thomas@python.org>2006-04-21 10:40:58 (GMT)
commit49fd7fa4431da299196d74087df4a04f99f9c46f (patch)
tree35ace5fe78d3d52c7a9ab356ab9f6dbf8d4b71f4 /Doc/lib/libcontextlib.tex
parent9ada3d6e29d5165dadacbe6be07bcd35cfbef59d (diff)
downloadcpython-49fd7fa4431da299196d74087df4a04f99f9c46f.zip
cpython-49fd7fa4431da299196d74087df4a04f99f9c46f.tar.gz
cpython-49fd7fa4431da299196d74087df4a04f99f9c46f.tar.bz2
Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
number of tests, all because of the codecs/_multibytecodecs issue described here (it's not a Py3K issue, just something Py3K discovers): http://mail.python.org/pipermail/python-dev/2006-April/064051.html Hye-Shik Chang promised to look for a fix, so no need to fix it here. The tests that are expected to break are: test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecs test_multibytecodec This merge fixes an actual test failure (test_weakref) in this branch, though, so I believe merging is the right thing to do anyway.
Diffstat (limited to 'Doc/lib/libcontextlib.tex')
-rw-r--r--Doc/lib/libcontextlib.tex144
1 files changed, 144 insertions, 0 deletions
diff --git a/Doc/lib/libcontextlib.tex b/Doc/lib/libcontextlib.tex
new file mode 100644
index 0000000..46f9cdd
--- /dev/null
+++ b/Doc/lib/libcontextlib.tex
@@ -0,0 +1,144 @@
+\section{\module{contextlib} ---
+ Utilities for \keyword{with}-statement contexts.}
+
+\declaremodule{standard}{contextlib}
+\modulesynopsis{Utilities for \keyword{with}-statement contexts.}
+
+\versionadded{2.5}
+
+This module provides utilities for common tasks involving the
+\keyword{with} statement.
+
+Functions provided:
+
+\begin{funcdesc}{contextmanager}{func}
+This function is a decorator that can be used to define context managers
+for use with the \keyword{with} statement, without needing to create a
+class or separate \method{__enter__()} and \method{__exit__()} methods.
+
+A simple example:
+
+\begin{verbatim}
+from __future__ import with_statement
+from contextlib import contextmanager
+
+@contextmanager
+def tag(name):
+ print "<%s>" % name
+ yield
+ print "</%s>" % name
+
+>>> with tag("h1"):
+... print "foo"
+...
+<h1>
+foo
+</h1>
+\end{verbatim}
+
+When called, the decorated function must return a generator-iterator.
+This iterator must yield exactly one value, which will be bound to the
+targets in the \keyword{with} statement's \keyword{as} clause, if any.
+
+At the point where the generator yields, the block nested in the
+\keyword{with} statement is executed. The generator is then resumed
+after the block is exited. If an unhandled exception occurs in the
+block, it is reraised inside the generator at the point where the yield
+occurred. Thus, you can use a
+\keyword{try}...\keyword{except}...\keyword{finally} statement to trap
+the error (if any), or ensure that some cleanup takes place.
+
+Note that you can use \code{@contextmanager} to define a context
+manager's \method{__context__} method. This is usually more convenient
+than creating another class just to serve as a context. For example:
+
+\begin{verbatim}
+from __future__ import with_statement
+from contextlib import contextmanager
+
+class Tag:
+ def __init__(self, name):
+ self.name = name
+
+ @contextmanager
+ def __context__(self):
+ print "<%s>" % self.name
+ yield self
+ print "</%s>" % self.name
+
+h1 = Tag("h1")
+
+>>> with h1 as me:
+... print "hello from", me
+<h1>
+hello from <__main__.Tag instance at 0x402ce8ec>
+</h1>
+\end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{nested}{ctx1\optional{, ctx2\optional{, ...}}}
+Combine multiple context managers into a single nested context manager.
+
+Code like this:
+
+\begin{verbatim}
+from contextlib import nested
+
+with nested(A, B, C) as (X, Y, Z):
+ do_something()
+\end{verbatim}
+
+is equivalent to this:
+
+\begin{verbatim}
+with A as X:
+ with B as Y:
+ with C as Z:
+ do_something()
+\end{verbatim}
+
+Note that if one of the nested contexts' \method{__exit__()} method
+raises an exception, any previous exception state will be lost; the new
+exception will be passed to the outer contexts' \method{__exit__()}
+method(s), if any. In general, \method{__exit__()} methods should avoid
+raising exceptions, and in particular they should not re-raise a
+passed-in exception.
+\end{funcdesc}
+
+\label{context-closing}
+\begin{funcdesc}{closing}{thing}
+Return a context manager that closes \var{thing} upon completion of the
+block. This is basically equivalent to:
+
+\begin{verbatim}
+from contextlib import contextmanager
+
+@contextmanager
+def closing(thing):
+ try:
+ yield thing
+ finally:
+ thing.close()
+\end{verbatim}
+
+And lets you write code like this:
+\begin{verbatim}
+from __future__ import with_statement
+from contextlib import closing
+import codecs
+
+with closing(codecs.open("foo", encoding="utf8")) as f:
+ for line in f:
+ print line.encode("latin1")
+\end{verbatim}
+
+without needing to explicitly close \code{f}. Even if an error occurs,
+\code{f.close()} will be called when the \keyword{with} block is exited.
+
+\end{funcdesc}
+
+\begin{seealso}
+ \seepep{0343}{The "with" statement}
+ {The specification, background, and examples for the
+ Python \keyword{with} statement.}
+\end{seealso}