blob: e8dc17fed324dc9e9537d49a5f57d213ec3fc05b [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
Raymond Hettinger10480942011-01-10 03:26:08 +00007**Source code:** :source:`Lib/contextlib.py`
Georg Brandl116aa622007-08-15 14:28:22 +00008
Raymond Hettinger4f707fd2011-01-10 19:54:11 +00009--------------
10
Georg Brandl116aa622007-08-15 14:28:22 +000011This module provides utilities for common tasks involving the :keyword:`with`
12statement. For more information see also :ref:`typecontextmanager` and
13:ref:`context-managers`.
14
15Functions provided:
16
17
Georg Brandl8a1caa22010-07-29 16:01:11 +000018.. decorator:: contextmanager
Georg Brandl116aa622007-08-15 14:28:22 +000019
Christian Heimesd8654cf2007-12-02 15:22:16 +000020 This function is a :term:`decorator` that can be used to define a factory
21 function for :keyword:`with` statement context managers, without needing to
22 create a class or separate :meth:`__enter__` and :meth:`__exit__` methods.
Georg Brandl116aa622007-08-15 14:28:22 +000023
24 A simple example (this is not recommended as a real way of generating HTML!)::
25
Georg Brandl116aa622007-08-15 14:28:22 +000026 from contextlib import contextmanager
27
28 @contextmanager
29 def tag(name):
Georg Brandl6911e3c2007-09-04 07:15:32 +000030 print("<%s>" % name)
Georg Brandl116aa622007-08-15 14:28:22 +000031 yield
Georg Brandl6911e3c2007-09-04 07:15:32 +000032 print("</%s>" % name)
Georg Brandl116aa622007-08-15 14:28:22 +000033
34 >>> with tag("h1"):
Georg Brandl6911e3c2007-09-04 07:15:32 +000035 ... print("foo")
Georg Brandl116aa622007-08-15 14:28:22 +000036 ...
37 <h1>
38 foo
39 </h1>
40
Georg Brandl9afde1c2007-11-01 20:32:30 +000041 The function being decorated must return a :term:`generator`-iterator when
42 called. This iterator must yield exactly one value, which will be bound to
43 the targets in the :keyword:`with` statement's :keyword:`as` clause, if any.
Georg Brandl116aa622007-08-15 14:28:22 +000044
45 At the point where the generator yields, the block nested in the :keyword:`with`
46 statement is executed. The generator is then resumed after the block is exited.
47 If an unhandled exception occurs in the block, it is reraised inside the
48 generator at the point where the yield occurred. Thus, you can use a
49 :keyword:`try`...\ :keyword:`except`...\ :keyword:`finally` statement to trap
50 the error (if any), or ensure that some cleanup takes place. If an exception is
51 trapped merely in order to log it or to perform some action (rather than to
52 suppress it entirely), the generator must reraise that exception. Otherwise the
53 generator context manager will indicate to the :keyword:`with` statement that
54 the exception has been handled, and execution will resume with the statement
55 immediately following the :keyword:`with` statement.
56
Nick Coghlan0ded3e32011-05-05 23:49:25 +100057 :func:`contextmanager` uses :class:`ContextDecorator` so the context managers
58 it creates can be used as decorators as well as in :keyword:`with` statements.
59 When used as a decorator, a new generator instance is implicitly created on
60 each function call (this allows the otherwise "one-shot" context managers
61 created by :func:`contextmanager` to meet the requirement that context
62 managers support multiple invocations in order to be used as decorators).
Michael Foordb3a89842010-06-30 12:17:50 +000063
64 .. versionchanged:: 3.2
65 Use of :class:`ContextDecorator`.
Georg Brandl116aa622007-08-15 14:28:22 +000066
Georg Brandl86e78d12010-07-18 13:43:32 +000067
Georg Brandl116aa622007-08-15 14:28:22 +000068.. function:: closing(thing)
69
70 Return a context manager that closes *thing* upon completion of the block. This
71 is basically equivalent to::
72
73 from contextlib import contextmanager
74
75 @contextmanager
76 def closing(thing):
77 try:
78 yield thing
79 finally:
80 thing.close()
81
82 And lets you write code like this::
83
Georg Brandl116aa622007-08-15 14:28:22 +000084 from contextlib import closing
Georg Brandl0f7ede42008-06-23 11:23:31 +000085 from urllib.request import urlopen
Georg Brandl116aa622007-08-15 14:28:22 +000086
Georg Brandl0f7ede42008-06-23 11:23:31 +000087 with closing(urlopen('http://www.python.org')) as page:
Georg Brandl116aa622007-08-15 14:28:22 +000088 for line in page:
Georg Brandl6911e3c2007-09-04 07:15:32 +000089 print(line)
Georg Brandl116aa622007-08-15 14:28:22 +000090
91 without needing to explicitly close ``page``. Even if an error occurs,
92 ``page.close()`` will be called when the :keyword:`with` block is exited.
93
94
Michael Foordb3a89842010-06-30 12:17:50 +000095.. class:: ContextDecorator()
96
97 A base class that enables a context manager to also be used as a decorator.
98
99 Context managers inheriting from ``ContextDecorator`` have to implement
100 ``__enter__`` and ``__exit__`` as normal. ``__exit__`` retains its optional
101 exception handling even when used as a decorator.
102
Georg Brandl86e78d12010-07-18 13:43:32 +0000103 ``ContextDecorator`` is used by :func:`contextmanager`, so you get this
104 functionality automatically.
105
106 Example of ``ContextDecorator``::
Michael Foordb3a89842010-06-30 12:17:50 +0000107
108 from contextlib import ContextDecorator
109
110 class mycontext(ContextDecorator):
Georg Brandl86e78d12010-07-18 13:43:32 +0000111 def __enter__(self):
112 print('Starting')
113 return self
Michael Foordb3a89842010-06-30 12:17:50 +0000114
Georg Brandl86e78d12010-07-18 13:43:32 +0000115 def __exit__(self, *exc):
116 print('Finishing')
117 return False
Michael Foordb3a89842010-06-30 12:17:50 +0000118
119 >>> @mycontext()
120 ... def function():
Georg Brandl86e78d12010-07-18 13:43:32 +0000121 ... print('The bit in the middle')
Michael Foordb3a89842010-06-30 12:17:50 +0000122 ...
123 >>> function()
124 Starting
125 The bit in the middle
126 Finishing
127
128 >>> with mycontext():
Georg Brandl86e78d12010-07-18 13:43:32 +0000129 ... print('The bit in the middle')
Michael Foordb3a89842010-06-30 12:17:50 +0000130 ...
131 Starting
132 The bit in the middle
133 Finishing
134
Georg Brandl86e78d12010-07-18 13:43:32 +0000135 This change is just syntactic sugar for any construct of the following form::
136
137 def f():
138 with cm():
139 # Do stuff
140
141 ``ContextDecorator`` lets you instead write::
142
143 @cm()
144 def f():
145 # Do stuff
146
147 It makes it clear that the ``cm`` applies to the whole function, rather than
148 just a piece of it (and saving an indentation level is nice, too).
149
Michael Foordb3a89842010-06-30 12:17:50 +0000150 Existing context managers that already have a base class can be extended by
151 using ``ContextDecorator`` as a mixin class::
152
153 from contextlib import ContextDecorator
154
155 class mycontext(ContextBaseClass, ContextDecorator):
Georg Brandl86e78d12010-07-18 13:43:32 +0000156 def __enter__(self):
157 return self
Michael Foordb3a89842010-06-30 12:17:50 +0000158
Georg Brandl86e78d12010-07-18 13:43:32 +0000159 def __exit__(self, *exc):
160 return False
Michael Foordb3a89842010-06-30 12:17:50 +0000161
Nick Coghlan0ded3e32011-05-05 23:49:25 +1000162 .. note::
163 As the decorated function must be able to be called multiple times, the
164 underlying context manager must support use in multiple :keyword:`with`
165 statements. If this is not the case, then the original construct with the
166 explicit :keyword:`with` statement inside the function should be used.
167
Michael Foordb3a89842010-06-30 12:17:50 +0000168 .. versionadded:: 3.2
169
170
Georg Brandl116aa622007-08-15 14:28:22 +0000171.. seealso::
172
173 :pep:`0343` - The "with" statement
174 The specification, background, and examples for the Python :keyword:`with`
175 statement.
176