blob: 7f07b376e00be1b7046f513a7c92ea9fd611656b [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
Nick Coghlane708cf52006-04-25 11:05:56 +000014\begin{funcdesc}{context}{func}
Nick Coghlana7e820a2006-04-25 10:56:51 +000015This function is a decorator that can be used to define a factory
16function for \keyword{with} statement context objects, without
17needing to create a class or separate \method{__enter__()} and
18\method{__exit__()} methods.
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +000019
20A simple example:
21
22\begin{verbatim}
23from __future__ import with_statement
Nick Coghlana7e820a2006-04-25 10:56:51 +000024from contextlib import contextfactory
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +000025
Nick Coghlana7e820a2006-04-25 10:56:51 +000026@contextfactory
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +000027def tag(name):
28 print "<%s>" % name
29 yield
30 print "</%s>" % name
31
32>>> with tag("h1"):
33... print "foo"
34...
35<h1>
36foo
37</h1>
38\end{verbatim}
39
Nick Coghlana7e820a2006-04-25 10:56:51 +000040The function being decorated must return a generator-iterator when
41called. This iterator must yield exactly one value, which will be
42bound to the targets in the \keyword{with} statement's \keyword{as}
43clause, if any.
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +000044
45At the point where the generator yields, the block nested in the
46\keyword{with} statement is executed. The generator is then resumed
47after the block is exited. If an unhandled exception occurs in the
48block, it is reraised inside the generator at the point where the yield
49occurred. Thus, you can use a
50\keyword{try}...\keyword{except}...\keyword{finally} statement to trap
Nick Coghlan877cf232006-04-24 04:17:02 +000051the error (if any), or ensure that some cleanup takes place. If an
52exception is trapped merely in order to log it or to perform some
53action (rather than to suppress it entirely), the generator must
54reraise that exception. Otherwise the \keyword{with} statement will
55treat the exception as having been handled, and resume execution with
56the statement immediately following the \keyword{with} statement.
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +000057
Nick Coghlana7e820a2006-04-25 10:56:51 +000058Note that you can use \code{@contextfactory} to define a context
59manager's \method{__context__} method. This is usually more
Nick Coghlan877cf232006-04-24 04:17:02 +000060convenient than creating another class just to serve as a context
Nick Coghlana7e820a2006-04-25 10:56:51 +000061object. For example:
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +000062
63\begin{verbatim}
64from __future__ import with_statement
Nick Coghlana7e820a2006-04-25 10:56:51 +000065from contextlib import contextfactory
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +000066
67class Tag:
68 def __init__(self, name):
69 self.name = name
70
Nick Coghlana7e820a2006-04-25 10:56:51 +000071 @contextfactory
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +000072 def __context__(self):
73 print "<%s>" % self.name
74 yield self
75 print "</%s>" % self.name
76
77h1 = Tag("h1")
78
79>>> with h1 as me:
80... print "hello from", me
81<h1>
82hello from <__main__.Tag instance at 0x402ce8ec>
83</h1>
84\end{verbatim}
85\end{funcdesc}
86
87\begin{funcdesc}{nested}{ctx1\optional{, ctx2\optional{, ...}}}
Nick Coghlana7e820a2006-04-25 10:56:51 +000088Combine multiple context managers into a single nested context manager.
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +000089
90Code like this:
91
92\begin{verbatim}
93from contextlib import nested
94
95with nested(A, B, C) as (X, Y, Z):
96 do_something()
97\end{verbatim}
98
99is equivalent to this:
100
101\begin{verbatim}
102with A as X:
103 with B as Y:
104 with C as Z:
105 do_something()
106\end{verbatim}
107
Nick Coghlan877cf232006-04-24 04:17:02 +0000108Note that if the \method{__exit__()} method of one of the nested
Nick Coghlana7e820a2006-04-25 10:56:51 +0000109context objects indicates an exception should be suppressed, no
Nick Coghlan877cf232006-04-24 04:17:02 +0000110exception information will be passed to any remaining outer context
Nick Coghlana7e820a2006-04-25 10:56:51 +0000111objects. Similarly, if the \method{__exit__()} method of one of the
112nested context objects raises an exception, any previous exception
Nick Coghlan877cf232006-04-24 04:17:02 +0000113state will be lost; the new exception will be passed to the
Nick Coghlana7e820a2006-04-25 10:56:51 +0000114\method{__exit__()} methods of any remaining outer context objects.
Nick Coghlan877cf232006-04-24 04:17:02 +0000115In general, \method{__exit__()} methods should avoid raising
116exceptions, and in particular they should not re-raise a
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +0000117passed-in exception.
118\end{funcdesc}
119
120\label{context-closing}
121\begin{funcdesc}{closing}{thing}
Nick Coghlana7e820a2006-04-25 10:56:51 +0000122Return a context that closes \var{thing} upon completion of the
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +0000123block. This is basically equivalent to:
124
125\begin{verbatim}
Nick Coghlana7e820a2006-04-25 10:56:51 +0000126from contextlib import contextfactory
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +0000127
Nick Coghlana7e820a2006-04-25 10:56:51 +0000128@contextfactory
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +0000129def closing(thing):
130 try:
131 yield thing
132 finally:
133 thing.close()
134\end{verbatim}
135
136And lets you write code like this:
137\begin{verbatim}
Phillip J. Ebybdfd6932006-03-28 00:08:22 +0000138from __future__ import with_statement
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +0000139from contextlib import closing
Phillip J. Ebybdfd6932006-03-28 00:08:22 +0000140import codecs
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +0000141
Nick Coghlana7e820a2006-04-25 10:56:51 +0000142with closing(urllib.urlopen('http://www.python.org')) as page:
143 for line in page:
Nick Coghlan5ef9d9f2006-04-23 15:14:37 +0000144 print line
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +0000145\end{verbatim}
146
Nick Coghlana7e820a2006-04-25 10:56:51 +0000147without needing to explicitly close \code{page}. Even if an error
148occurs, \code{page.close()} will be called when the \keyword{with}
149block is exited.
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +0000150
Nick Coghlana7e820a2006-04-25 10:56:51 +0000151Context managers with a close method can use this context factory
152directly without needing to implement their own
153\method{__context__()} method.
154\begin{verbatim}
155from __future__ import with_statement
156from contextlib import closing
157
158class MyClass:
159 def close(self):
160 print "Closing", self
161 __context__ = closing
162
163>>> with MyClass() as x:
164... print "Hello from", x
165...
166Hello from <__main__.MyClass instance at 0xb7df02ec>
167Closing <__main__.MyClass instance at 0xb7df02ec>
168\end{verbatim}
Phillip J. Ebyd207b4f2006-03-27 23:58:46 +0000169\end{funcdesc}
170
171\begin{seealso}
172 \seepep{0343}{The "with" statement}
173 {The specification, background, and examples for the
174 Python \keyword{with} statement.}
175\end{seealso}