blob: 2a9eb0e666f45ca77094d5b4ce0dd761d6e948f4 [file] [log] [blame]
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +00001\section{\module{contextlib} ---
2 Utilities for \keyword{with}-statement contexts.}
3
4\declaremodule{standard}{contextlib}
5\modulesynopsis{Utilities for \keyword{with}-statement contexts.}
6
Neal Norwitzd03b0732006-03-28 05:51:02 +00007\versionadded{2.5}
8
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +00009This module provides utilities for common tasks involving the
10\keyword{with} statement.
11
12Functions provided:
13
14\begin{funcdesc}{contextmanager}{func}
15This function is a decorator that can be used to define context managers
16for use with the \keyword{with} statement, without needing to create a
17class or separate \method{__enter__()} and \method{__exit__()} methods.
18
19A simple example:
20
21\begin{verbatim}
22from __future__ import with_statement
23from contextlib import contextmanager
24
25@contextmanager
26def tag(name):
27 print "<%s>" % name
28 yield
29 print "</%s>" % name
30
31>>> with tag("h1"):
32... print "foo"
33...
34<h1>
35foo
36</h1>
37\end{verbatim}
38
39When called, the decorated function must return a generator-iterator.
40This iterator must yield exactly one value, which will be bound to the
41targets in the \keyword{with} statement's \keyword{as} clause, if any.
42
43At the point where the generator yields, the block nested in the
44\keyword{with} statement is executed. The generator is then resumed
45after the block is exited. If an unhandled exception occurs in the
46block, it is reraised inside the generator at the point where the yield
47occurred. Thus, you can use a
48\keyword{try}...\keyword{except}...\keyword{finally} statement to trap
Nick Coghlan877cf232006-04-24 04:17:02 +000049the error (if any), or ensure that some cleanup takes place. If an
50exception is trapped merely in order to log it or to perform some
51action (rather than to suppress it entirely), the generator must
52reraise that exception. Otherwise the \keyword{with} statement will
53treat the exception as having been handled, and resume execution with
54the statement immediately following the \keyword{with} statement.
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +000055
56Note that you can use \code{@contextmanager} to define a context
Nick Coghlan877cf232006-04-24 04:17:02 +000057specifier's \method{__context__} method. This is usually more
58convenient than creating another class just to serve as a context
59manager. For example:
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +000060
61\begin{verbatim}
62from __future__ import with_statement
63from contextlib import contextmanager
64
65class Tag:
66 def __init__(self, name):
67 self.name = name
68
69 @contextmanager
70 def __context__(self):
71 print "<%s>" % self.name
72 yield self
73 print "</%s>" % self.name
74
75h1 = Tag("h1")
76
77>>> with h1 as me:
78... print "hello from", me
79<h1>
80hello from <__main__.Tag instance at 0x402ce8ec>
81</h1>
82\end{verbatim}
83\end{funcdesc}
84
85\begin{funcdesc}{nested}{ctx1\optional{, ctx2\optional{, ...}}}
Nick Coghlan877cf232006-04-24 04:17:02 +000086Combine multiple context specifiers into a single nested context manager.
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +000087
88Code like this:
89
90\begin{verbatim}
91from contextlib import nested
92
93with nested(A, B, C) as (X, Y, Z):
94 do_something()
95\end{verbatim}
96
97is equivalent to this:
98
99\begin{verbatim}
100with A as X:
101 with B as Y:
102 with C as Z:
103 do_something()
104\end{verbatim}
105
Nick Coghlan877cf232006-04-24 04:17:02 +0000106Note that if the \method{__exit__()} method of one of the nested
107context managers indicates an exception should be suppressed, no
108exception information will be passed to any remaining outer context
109managers. Similarly, if the \method{__exit__()} method of one of the
110nested context managers raises an exception, any previous exception
111state will be lost; the new exception will be passed to the
112\method{__exit__()} methods of any remaining outer context managers.
113In general, \method{__exit__()} methods should avoid raising
114exceptions, and in particular they should not re-raise a
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +0000115passed-in exception.
116\end{funcdesc}
117
118\label{context-closing}
119\begin{funcdesc}{closing}{thing}
120Return a context manager that closes \var{thing} upon completion of the
121block. This is basically equivalent to:
122
123\begin{verbatim}
124from contextlib import contextmanager
125
126@contextmanager
127def closing(thing):
128 try:
129 yield thing
130 finally:
131 thing.close()
132\end{verbatim}
133
134And lets you write code like this:
135\begin{verbatim}
Phillip J. Ebybdfd6932006-03-28 00:08:22 +0000136from __future__ import with_statement
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +0000137from contextlib import closing
Phillip J. Ebybdfd6932006-03-28 00:08:22 +0000138import codecs
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +0000139
Nick Coghlan5ef9d9f2006-04-23 15:14:37 +0000140with closing(urllib.urlopen('http://www.python.org')) as f:
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +0000141 for line in f:
Nick Coghlan5ef9d9f2006-04-23 15:14:37 +0000142 print line
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +0000143\end{verbatim}
144
145without needing to explicitly close \code{f}. Even if an error occurs,
146\code{f.close()} will be called when the \keyword{with} block is exited.
147
148\end{funcdesc}
149
150\begin{seealso}
151 \seepep{0343}{The "with" statement}
152 {The specification, background, and examples for the
153 Python \keyword{with} statement.}
154\end{seealso}