blob: f18c1005331804abdf52d329ce0c80ef12680d1d [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
Georg Brandl116aa622007-08-15 14:28:22 +000015
Nick Coghlan3267a302012-05-21 22:54:43 +100016Utilities
17---------
18
19Functions and classes provided:
Georg Brandl116aa622007-08-15 14:28:22 +000020
Georg Brandl8a1caa22010-07-29 16:01:11 +000021.. decorator:: contextmanager
Georg Brandl116aa622007-08-15 14:28:22 +000022
Christian Heimesd8654cf2007-12-02 15:22:16 +000023 This function is a :term:`decorator` that can be used to define a factory
24 function for :keyword:`with` statement context managers, without needing to
25 create a class or separate :meth:`__enter__` and :meth:`__exit__` methods.
Georg Brandl116aa622007-08-15 14:28:22 +000026
27 A simple example (this is not recommended as a real way of generating HTML!)::
28
Georg Brandl116aa622007-08-15 14:28:22 +000029 from contextlib import contextmanager
30
31 @contextmanager
32 def tag(name):
Georg Brandl6911e3c2007-09-04 07:15:32 +000033 print("<%s>" % name)
Georg Brandl116aa622007-08-15 14:28:22 +000034 yield
Georg Brandl6911e3c2007-09-04 07:15:32 +000035 print("</%s>" % name)
Georg Brandl116aa622007-08-15 14:28:22 +000036
37 >>> with tag("h1"):
Georg Brandl6911e3c2007-09-04 07:15:32 +000038 ... print("foo")
Georg Brandl116aa622007-08-15 14:28:22 +000039 ...
40 <h1>
41 foo
42 </h1>
43
Georg Brandl9afde1c2007-11-01 20:32:30 +000044 The function being decorated must return a :term:`generator`-iterator when
45 called. This iterator must yield exactly one value, which will be bound to
46 the targets in the :keyword:`with` statement's :keyword:`as` clause, if any.
Georg Brandl116aa622007-08-15 14:28:22 +000047
48 At the point where the generator yields, the block nested in the :keyword:`with`
49 statement is executed. The generator is then resumed after the block is exited.
50 If an unhandled exception occurs in the block, it is reraised inside the
51 generator at the point where the yield occurred. Thus, you can use a
52 :keyword:`try`...\ :keyword:`except`...\ :keyword:`finally` statement to trap
53 the error (if any), or ensure that some cleanup takes place. If an exception is
54 trapped merely in order to log it or to perform some action (rather than to
55 suppress it entirely), the generator must reraise that exception. Otherwise the
56 generator context manager will indicate to the :keyword:`with` statement that
57 the exception has been handled, and execution will resume with the statement
58 immediately following the :keyword:`with` statement.
59
Nick Coghlan0ded3e32011-05-05 23:49:25 +100060 :func:`contextmanager` uses :class:`ContextDecorator` so the context managers
61 it creates can be used as decorators as well as in :keyword:`with` statements.
62 When used as a decorator, a new generator instance is implicitly created on
63 each function call (this allows the otherwise "one-shot" context managers
64 created by :func:`contextmanager` to meet the requirement that context
65 managers support multiple invocations in order to be used as decorators).
Michael Foordb3a89842010-06-30 12:17:50 +000066
67 .. versionchanged:: 3.2
68 Use of :class:`ContextDecorator`.
Georg Brandl116aa622007-08-15 14:28:22 +000069
Georg Brandl86e78d12010-07-18 13:43:32 +000070
Georg Brandl116aa622007-08-15 14:28:22 +000071.. function:: closing(thing)
72
73 Return a context manager that closes *thing* upon completion of the block. This
74 is basically equivalent to::
75
76 from contextlib import contextmanager
77
78 @contextmanager
79 def closing(thing):
80 try:
81 yield thing
82 finally:
83 thing.close()
84
85 And lets you write code like this::
86
Georg Brandl116aa622007-08-15 14:28:22 +000087 from contextlib import closing
Georg Brandl0f7ede42008-06-23 11:23:31 +000088 from urllib.request import urlopen
Georg Brandl116aa622007-08-15 14:28:22 +000089
Georg Brandl0f7ede42008-06-23 11:23:31 +000090 with closing(urlopen('http://www.python.org')) as page:
Georg Brandl116aa622007-08-15 14:28:22 +000091 for line in page:
Georg Brandl6911e3c2007-09-04 07:15:32 +000092 print(line)
Georg Brandl116aa622007-08-15 14:28:22 +000093
94 without needing to explicitly close ``page``. Even if an error occurs,
95 ``page.close()`` will be called when the :keyword:`with` block is exited.
96
Raymond Hettingere318a882013-03-10 22:26:51 -070097.. function:: ignored(*exceptions)
98
Ned Deily05bdd852013-03-31 17:06:15 -070099 Return a context manager that ignores the specified exceptions if they
Raymond Hettingere318a882013-03-10 22:26:51 -0700100 occur in the body of a with-statement.
101
102 For example::
103
104 from contextlib import ignored
105
106 with ignored(OSError):
107 os.remove('somefile.tmp')
108
109 This code is equivalent to::
110
111 try:
112 os.remove('somefile.tmp')
113 except OSError:
114 pass
115
116 .. versionadded:: 3.4
Georg Brandl116aa622007-08-15 14:28:22 +0000117
Michael Foordb3a89842010-06-30 12:17:50 +0000118.. class:: ContextDecorator()
119
120 A base class that enables a context manager to also be used as a decorator.
121
122 Context managers inheriting from ``ContextDecorator`` have to implement
123 ``__enter__`` and ``__exit__`` as normal. ``__exit__`` retains its optional
124 exception handling even when used as a decorator.
125
Georg Brandl86e78d12010-07-18 13:43:32 +0000126 ``ContextDecorator`` is used by :func:`contextmanager`, so you get this
127 functionality automatically.
128
129 Example of ``ContextDecorator``::
Michael Foordb3a89842010-06-30 12:17:50 +0000130
131 from contextlib import ContextDecorator
132
133 class mycontext(ContextDecorator):
Georg Brandl86e78d12010-07-18 13:43:32 +0000134 def __enter__(self):
135 print('Starting')
136 return self
Michael Foordb3a89842010-06-30 12:17:50 +0000137
Georg Brandl86e78d12010-07-18 13:43:32 +0000138 def __exit__(self, *exc):
139 print('Finishing')
140 return False
Michael Foordb3a89842010-06-30 12:17:50 +0000141
142 >>> @mycontext()
143 ... def function():
Georg Brandl86e78d12010-07-18 13:43:32 +0000144 ... print('The bit in the middle')
Michael Foordb3a89842010-06-30 12:17:50 +0000145 ...
146 >>> function()
147 Starting
148 The bit in the middle
149 Finishing
150
151 >>> with mycontext():
Georg Brandl86e78d12010-07-18 13:43:32 +0000152 ... print('The bit in the middle')
Michael Foordb3a89842010-06-30 12:17:50 +0000153 ...
154 Starting
155 The bit in the middle
156 Finishing
157
Georg Brandl86e78d12010-07-18 13:43:32 +0000158 This change is just syntactic sugar for any construct of the following form::
159
160 def f():
161 with cm():
162 # Do stuff
163
164 ``ContextDecorator`` lets you instead write::
165
166 @cm()
167 def f():
168 # Do stuff
169
170 It makes it clear that the ``cm`` applies to the whole function, rather than
171 just a piece of it (and saving an indentation level is nice, too).
172
Michael Foordb3a89842010-06-30 12:17:50 +0000173 Existing context managers that already have a base class can be extended by
174 using ``ContextDecorator`` as a mixin class::
175
176 from contextlib import ContextDecorator
177
178 class mycontext(ContextBaseClass, ContextDecorator):
Georg Brandl86e78d12010-07-18 13:43:32 +0000179 def __enter__(self):
180 return self
Michael Foordb3a89842010-06-30 12:17:50 +0000181
Georg Brandl86e78d12010-07-18 13:43:32 +0000182 def __exit__(self, *exc):
183 return False
Michael Foordb3a89842010-06-30 12:17:50 +0000184
Nick Coghlan0ded3e32011-05-05 23:49:25 +1000185 .. note::
186 As the decorated function must be able to be called multiple times, the
187 underlying context manager must support use in multiple :keyword:`with`
188 statements. If this is not the case, then the original construct with the
189 explicit :keyword:`with` statement inside the function should be used.
190
Michael Foordb3a89842010-06-30 12:17:50 +0000191 .. versionadded:: 3.2
192
193
Nick Coghlan3267a302012-05-21 22:54:43 +1000194.. class:: ExitStack()
195
196 A context manager that is designed to make it easy to programmatically
197 combine other context managers and cleanup functions, especially those
198 that are optional or otherwise driven by input data.
199
200 For example, a set of files may easily be handled in a single with
201 statement as follows::
202
203 with ExitStack() as stack:
204 files = [stack.enter_context(open(fname)) for fname in filenames]
205 # All opened files will automatically be closed at the end of
206 # the with statement, even if attempts to open files later
Andrew Svetlov5b898402012-12-18 21:26:36 +0200207 # in the list raise an exception
Nick Coghlan3267a302012-05-21 22:54:43 +1000208
209 Each instance maintains a stack of registered callbacks that are called in
210 reverse order when the instance is closed (either explicitly or implicitly
Nick Coghlan27228272012-05-31 22:17:08 +1000211 at the end of a :keyword:`with` statement). Note that callbacks are *not*
212 invoked implicitly when the context stack instance is garbage collected.
Nick Coghlan3267a302012-05-21 22:54:43 +1000213
214 This stack model is used so that context managers that acquire their
215 resources in their ``__init__`` method (such as file objects) can be
216 handled correctly.
217
218 Since registered callbacks are invoked in the reverse order of
Nick Coghlan27228272012-05-31 22:17:08 +1000219 registration, this ends up behaving as if multiple nested :keyword:`with`
Nick Coghlan3267a302012-05-21 22:54:43 +1000220 statements had been used with the registered set of callbacks. This even
221 extends to exception handling - if an inner callback suppresses or replaces
222 an exception, then outer callbacks will be passed arguments based on that
223 updated state.
224
225 This is a relatively low level API that takes care of the details of
226 correctly unwinding the stack of exit callbacks. It provides a suitable
227 foundation for higher level context managers that manipulate the exit
228 stack in application specific ways.
229
Nick Coghlana497b442012-05-22 23:02:00 +1000230 .. versionadded:: 3.3
231
Nick Coghlan3267a302012-05-21 22:54:43 +1000232 .. method:: enter_context(cm)
233
234 Enters a new context manager and adds its :meth:`__exit__` method to
235 the callback stack. The return value is the result of the context
236 manager's own :meth:`__enter__` method.
237
238 These context managers may suppress exceptions just as they normally
Nick Coghlan27228272012-05-31 22:17:08 +1000239 would if used directly as part of a :keyword:`with` statement.
Nick Coghlan3267a302012-05-21 22:54:43 +1000240
241 .. method:: push(exit)
242
243 Adds a context manager's :meth:`__exit__` method to the callback stack.
244
245 As ``__enter__`` is *not* invoked, this method can be used to cover
246 part of an :meth:`__enter__` implementation with a context manager's own
247 :meth:`__exit__` method.
248
249 If passed an object that is not a context manager, this method assumes
250 it is a callback with the same signature as a context manager's
251 :meth:`__exit__` method and adds it directly to the callback stack.
252
253 By returning true values, these callbacks can suppress exceptions the
254 same way context manager :meth:`__exit__` methods can.
255
256 The passed in object is returned from the function, allowing this
Nick Coghlan27228272012-05-31 22:17:08 +1000257 method to be used as a function decorator.
Nick Coghlan3267a302012-05-21 22:54:43 +1000258
259 .. method:: callback(callback, *args, **kwds)
260
261 Accepts an arbitrary callback function and arguments and adds it to
262 the callback stack.
263
264 Unlike the other methods, callbacks added this way cannot suppress
265 exceptions (as they are never passed the exception details).
266
267 The passed in callback is returned from the function, allowing this
Nick Coghlan27228272012-05-31 22:17:08 +1000268 method to be used as a function decorator.
Nick Coghlan3267a302012-05-21 22:54:43 +1000269
270 .. method:: pop_all()
271
272 Transfers the callback stack to a fresh :class:`ExitStack` instance
273 and returns it. No callbacks are invoked by this operation - instead,
274 they will now be invoked when the new stack is closed (either
Nick Coghlan27228272012-05-31 22:17:08 +1000275 explicitly or implicitly at the end of a :keyword:`with` statement).
Nick Coghlan3267a302012-05-21 22:54:43 +1000276
277 For example, a group of files can be opened as an "all or nothing"
278 operation as follows::
279
280 with ExitStack() as stack:
281 files = [stack.enter_context(open(fname)) for fname in filenames]
282 close_files = stack.pop_all().close
283 # If opening any file fails, all previously opened files will be
284 # closed automatically. If all files are opened successfully,
285 # they will remain open even after the with statement ends.
286 # close_files() can then be invoked explicitly to close them all
287
288 .. method:: close()
289
290 Immediately unwinds the callback stack, invoking callbacks in the
291 reverse order of registration. For any context managers and exit
292 callbacks registered, the arguments passed in will indicate that no
293 exception occurred.
294
Nick Coghlan3267a302012-05-21 22:54:43 +1000295
296Examples and Recipes
297--------------------
298
299This section describes some examples and recipes for making effective use of
300the tools provided by :mod:`contextlib`.
301
302
Nick Coghlan27228272012-05-31 22:17:08 +1000303Supporting a variable number of context managers
304^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
305
306The primary use case for :class:`ExitStack` is the one given in the class
307documentation: supporting a variable number of context managers and other
308cleanup operations in a single :keyword:`with` statement. The variability
309may come from the number of context managers needed being driven by user
310input (such as opening a user specified collection of files), or from
311some of the context managers being optional::
312
313 with ExitStack() as stack:
314 for resource in resources:
315 stack.enter_context(resource)
316 if need_special resource:
317 special = acquire_special_resource()
318 stack.callback(release_special_resource, special)
319 # Perform operations that use the acquired resources
320
321As shown, :class:`ExitStack` also makes it quite easy to use :keyword:`with`
322statements to manage arbitrary resources that don't natively support the
323context management protocol.
324
325
326Simplifying support for single optional context managers
327^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
328
329In the specific case of a single optional context manager, :class:`ExitStack`
330instances can be used as a "do nothing" context manager, allowing a context
Nick Coghlanb7a455f2012-05-31 22:34:59 +1000331manager to easily be omitted without affecting the overall structure of
Nick Coghlan27228272012-05-31 22:17:08 +1000332the source code::
333
334 def debug_trace(details):
335 if __debug__:
336 return TraceContext(details)
337 # Don't do anything special with the context in release mode
338 return ExitStack()
339
340 with debug_trace():
341 # Suite is traced in debug mode, but runs normally otherwise
342
343
344Catching exceptions from ``__enter__`` methods
345^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
346
347It is occasionally desirable to catch exceptions from an ``__enter__``
348method implementation, *without* inadvertently catching exceptions from
349the :keyword:`with` statement body or the context manager's ``__exit__``
350method. By using :class:`ExitStack` the steps in the context management
351protocol can be separated slightly in order to allow this::
352
353 stack = ExitStack()
354 try:
355 x = stack.enter_context(cm)
356 except Exception:
357 # handle __enter__ exception
358 else:
359 with stack:
360 # Handle normal case
361
362Actually needing to do this is likely to indicate that the underlying API
363should be providing a direct resource management interface for use with
364:keyword:`try`/:keyword:`except`/:keyword:`finally` statements, but not
365all APIs are well designed in that regard. When a context manager is the
366only resource management API provided, then :class:`ExitStack` can make it
367easier to handle various situations that can't be handled directly in a
368:keyword:`with` statement.
369
370
Nick Coghlan3267a302012-05-21 22:54:43 +1000371Cleaning up in an ``__enter__`` implementation
372^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
373
374As noted in the documentation of :meth:`ExitStack.push`, this
375method can be useful in cleaning up an already allocated resource if later
376steps in the :meth:`__enter__` implementation fail.
377
378Here's an example of doing this for a context manager that accepts resource
379acquisition and release functions, along with an optional validation function,
380and maps them to the context management protocol::
381
382 from contextlib import contextmanager, ExitStack
383
Ezio Melottic9cfcf12013-03-11 09:42:40 +0200384 class ResourceManager:
Nick Coghlan3267a302012-05-21 22:54:43 +1000385
386 def __init__(self, acquire_resource, release_resource, check_resource_ok=None):
387 self.acquire_resource = acquire_resource
388 self.release_resource = release_resource
389 if check_resource_ok is None:
390 def check_resource_ok(resource):
391 return True
392 self.check_resource_ok = check_resource_ok
393
394 @contextmanager
395 def _cleanup_on_error(self):
396 with ExitStack() as stack:
397 stack.push(self)
398 yield
399 # The validation check passed and didn't raise an exception
400 # Accordingly, we want to keep the resource, and pass it
401 # back to our caller
402 stack.pop_all()
403
404 def __enter__(self):
405 resource = self.acquire_resource()
406 with self._cleanup_on_error():
407 if not self.check_resource_ok(resource):
408 msg = "Failed validation for {!r}"
409 raise RuntimeError(msg.format(resource))
410 return resource
411
412 def __exit__(self, *exc_details):
413 # We don't need to duplicate any of our resource release logic
414 self.release_resource()
415
416
417Replacing any use of ``try-finally`` and flag variables
418^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
419
420A pattern you will sometimes see is a ``try-finally`` statement with a flag
421variable to indicate whether or not the body of the ``finally`` clause should
422be executed. In its simplest form (that can't already be handled just by
423using an ``except`` clause instead), it looks something like this::
424
425 cleanup_needed = True
426 try:
427 result = perform_operation()
428 if result:
429 cleanup_needed = False
430 finally:
431 if cleanup_needed:
432 cleanup_resources()
433
434As with any ``try`` statement based code, this can cause problems for
435development and review, because the setup code and the cleanup code can end
436up being separated by arbitrarily long sections of code.
437
438:class:`ExitStack` makes it possible to instead register a callback for
439execution at the end of a ``with`` statement, and then later decide to skip
440executing that callback::
441
442 from contextlib import ExitStack
443
444 with ExitStack() as stack:
445 stack.callback(cleanup_resources)
446 result = perform_operation()
447 if result:
448 stack.pop_all()
449
450This allows the intended cleanup up behaviour to be made explicit up front,
451rather than requiring a separate flag variable.
452
453If a particular application uses this pattern a lot, it can be simplified
454even further by means of a small helper class::
455
456 from contextlib import ExitStack
457
458 class Callback(ExitStack):
459 def __init__(self, callback, *args, **kwds):
460 super(Callback, self).__init__()
461 self.callback(callback, *args, **kwds)
462
463 def cancel(self):
464 self.pop_all()
465
466 with Callback(cleanup_resources) as cb:
467 result = perform_operation()
468 if result:
469 cb.cancel()
470
471If the resource cleanup isn't already neatly bundled into a standalone
472function, then it is still possible to use the decorator form of
473:meth:`ExitStack.callback` to declare the resource cleanup in
474advance::
475
476 from contextlib import ExitStack
477
478 with ExitStack() as stack:
479 @stack.callback
480 def cleanup_resources():
481 ...
482 result = perform_operation()
483 if result:
484 stack.pop_all()
485
486Due to the way the decorator protocol works, a callback function
487declared this way cannot take any parameters. Instead, any resources to
488be released must be accessed as closure variables
489
490
491Using a context manager as a function decorator
492^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
493
494:class:`ContextDecorator` makes it possible to use a context manager in
495both an ordinary ``with`` statement and also as a function decorator.
496
497For example, it is sometimes useful to wrap functions or groups of statements
498with a logger that can track the time of entry and time of exit. Rather than
499writing both a function decorator and a context manager for the task,
500inheriting from :class:`ContextDecorator` provides both capabilities in a
501single definition::
502
503 from contextlib import ContextDecorator
504 import logging
505
506 logging.basicConfig(level=logging.INFO)
507
508 class track_entry_and_exit(ContextDecorator):
509 def __init__(self, name):
510 self.name = name
511
512 def __enter__(self):
513 logging.info('Entering: {}'.format(name))
514
515 def __exit__(self, exc_type, exc, exc_tb):
516 logging.info('Exiting: {}'.format(name))
517
518Instances of this class can be used as both a context manager::
519
520 with track_entry_and_exit('widget loader'):
521 print('Some time consuming activity goes here')
522 load_widget()
523
524And also as a function decorator::
525
526 @track_entry_and_exit('widget loader')
527 def activity():
528 print('Some time consuming activity goes here')
529 load_widget()
530
531Note that there is one additional limitation when using context managers
532as function decorators: there's no way to access the return value of
533:meth:`__enter__`. If that value is needed, then it is still necessary to use
534an explicit ``with`` statement.
535
Georg Brandl116aa622007-08-15 14:28:22 +0000536.. seealso::
537
538 :pep:`0343` - The "with" statement
539 The specification, background, and examples for the Python :keyword:`with`
540 statement.
541