blob: bac9d13736210b13e338dace6365ea101e5468c9 [file] [log] [blame]
Georg Brandl0eaab972009-06-08 08:00:22 +00001:mod:`contextlib` --- Utilities for :keyword:`with`\ -statement contexts
2========================================================================
Georg Brandl116aa622007-08-15 14:28:22 +00003
4.. module:: contextlib
5 :synopsis: Utilities for with-statement contexts.
6
7
Georg Brandl116aa622007-08-15 14:28:22 +00008This module provides utilities for common tasks involving the :keyword:`with`
9statement. For more information see also :ref:`typecontextmanager` and
10:ref:`context-managers`.
11
12Functions provided:
13
14
15.. function:: contextmanager(func)
16
Christian Heimesd8654cf2007-12-02 15:22:16 +000017 This function is a :term:`decorator` that can be used to define a factory
18 function for :keyword:`with` statement context managers, without needing to
19 create a class or separate :meth:`__enter__` and :meth:`__exit__` methods.
Georg Brandl116aa622007-08-15 14:28:22 +000020
21 A simple example (this is not recommended as a real way of generating HTML!)::
22
Georg Brandl116aa622007-08-15 14:28:22 +000023 from contextlib import contextmanager
24
25 @contextmanager
26 def tag(name):
Georg Brandl6911e3c2007-09-04 07:15:32 +000027 print("<%s>" % name)
Georg Brandl116aa622007-08-15 14:28:22 +000028 yield
Georg Brandl6911e3c2007-09-04 07:15:32 +000029 print("</%s>" % name)
Georg Brandl116aa622007-08-15 14:28:22 +000030
31 >>> with tag("h1"):
Georg Brandl6911e3c2007-09-04 07:15:32 +000032 ... print("foo")
Georg Brandl116aa622007-08-15 14:28:22 +000033 ...
34 <h1>
35 foo
36 </h1>
37
Georg Brandl9afde1c2007-11-01 20:32:30 +000038 The function being decorated must return a :term:`generator`-iterator when
39 called. This iterator must yield exactly one value, which will be bound to
40 the targets in the :keyword:`with` statement's :keyword:`as` clause, if any.
Georg Brandl116aa622007-08-15 14:28:22 +000041
42 At the point where the generator yields, the block nested in the :keyword:`with`
43 statement is executed. The generator is then resumed after the block is exited.
44 If an unhandled exception occurs in the block, it is reraised inside the
45 generator at the point where the yield occurred. Thus, you can use a
46 :keyword:`try`...\ :keyword:`except`...\ :keyword:`finally` statement to trap
47 the error (if any), or ensure that some cleanup takes place. If an exception is
48 trapped merely in order to log it or to perform some action (rather than to
49 suppress it entirely), the generator must reraise that exception. Otherwise the
50 generator context manager will indicate to the :keyword:`with` statement that
51 the exception has been handled, and execution will resume with the statement
52 immediately following the :keyword:`with` statement.
53
54
55.. function:: nested(mgr1[, mgr2[, ...]])
56
57 Combine multiple context managers into a single nested context manager.
58
59 Code like this::
60
61 from contextlib import nested
62
Benjamin Petersonf07d0022009-03-21 17:31:58 +000063 with nested(A(), B(), C()) as (X, Y, Z):
Georg Brandl116aa622007-08-15 14:28:22 +000064 do_something()
65
66 is equivalent to this::
67
Benjamin Petersonf07d0022009-03-21 17:31:58 +000068 m1, m2, m3 = A(), B(), C()
69 with m1 as X:
70 with m2 as Y:
71 with m3 as Z:
Georg Brandl116aa622007-08-15 14:28:22 +000072 do_something()
73
74 Note that if the :meth:`__exit__` method of one of the nested context managers
75 indicates an exception should be suppressed, no exception information will be
76 passed to any remaining outer context managers. Similarly, if the
77 :meth:`__exit__` method of one of the nested managers raises an exception, any
78 previous exception state will be lost; the new exception will be passed to the
79 :meth:`__exit__` methods of any remaining outer context managers. In general,
80 :meth:`__exit__` methods should avoid raising exceptions, and in particular they
81 should not re-raise a passed-in exception.
82
Raymond Hettinger91e3b9d2009-05-28 22:20:03 +000083 .. deprecated:: 3.1
84 The with-statement now supports this functionality directly.
Georg Brandl116aa622007-08-15 14:28:22 +000085
86.. function:: closing(thing)
87
88 Return a context manager that closes *thing* upon completion of the block. This
89 is basically equivalent to::
90
91 from contextlib import contextmanager
92
93 @contextmanager
94 def closing(thing):
95 try:
96 yield thing
97 finally:
98 thing.close()
99
100 And lets you write code like this::
101
Georg Brandl116aa622007-08-15 14:28:22 +0000102 from contextlib import closing
Georg Brandl0f7ede42008-06-23 11:23:31 +0000103 from urllib.request import urlopen
Georg Brandl116aa622007-08-15 14:28:22 +0000104
Georg Brandl0f7ede42008-06-23 11:23:31 +0000105 with closing(urlopen('http://www.python.org')) as page:
Georg Brandl116aa622007-08-15 14:28:22 +0000106 for line in page:
Georg Brandl6911e3c2007-09-04 07:15:32 +0000107 print(line)
Georg Brandl116aa622007-08-15 14:28:22 +0000108
109 without needing to explicitly close ``page``. Even if an error occurs,
110 ``page.close()`` will be called when the :keyword:`with` block is exited.
111
112
113.. seealso::
114
115 :pep:`0343` - The "with" statement
116 The specification, background, and examples for the Python :keyword:`with`
117 statement.
118