blob: cac113e839aadc2b99079a5f37753ebc539c84b2 [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 Hettinger1254b402013-10-10 22:39:39 -070097.. function:: ignore(*exceptions)
Raymond Hettingere318a882013-03-10 22:26:51 -070098
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
Raymond Hettinger1254b402013-10-10 22:39:39 -0700104 from contextlib import ignore
Raymond Hettingere318a882013-03-10 22:26:51 -0700105
Raymond Hettinger1254b402013-10-10 22:39:39 -0700106 with ignore(OSError):
Raymond Hettingere318a882013-03-10 22:26:51 -0700107 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
Raymond Hettinger088cbf22013-10-10 00:46:57 -0700118.. function:: redirect_stdout(new_target)
119
120 Context manager for temporarily redirecting :data:`sys.stdout` to
121 another file or file-like object.
122
123 This tool adds flexibility to existing functions or classes whose output
124 is hardwired to stdout.
125
126 For example, the output of :func:`help` normally is sent to *sys.stdout*.
127 You can capture that output in a string by redirecting the output to a
128 :class:`io.StringIO` object::
129
130 f = io.StringIO()
131 with redirect_stdout(f):
132 help(pow)
133 s = f.getvalue()
134
135 To send the output of :func:`help` to a file on disk, redirect the output
136 to a regular file::
137
138 with open('help.txt', 'w') as f:
139 with redirect_stdout(f):
140 help(pow)
141
142 To send the output of :func:`help` to *sys.stderr*::
143
144 with redirect_stdout(sys.stderr):
145 help(pow)
146
147 .. versionadded:: 3.4
148
Michael Foordb3a89842010-06-30 12:17:50 +0000149.. class:: ContextDecorator()
150
151 A base class that enables a context manager to also be used as a decorator.
152
153 Context managers inheriting from ``ContextDecorator`` have to implement
154 ``__enter__`` and ``__exit__`` as normal. ``__exit__`` retains its optional
155 exception handling even when used as a decorator.
156
Georg Brandl86e78d12010-07-18 13:43:32 +0000157 ``ContextDecorator`` is used by :func:`contextmanager`, so you get this
158 functionality automatically.
159
160 Example of ``ContextDecorator``::
Michael Foordb3a89842010-06-30 12:17:50 +0000161
162 from contextlib import ContextDecorator
163
164 class mycontext(ContextDecorator):
Georg Brandl86e78d12010-07-18 13:43:32 +0000165 def __enter__(self):
166 print('Starting')
167 return self
Michael Foordb3a89842010-06-30 12:17:50 +0000168
Georg Brandl86e78d12010-07-18 13:43:32 +0000169 def __exit__(self, *exc):
170 print('Finishing')
171 return False
Michael Foordb3a89842010-06-30 12:17:50 +0000172
173 >>> @mycontext()
174 ... def function():
Georg Brandl86e78d12010-07-18 13:43:32 +0000175 ... print('The bit in the middle')
Michael Foordb3a89842010-06-30 12:17:50 +0000176 ...
177 >>> function()
178 Starting
179 The bit in the middle
180 Finishing
181
182 >>> with mycontext():
Georg Brandl86e78d12010-07-18 13:43:32 +0000183 ... print('The bit in the middle')
Michael Foordb3a89842010-06-30 12:17:50 +0000184 ...
185 Starting
186 The bit in the middle
187 Finishing
188
Georg Brandl86e78d12010-07-18 13:43:32 +0000189 This change is just syntactic sugar for any construct of the following form::
190
191 def f():
192 with cm():
193 # Do stuff
194
195 ``ContextDecorator`` lets you instead write::
196
197 @cm()
198 def f():
199 # Do stuff
200
201 It makes it clear that the ``cm`` applies to the whole function, rather than
202 just a piece of it (and saving an indentation level is nice, too).
203
Michael Foordb3a89842010-06-30 12:17:50 +0000204 Existing context managers that already have a base class can be extended by
205 using ``ContextDecorator`` as a mixin class::
206
207 from contextlib import ContextDecorator
208
209 class mycontext(ContextBaseClass, ContextDecorator):
Georg Brandl86e78d12010-07-18 13:43:32 +0000210 def __enter__(self):
211 return self
Michael Foordb3a89842010-06-30 12:17:50 +0000212
Georg Brandl86e78d12010-07-18 13:43:32 +0000213 def __exit__(self, *exc):
214 return False
Michael Foordb3a89842010-06-30 12:17:50 +0000215
Nick Coghlan0ded3e32011-05-05 23:49:25 +1000216 .. note::
217 As the decorated function must be able to be called multiple times, the
218 underlying context manager must support use in multiple :keyword:`with`
219 statements. If this is not the case, then the original construct with the
220 explicit :keyword:`with` statement inside the function should be used.
221
Michael Foordb3a89842010-06-30 12:17:50 +0000222 .. versionadded:: 3.2
223
224
Nick Coghlan3267a302012-05-21 22:54:43 +1000225.. class:: ExitStack()
226
227 A context manager that is designed to make it easy to programmatically
228 combine other context managers and cleanup functions, especially those
229 that are optional or otherwise driven by input data.
230
231 For example, a set of files may easily be handled in a single with
232 statement as follows::
233
234 with ExitStack() as stack:
235 files = [stack.enter_context(open(fname)) for fname in filenames]
236 # All opened files will automatically be closed at the end of
237 # the with statement, even if attempts to open files later
Andrew Svetlov5b898402012-12-18 21:26:36 +0200238 # in the list raise an exception
Nick Coghlan3267a302012-05-21 22:54:43 +1000239
240 Each instance maintains a stack of registered callbacks that are called in
241 reverse order when the instance is closed (either explicitly or implicitly
Nick Coghlan27228272012-05-31 22:17:08 +1000242 at the end of a :keyword:`with` statement). Note that callbacks are *not*
243 invoked implicitly when the context stack instance is garbage collected.
Nick Coghlan3267a302012-05-21 22:54:43 +1000244
245 This stack model is used so that context managers that acquire their
246 resources in their ``__init__`` method (such as file objects) can be
247 handled correctly.
248
249 Since registered callbacks are invoked in the reverse order of
Nick Coghlan27228272012-05-31 22:17:08 +1000250 registration, this ends up behaving as if multiple nested :keyword:`with`
Nick Coghlan3267a302012-05-21 22:54:43 +1000251 statements had been used with the registered set of callbacks. This even
252 extends to exception handling - if an inner callback suppresses or replaces
253 an exception, then outer callbacks will be passed arguments based on that
254 updated state.
255
256 This is a relatively low level API that takes care of the details of
257 correctly unwinding the stack of exit callbacks. It provides a suitable
258 foundation for higher level context managers that manipulate the exit
259 stack in application specific ways.
260
Nick Coghlana497b442012-05-22 23:02:00 +1000261 .. versionadded:: 3.3
262
Nick Coghlan3267a302012-05-21 22:54:43 +1000263 .. method:: enter_context(cm)
264
265 Enters a new context manager and adds its :meth:`__exit__` method to
266 the callback stack. The return value is the result of the context
267 manager's own :meth:`__enter__` method.
268
269 These context managers may suppress exceptions just as they normally
Nick Coghlan27228272012-05-31 22:17:08 +1000270 would if used directly as part of a :keyword:`with` statement.
Nick Coghlan3267a302012-05-21 22:54:43 +1000271
272 .. method:: push(exit)
273
274 Adds a context manager's :meth:`__exit__` method to the callback stack.
275
276 As ``__enter__`` is *not* invoked, this method can be used to cover
277 part of an :meth:`__enter__` implementation with a context manager's own
278 :meth:`__exit__` method.
279
280 If passed an object that is not a context manager, this method assumes
281 it is a callback with the same signature as a context manager's
282 :meth:`__exit__` method and adds it directly to the callback stack.
283
284 By returning true values, these callbacks can suppress exceptions the
285 same way context manager :meth:`__exit__` methods can.
286
287 The passed in object is returned from the function, allowing this
Nick Coghlan27228272012-05-31 22:17:08 +1000288 method to be used as a function decorator.
Nick Coghlan3267a302012-05-21 22:54:43 +1000289
290 .. method:: callback(callback, *args, **kwds)
291
292 Accepts an arbitrary callback function and arguments and adds it to
293 the callback stack.
294
295 Unlike the other methods, callbacks added this way cannot suppress
296 exceptions (as they are never passed the exception details).
297
298 The passed in callback is returned from the function, allowing this
Nick Coghlan27228272012-05-31 22:17:08 +1000299 method to be used as a function decorator.
Nick Coghlan3267a302012-05-21 22:54:43 +1000300
301 .. method:: pop_all()
302
303 Transfers the callback stack to a fresh :class:`ExitStack` instance
304 and returns it. No callbacks are invoked by this operation - instead,
305 they will now be invoked when the new stack is closed (either
Nick Coghlan27228272012-05-31 22:17:08 +1000306 explicitly or implicitly at the end of a :keyword:`with` statement).
Nick Coghlan3267a302012-05-21 22:54:43 +1000307
308 For example, a group of files can be opened as an "all or nothing"
309 operation as follows::
310
311 with ExitStack() as stack:
312 files = [stack.enter_context(open(fname)) for fname in filenames]
Barry Warsawd8f870d2013-05-10 11:35:38 -0400313 # Hold onto the close method, but don't call it yet.
314 close_files = stack.pop_all().close
Nick Coghlan3267a302012-05-21 22:54:43 +1000315 # If opening any file fails, all previously opened files will be
316 # closed automatically. If all files are opened successfully,
317 # they will remain open even after the with statement ends.
Barry Warsawd8f870d2013-05-10 11:35:38 -0400318 # close_files() can then be invoked explicitly to close them all.
Nick Coghlan3267a302012-05-21 22:54:43 +1000319
320 .. method:: close()
321
322 Immediately unwinds the callback stack, invoking callbacks in the
323 reverse order of registration. For any context managers and exit
324 callbacks registered, the arguments passed in will indicate that no
325 exception occurred.
326
Nick Coghlan3267a302012-05-21 22:54:43 +1000327
328Examples and Recipes
329--------------------
330
331This section describes some examples and recipes for making effective use of
332the tools provided by :mod:`contextlib`.
333
334
Nick Coghlan27228272012-05-31 22:17:08 +1000335Supporting a variable number of context managers
336^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
337
338The primary use case for :class:`ExitStack` is the one given in the class
339documentation: supporting a variable number of context managers and other
340cleanup operations in a single :keyword:`with` statement. The variability
341may come from the number of context managers needed being driven by user
342input (such as opening a user specified collection of files), or from
343some of the context managers being optional::
344
345 with ExitStack() as stack:
346 for resource in resources:
347 stack.enter_context(resource)
348 if need_special resource:
349 special = acquire_special_resource()
350 stack.callback(release_special_resource, special)
351 # Perform operations that use the acquired resources
352
353As shown, :class:`ExitStack` also makes it quite easy to use :keyword:`with`
354statements to manage arbitrary resources that don't natively support the
355context management protocol.
356
357
358Simplifying support for single optional context managers
359^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
360
361In the specific case of a single optional context manager, :class:`ExitStack`
362instances can be used as a "do nothing" context manager, allowing a context
Nick Coghlanb7a455f2012-05-31 22:34:59 +1000363manager to easily be omitted without affecting the overall structure of
Nick Coghlan27228272012-05-31 22:17:08 +1000364the source code::
365
366 def debug_trace(details):
367 if __debug__:
368 return TraceContext(details)
369 # Don't do anything special with the context in release mode
370 return ExitStack()
371
372 with debug_trace():
373 # Suite is traced in debug mode, but runs normally otherwise
374
375
376Catching exceptions from ``__enter__`` methods
377^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
378
379It is occasionally desirable to catch exceptions from an ``__enter__``
380method implementation, *without* inadvertently catching exceptions from
381the :keyword:`with` statement body or the context manager's ``__exit__``
382method. By using :class:`ExitStack` the steps in the context management
383protocol can be separated slightly in order to allow this::
384
385 stack = ExitStack()
386 try:
387 x = stack.enter_context(cm)
388 except Exception:
389 # handle __enter__ exception
390 else:
391 with stack:
392 # Handle normal case
393
394Actually needing to do this is likely to indicate that the underlying API
395should be providing a direct resource management interface for use with
396:keyword:`try`/:keyword:`except`/:keyword:`finally` statements, but not
397all APIs are well designed in that regard. When a context manager is the
398only resource management API provided, then :class:`ExitStack` can make it
399easier to handle various situations that can't be handled directly in a
400:keyword:`with` statement.
401
402
Nick Coghlan3267a302012-05-21 22:54:43 +1000403Cleaning up in an ``__enter__`` implementation
404^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
405
406As noted in the documentation of :meth:`ExitStack.push`, this
407method can be useful in cleaning up an already allocated resource if later
408steps in the :meth:`__enter__` implementation fail.
409
410Here's an example of doing this for a context manager that accepts resource
411acquisition and release functions, along with an optional validation function,
412and maps them to the context management protocol::
413
414 from contextlib import contextmanager, ExitStack
415
Ezio Melottic9cfcf12013-03-11 09:42:40 +0200416 class ResourceManager:
Nick Coghlan3267a302012-05-21 22:54:43 +1000417
418 def __init__(self, acquire_resource, release_resource, check_resource_ok=None):
419 self.acquire_resource = acquire_resource
420 self.release_resource = release_resource
421 if check_resource_ok is None:
422 def check_resource_ok(resource):
423 return True
424 self.check_resource_ok = check_resource_ok
425
426 @contextmanager
427 def _cleanup_on_error(self):
428 with ExitStack() as stack:
429 stack.push(self)
430 yield
431 # The validation check passed and didn't raise an exception
432 # Accordingly, we want to keep the resource, and pass it
433 # back to our caller
434 stack.pop_all()
435
436 def __enter__(self):
437 resource = self.acquire_resource()
438 with self._cleanup_on_error():
439 if not self.check_resource_ok(resource):
440 msg = "Failed validation for {!r}"
441 raise RuntimeError(msg.format(resource))
442 return resource
443
444 def __exit__(self, *exc_details):
445 # We don't need to duplicate any of our resource release logic
446 self.release_resource()
447
448
449Replacing any use of ``try-finally`` and flag variables
450^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
451
452A pattern you will sometimes see is a ``try-finally`` statement with a flag
453variable to indicate whether or not the body of the ``finally`` clause should
454be executed. In its simplest form (that can't already be handled just by
455using an ``except`` clause instead), it looks something like this::
456
457 cleanup_needed = True
458 try:
459 result = perform_operation()
460 if result:
461 cleanup_needed = False
462 finally:
463 if cleanup_needed:
464 cleanup_resources()
465
466As with any ``try`` statement based code, this can cause problems for
467development and review, because the setup code and the cleanup code can end
468up being separated by arbitrarily long sections of code.
469
470:class:`ExitStack` makes it possible to instead register a callback for
471execution at the end of a ``with`` statement, and then later decide to skip
472executing that callback::
473
474 from contextlib import ExitStack
475
476 with ExitStack() as stack:
477 stack.callback(cleanup_resources)
478 result = perform_operation()
479 if result:
480 stack.pop_all()
481
482This allows the intended cleanup up behaviour to be made explicit up front,
483rather than requiring a separate flag variable.
484
485If a particular application uses this pattern a lot, it can be simplified
486even further by means of a small helper class::
487
488 from contextlib import ExitStack
489
490 class Callback(ExitStack):
491 def __init__(self, callback, *args, **kwds):
492 super(Callback, self).__init__()
493 self.callback(callback, *args, **kwds)
494
495 def cancel(self):
496 self.pop_all()
497
498 with Callback(cleanup_resources) as cb:
499 result = perform_operation()
500 if result:
501 cb.cancel()
502
503If the resource cleanup isn't already neatly bundled into a standalone
504function, then it is still possible to use the decorator form of
505:meth:`ExitStack.callback` to declare the resource cleanup in
506advance::
507
508 from contextlib import ExitStack
509
510 with ExitStack() as stack:
511 @stack.callback
512 def cleanup_resources():
513 ...
514 result = perform_operation()
515 if result:
516 stack.pop_all()
517
518Due to the way the decorator protocol works, a callback function
519declared this way cannot take any parameters. Instead, any resources to
520be released must be accessed as closure variables
521
522
523Using a context manager as a function decorator
524^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
525
526:class:`ContextDecorator` makes it possible to use a context manager in
527both an ordinary ``with`` statement and also as a function decorator.
528
529For example, it is sometimes useful to wrap functions or groups of statements
530with a logger that can track the time of entry and time of exit. Rather than
531writing both a function decorator and a context manager for the task,
532inheriting from :class:`ContextDecorator` provides both capabilities in a
533single definition::
534
535 from contextlib import ContextDecorator
536 import logging
537
538 logging.basicConfig(level=logging.INFO)
539
540 class track_entry_and_exit(ContextDecorator):
541 def __init__(self, name):
542 self.name = name
543
544 def __enter__(self):
545 logging.info('Entering: {}'.format(name))
546
547 def __exit__(self, exc_type, exc, exc_tb):
548 logging.info('Exiting: {}'.format(name))
549
550Instances of this class can be used as both a context manager::
551
552 with track_entry_and_exit('widget loader'):
553 print('Some time consuming activity goes here')
554 load_widget()
555
556And also as a function decorator::
557
558 @track_entry_and_exit('widget loader')
559 def activity():
560 print('Some time consuming activity goes here')
561 load_widget()
562
563Note that there is one additional limitation when using context managers
564as function decorators: there's no way to access the return value of
565:meth:`__enter__`. If that value is needed, then it is still necessary to use
566an explicit ``with`` statement.
567
Georg Brandl116aa622007-08-15 14:28:22 +0000568.. seealso::
569
570 :pep:`0343` - The "with" statement
571 The specification, background, and examples for the Python :keyword:`with`
572 statement.
573