blob: cf85fcd4b295697133bac1c6cce229a2edb1ff43 [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
Georg Brandla7c17e52013-10-13 22:25:10 +020097
Nick Coghlan240f86d2013-10-17 23:40:57 +100098.. function:: suppress(*exceptions)
Raymond Hettingere318a882013-03-10 22:26:51 -070099
Nick Coghlan240f86d2013-10-17 23:40:57 +1000100 Return a context manager that suppresses any of the specified exceptions
101 if they occur in the body of a with statement and then resumes execution
102 with the first statement following the end of the with statement.
Raymond Hettingere318a882013-03-10 22:26:51 -0700103
Nick Coghlan240f86d2013-10-17 23:40:57 +1000104 As with any other mechanism that completely suppresses exceptions, this
105 context manager should be used only to cover very specific errors where
106 silently continuing with program execution is known to be the right
107 thing to do.
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000108
Raymond Hettingere318a882013-03-10 22:26:51 -0700109 For example::
110
Nick Coghlan240f86d2013-10-17 23:40:57 +1000111 from contextlib import suppress
Raymond Hettingere318a882013-03-10 22:26:51 -0700112
Nick Coghlan240f86d2013-10-17 23:40:57 +1000113 with suppress(FileNotFoundError):
Raymond Hettingere318a882013-03-10 22:26:51 -0700114 os.remove('somefile.tmp')
115
Nick Coghlan240f86d2013-10-17 23:40:57 +1000116 with suppress(FileNotFoundError):
117 os.remove('someotherfile.tmp')
118
Raymond Hettingere318a882013-03-10 22:26:51 -0700119 This code is equivalent to::
120
121 try:
122 os.remove('somefile.tmp')
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000123 except FileNotFoundError:
Raymond Hettingere318a882013-03-10 22:26:51 -0700124 pass
125
Nick Coghlan240f86d2013-10-17 23:40:57 +1000126 try:
127 os.remove('someotherfile.tmp')
128 except FileNotFoundError:
129 pass
130
Nick Coghlan8608d262013-10-20 00:30:51 +1000131 This context manager is :ref:`reentrant <reentrant-cms>`.
132
Raymond Hettingere318a882013-03-10 22:26:51 -0700133 .. versionadded:: 3.4
Georg Brandl116aa622007-08-15 14:28:22 +0000134
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000135
Raymond Hettinger088cbf22013-10-10 00:46:57 -0700136.. function:: redirect_stdout(new_target)
137
138 Context manager for temporarily redirecting :data:`sys.stdout` to
139 another file or file-like object.
140
141 This tool adds flexibility to existing functions or classes whose output
142 is hardwired to stdout.
143
144 For example, the output of :func:`help` normally is sent to *sys.stdout*.
Serhiy Storchakad65c9492015-11-02 14:10:23 +0200145 You can capture that output in a string by redirecting the output to an
Raymond Hettinger088cbf22013-10-10 00:46:57 -0700146 :class:`io.StringIO` object::
147
148 f = io.StringIO()
149 with redirect_stdout(f):
150 help(pow)
151 s = f.getvalue()
152
153 To send the output of :func:`help` to a file on disk, redirect the output
154 to a regular file::
155
156 with open('help.txt', 'w') as f:
157 with redirect_stdout(f):
158 help(pow)
159
160 To send the output of :func:`help` to *sys.stderr*::
161
162 with redirect_stdout(sys.stderr):
163 help(pow)
164
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000165 Note that the global side effect on :data:`sys.stdout` means that this
166 context manager is not suitable for use in library code and most threaded
167 applications. It also has no effect on the output of subprocesses.
168 However, it is still a useful approach for many utility scripts.
169
Nick Coghlan36d8ef92014-10-12 10:25:00 +1000170 This context manager is :ref:`reentrant <reentrant-cms>`.
Nick Coghlan8608d262013-10-20 00:30:51 +1000171
Raymond Hettinger088cbf22013-10-10 00:46:57 -0700172 .. versionadded:: 3.4
173
Georg Brandla7c17e52013-10-13 22:25:10 +0200174
Berker Peksagbb44fe02014-11-28 23:28:06 +0200175.. function:: redirect_stderr(new_target)
176
177 Similar to :func:`~contextlib.redirect_stdout` but redirecting
178 :data:`sys.stderr` to another file or file-like object.
179
180 This context manager is :ref:`reentrant <reentrant-cms>`.
181
182 .. versionadded:: 3.5
183
184
Michael Foordb3a89842010-06-30 12:17:50 +0000185.. class:: ContextDecorator()
186
187 A base class that enables a context manager to also be used as a decorator.
188
189 Context managers inheriting from ``ContextDecorator`` have to implement
190 ``__enter__`` and ``__exit__`` as normal. ``__exit__`` retains its optional
191 exception handling even when used as a decorator.
192
Georg Brandl86e78d12010-07-18 13:43:32 +0000193 ``ContextDecorator`` is used by :func:`contextmanager`, so you get this
194 functionality automatically.
195
196 Example of ``ContextDecorator``::
Michael Foordb3a89842010-06-30 12:17:50 +0000197
198 from contextlib import ContextDecorator
199
200 class mycontext(ContextDecorator):
Georg Brandl86e78d12010-07-18 13:43:32 +0000201 def __enter__(self):
202 print('Starting')
203 return self
Michael Foordb3a89842010-06-30 12:17:50 +0000204
Georg Brandl86e78d12010-07-18 13:43:32 +0000205 def __exit__(self, *exc):
206 print('Finishing')
207 return False
Michael Foordb3a89842010-06-30 12:17:50 +0000208
209 >>> @mycontext()
210 ... def function():
Georg Brandl86e78d12010-07-18 13:43:32 +0000211 ... print('The bit in the middle')
Michael Foordb3a89842010-06-30 12:17:50 +0000212 ...
213 >>> function()
214 Starting
215 The bit in the middle
216 Finishing
217
218 >>> with mycontext():
Georg Brandl86e78d12010-07-18 13:43:32 +0000219 ... print('The bit in the middle')
Michael Foordb3a89842010-06-30 12:17:50 +0000220 ...
221 Starting
222 The bit in the middle
223 Finishing
224
Georg Brandl86e78d12010-07-18 13:43:32 +0000225 This change is just syntactic sugar for any construct of the following form::
226
227 def f():
228 with cm():
229 # Do stuff
230
231 ``ContextDecorator`` lets you instead write::
232
233 @cm()
234 def f():
235 # Do stuff
236
237 It makes it clear that the ``cm`` applies to the whole function, rather than
238 just a piece of it (and saving an indentation level is nice, too).
239
Michael Foordb3a89842010-06-30 12:17:50 +0000240 Existing context managers that already have a base class can be extended by
241 using ``ContextDecorator`` as a mixin class::
242
243 from contextlib import ContextDecorator
244
245 class mycontext(ContextBaseClass, ContextDecorator):
Georg Brandl86e78d12010-07-18 13:43:32 +0000246 def __enter__(self):
247 return self
Michael Foordb3a89842010-06-30 12:17:50 +0000248
Georg Brandl86e78d12010-07-18 13:43:32 +0000249 def __exit__(self, *exc):
250 return False
Michael Foordb3a89842010-06-30 12:17:50 +0000251
Nick Coghlan0ded3e32011-05-05 23:49:25 +1000252 .. note::
253 As the decorated function must be able to be called multiple times, the
254 underlying context manager must support use in multiple :keyword:`with`
255 statements. If this is not the case, then the original construct with the
256 explicit :keyword:`with` statement inside the function should be used.
257
Michael Foordb3a89842010-06-30 12:17:50 +0000258 .. versionadded:: 3.2
259
260
Nick Coghlan3267a302012-05-21 22:54:43 +1000261.. class:: ExitStack()
262
263 A context manager that is designed to make it easy to programmatically
264 combine other context managers and cleanup functions, especially those
265 that are optional or otherwise driven by input data.
266
267 For example, a set of files may easily be handled in a single with
268 statement as follows::
269
270 with ExitStack() as stack:
271 files = [stack.enter_context(open(fname)) for fname in filenames]
272 # All opened files will automatically be closed at the end of
273 # the with statement, even if attempts to open files later
Andrew Svetlov5b898402012-12-18 21:26:36 +0200274 # in the list raise an exception
Nick Coghlan3267a302012-05-21 22:54:43 +1000275
276 Each instance maintains a stack of registered callbacks that are called in
277 reverse order when the instance is closed (either explicitly or implicitly
Nick Coghlan27228272012-05-31 22:17:08 +1000278 at the end of a :keyword:`with` statement). Note that callbacks are *not*
279 invoked implicitly when the context stack instance is garbage collected.
Nick Coghlan3267a302012-05-21 22:54:43 +1000280
281 This stack model is used so that context managers that acquire their
282 resources in their ``__init__`` method (such as file objects) can be
283 handled correctly.
284
285 Since registered callbacks are invoked in the reverse order of
Nick Coghlan27228272012-05-31 22:17:08 +1000286 registration, this ends up behaving as if multiple nested :keyword:`with`
Nick Coghlan3267a302012-05-21 22:54:43 +1000287 statements had been used with the registered set of callbacks. This even
288 extends to exception handling - if an inner callback suppresses or replaces
289 an exception, then outer callbacks will be passed arguments based on that
290 updated state.
291
292 This is a relatively low level API that takes care of the details of
293 correctly unwinding the stack of exit callbacks. It provides a suitable
294 foundation for higher level context managers that manipulate the exit
295 stack in application specific ways.
296
Nick Coghlana497b442012-05-22 23:02:00 +1000297 .. versionadded:: 3.3
298
Nick Coghlan3267a302012-05-21 22:54:43 +1000299 .. method:: enter_context(cm)
300
301 Enters a new context manager and adds its :meth:`__exit__` method to
302 the callback stack. The return value is the result of the context
303 manager's own :meth:`__enter__` method.
304
305 These context managers may suppress exceptions just as they normally
Nick Coghlan27228272012-05-31 22:17:08 +1000306 would if used directly as part of a :keyword:`with` statement.
Nick Coghlan3267a302012-05-21 22:54:43 +1000307
308 .. method:: push(exit)
309
310 Adds a context manager's :meth:`__exit__` method to the callback stack.
311
312 As ``__enter__`` is *not* invoked, this method can be used to cover
313 part of an :meth:`__enter__` implementation with a context manager's own
314 :meth:`__exit__` method.
315
316 If passed an object that is not a context manager, this method assumes
317 it is a callback with the same signature as a context manager's
318 :meth:`__exit__` method and adds it directly to the callback stack.
319
320 By returning true values, these callbacks can suppress exceptions the
321 same way context manager :meth:`__exit__` methods can.
322
323 The passed in object is returned from the function, allowing this
Nick Coghlan27228272012-05-31 22:17:08 +1000324 method to be used as a function decorator.
Nick Coghlan3267a302012-05-21 22:54:43 +1000325
326 .. method:: callback(callback, *args, **kwds)
327
328 Accepts an arbitrary callback function and arguments and adds it to
329 the callback stack.
330
331 Unlike the other methods, callbacks added this way cannot suppress
332 exceptions (as they are never passed the exception details).
333
334 The passed in callback is returned from the function, allowing this
Nick Coghlan27228272012-05-31 22:17:08 +1000335 method to be used as a function decorator.
Nick Coghlan3267a302012-05-21 22:54:43 +1000336
337 .. method:: pop_all()
338
339 Transfers the callback stack to a fresh :class:`ExitStack` instance
340 and returns it. No callbacks are invoked by this operation - instead,
341 they will now be invoked when the new stack is closed (either
Nick Coghlan27228272012-05-31 22:17:08 +1000342 explicitly or implicitly at the end of a :keyword:`with` statement).
Nick Coghlan3267a302012-05-21 22:54:43 +1000343
344 For example, a group of files can be opened as an "all or nothing"
345 operation as follows::
346
347 with ExitStack() as stack:
348 files = [stack.enter_context(open(fname)) for fname in filenames]
Barry Warsawd8f870d2013-05-10 11:35:38 -0400349 # Hold onto the close method, but don't call it yet.
350 close_files = stack.pop_all().close
Nick Coghlan3267a302012-05-21 22:54:43 +1000351 # If opening any file fails, all previously opened files will be
352 # closed automatically. If all files are opened successfully,
353 # they will remain open even after the with statement ends.
Barry Warsawd8f870d2013-05-10 11:35:38 -0400354 # close_files() can then be invoked explicitly to close them all.
Nick Coghlan3267a302012-05-21 22:54:43 +1000355
356 .. method:: close()
357
358 Immediately unwinds the callback stack, invoking callbacks in the
359 reverse order of registration. For any context managers and exit
360 callbacks registered, the arguments passed in will indicate that no
361 exception occurred.
362
Nick Coghlan3267a302012-05-21 22:54:43 +1000363
364Examples and Recipes
365--------------------
366
367This section describes some examples and recipes for making effective use of
368the tools provided by :mod:`contextlib`.
369
370
Nick Coghlan27228272012-05-31 22:17:08 +1000371Supporting a variable number of context managers
372^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
373
374The primary use case for :class:`ExitStack` is the one given in the class
375documentation: supporting a variable number of context managers and other
376cleanup operations in a single :keyword:`with` statement. The variability
377may come from the number of context managers needed being driven by user
378input (such as opening a user specified collection of files), or from
379some of the context managers being optional::
380
381 with ExitStack() as stack:
382 for resource in resources:
383 stack.enter_context(resource)
Raymond Hettingere8e2df32014-05-25 18:06:04 -0700384 if need_special_resource():
Nick Coghlan27228272012-05-31 22:17:08 +1000385 special = acquire_special_resource()
386 stack.callback(release_special_resource, special)
387 # Perform operations that use the acquired resources
388
389As shown, :class:`ExitStack` also makes it quite easy to use :keyword:`with`
390statements to manage arbitrary resources that don't natively support the
391context management protocol.
392
393
394Simplifying support for single optional context managers
395^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
396
397In the specific case of a single optional context manager, :class:`ExitStack`
398instances can be used as a "do nothing" context manager, allowing a context
Nick Coghlanb7a455f2012-05-31 22:34:59 +1000399manager to easily be omitted without affecting the overall structure of
Nick Coghlan27228272012-05-31 22:17:08 +1000400the source code::
401
402 def debug_trace(details):
403 if __debug__:
404 return TraceContext(details)
405 # Don't do anything special with the context in release mode
406 return ExitStack()
407
408 with debug_trace():
409 # Suite is traced in debug mode, but runs normally otherwise
410
411
412Catching exceptions from ``__enter__`` methods
413^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
414
415It is occasionally desirable to catch exceptions from an ``__enter__``
416method implementation, *without* inadvertently catching exceptions from
417the :keyword:`with` statement body or the context manager's ``__exit__``
418method. By using :class:`ExitStack` the steps in the context management
419protocol can be separated slightly in order to allow this::
420
421 stack = ExitStack()
422 try:
423 x = stack.enter_context(cm)
424 except Exception:
425 # handle __enter__ exception
426 else:
427 with stack:
428 # Handle normal case
429
430Actually needing to do this is likely to indicate that the underlying API
431should be providing a direct resource management interface for use with
432:keyword:`try`/:keyword:`except`/:keyword:`finally` statements, but not
433all APIs are well designed in that regard. When a context manager is the
434only resource management API provided, then :class:`ExitStack` can make it
435easier to handle various situations that can't be handled directly in a
436:keyword:`with` statement.
437
438
Nick Coghlan3267a302012-05-21 22:54:43 +1000439Cleaning up in an ``__enter__`` implementation
440^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
441
442As noted in the documentation of :meth:`ExitStack.push`, this
443method can be useful in cleaning up an already allocated resource if later
444steps in the :meth:`__enter__` implementation fail.
445
446Here's an example of doing this for a context manager that accepts resource
447acquisition and release functions, along with an optional validation function,
448and maps them to the context management protocol::
449
450 from contextlib import contextmanager, ExitStack
451
Ezio Melottic9cfcf12013-03-11 09:42:40 +0200452 class ResourceManager:
Nick Coghlan3267a302012-05-21 22:54:43 +1000453
454 def __init__(self, acquire_resource, release_resource, check_resource_ok=None):
455 self.acquire_resource = acquire_resource
456 self.release_resource = release_resource
457 if check_resource_ok is None:
458 def check_resource_ok(resource):
459 return True
460 self.check_resource_ok = check_resource_ok
461
462 @contextmanager
463 def _cleanup_on_error(self):
464 with ExitStack() as stack:
465 stack.push(self)
466 yield
467 # The validation check passed and didn't raise an exception
468 # Accordingly, we want to keep the resource, and pass it
469 # back to our caller
470 stack.pop_all()
471
472 def __enter__(self):
473 resource = self.acquire_resource()
474 with self._cleanup_on_error():
475 if not self.check_resource_ok(resource):
476 msg = "Failed validation for {!r}"
477 raise RuntimeError(msg.format(resource))
478 return resource
479
480 def __exit__(self, *exc_details):
481 # We don't need to duplicate any of our resource release logic
482 self.release_resource()
483
484
485Replacing any use of ``try-finally`` and flag variables
486^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
487
488A pattern you will sometimes see is a ``try-finally`` statement with a flag
489variable to indicate whether or not the body of the ``finally`` clause should
490be executed. In its simplest form (that can't already be handled just by
491using an ``except`` clause instead), it looks something like this::
492
493 cleanup_needed = True
494 try:
495 result = perform_operation()
496 if result:
497 cleanup_needed = False
498 finally:
499 if cleanup_needed:
500 cleanup_resources()
501
502As with any ``try`` statement based code, this can cause problems for
503development and review, because the setup code and the cleanup code can end
504up being separated by arbitrarily long sections of code.
505
506:class:`ExitStack` makes it possible to instead register a callback for
507execution at the end of a ``with`` statement, and then later decide to skip
508executing that callback::
509
510 from contextlib import ExitStack
511
512 with ExitStack() as stack:
513 stack.callback(cleanup_resources)
514 result = perform_operation()
515 if result:
516 stack.pop_all()
517
518This allows the intended cleanup up behaviour to be made explicit up front,
519rather than requiring a separate flag variable.
520
521If a particular application uses this pattern a lot, it can be simplified
522even further by means of a small helper class::
523
524 from contextlib import ExitStack
525
526 class Callback(ExitStack):
527 def __init__(self, callback, *args, **kwds):
528 super(Callback, self).__init__()
529 self.callback(callback, *args, **kwds)
530
531 def cancel(self):
532 self.pop_all()
533
534 with Callback(cleanup_resources) as cb:
535 result = perform_operation()
536 if result:
537 cb.cancel()
538
539If the resource cleanup isn't already neatly bundled into a standalone
540function, then it is still possible to use the decorator form of
541:meth:`ExitStack.callback` to declare the resource cleanup in
542advance::
543
544 from contextlib import ExitStack
545
546 with ExitStack() as stack:
547 @stack.callback
548 def cleanup_resources():
549 ...
550 result = perform_operation()
551 if result:
552 stack.pop_all()
553
554Due to the way the decorator protocol works, a callback function
555declared this way cannot take any parameters. Instead, any resources to
Martin Panterd21e0b52015-10-10 10:36:22 +0000556be released must be accessed as closure variables.
Nick Coghlan3267a302012-05-21 22:54:43 +1000557
558
559Using a context manager as a function decorator
560^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
561
562:class:`ContextDecorator` makes it possible to use a context manager in
563both an ordinary ``with`` statement and also as a function decorator.
564
565For example, it is sometimes useful to wrap functions or groups of statements
566with a logger that can track the time of entry and time of exit. Rather than
567writing both a function decorator and a context manager for the task,
568inheriting from :class:`ContextDecorator` provides both capabilities in a
569single definition::
570
571 from contextlib import ContextDecorator
572 import logging
573
574 logging.basicConfig(level=logging.INFO)
575
576 class track_entry_and_exit(ContextDecorator):
577 def __init__(self, name):
578 self.name = name
579
580 def __enter__(self):
Terry Jan Reedyf9bd9202014-10-10 16:00:18 -0400581 logging.info('Entering: {}'.format(self.name))
Nick Coghlan3267a302012-05-21 22:54:43 +1000582
583 def __exit__(self, exc_type, exc, exc_tb):
Terry Jan Reedyf9bd9202014-10-10 16:00:18 -0400584 logging.info('Exiting: {}'.format(self.name))
Nick Coghlan3267a302012-05-21 22:54:43 +1000585
586Instances of this class can be used as both a context manager::
587
588 with track_entry_and_exit('widget loader'):
589 print('Some time consuming activity goes here')
590 load_widget()
591
592And also as a function decorator::
593
594 @track_entry_and_exit('widget loader')
595 def activity():
596 print('Some time consuming activity goes here')
597 load_widget()
598
599Note that there is one additional limitation when using context managers
600as function decorators: there's no way to access the return value of
601:meth:`__enter__`. If that value is needed, then it is still necessary to use
602an explicit ``with`` statement.
603
Georg Brandl116aa622007-08-15 14:28:22 +0000604.. seealso::
605
Serhiy Storchakae4ba8722016-03-31 15:30:54 +0300606 :pep:`343` - The "with" statement
Georg Brandl116aa622007-08-15 14:28:22 +0000607 The specification, background, and examples for the Python :keyword:`with`
608 statement.
609
Nick Coghlan0acceb72013-10-20 13:22:21 +1000610.. _single-use-reusable-and-reentrant-cms:
Nick Coghlan8608d262013-10-20 00:30:51 +1000611
Nick Coghlan0acceb72013-10-20 13:22:21 +1000612Single use, reusable and reentrant context managers
613---------------------------------------------------
Nick Coghlan8608d262013-10-20 00:30:51 +1000614
615Most context managers are written in a way that means they can only be
616used effectively in a :keyword:`with` statement once. These single use
617context managers must be created afresh each time they're used -
618attempting to use them a second time will trigger an exception or
619otherwise not work correctly.
620
621This common limitation means that it is generally advisable to create
622context managers directly in the header of the :keyword:`with` statement
623where they are used (as shown in all of the usage examples above).
624
625Files are an example of effectively single use context managers, since
626the first :keyword:`with` statement will close the file, preventing any
627further IO operations using that file object.
628
629Context managers created using :func:`contextmanager` are also single use
630context managers, and will complain about the underlying generator failing
631to yield if an attempt is made to use them a second time::
632
633 >>> from contextlib import contextmanager
634 >>> @contextmanager
635 ... def singleuse():
636 ... print("Before")
637 ... yield
638 ... print("After")
639 ...
640 >>> cm = singleuse()
641 >>> with cm:
642 ... pass
643 ...
644 Before
645 After
646 >>> with cm:
Serhiy Storchakadba90392016-05-10 12:01:23 +0300647 ... pass
Nick Coghlan8608d262013-10-20 00:30:51 +1000648 ...
649 Traceback (most recent call last):
650 ...
651 RuntimeError: generator didn't yield
652
653
654.. _reentrant-cms:
655
656Reentrant context managers
657^^^^^^^^^^^^^^^^^^^^^^^^^^
658
659More sophisticated context managers may be "reentrant". These context
660managers can not only be used in multiple :keyword:`with` statements,
661but may also be used *inside* a :keyword:`with` statement that is already
662using the same context manager.
663
Nick Coghlan8e113b42013-11-03 17:00:51 +1000664:class:`threading.RLock` is an example of a reentrant context manager, as are
665:func:`suppress` and :func:`redirect_stdout`. Here's a very simple example of
666reentrant use::
Nick Coghlan8608d262013-10-20 00:30:51 +1000667
Nick Coghlan8e113b42013-11-03 17:00:51 +1000668 >>> from contextlib import redirect_stdout
669 >>> from io import StringIO
670 >>> stream = StringIO()
671 >>> write_to_stream = redirect_stdout(stream)
672 >>> with write_to_stream:
673 ... print("This is written to the stream rather than stdout")
674 ... with write_to_stream:
675 ... print("This is also written to the stream")
Nick Coghlan8608d262013-10-20 00:30:51 +1000676 ...
Nick Coghlan8e113b42013-11-03 17:00:51 +1000677 >>> print("This is written directly to stdout")
678 This is written directly to stdout
679 >>> print(stream.getvalue())
680 This is written to the stream rather than stdout
681 This is also written to the stream
682
683Real world examples of reentrancy are more likely to involve multiple
684functions calling each other and hence be far more complicated than this
685example.
686
687Note also that being reentrant is *not* the same thing as being thread safe.
688:func:`redirect_stdout`, for example, is definitely not thread safe, as it
689makes a global modification to the system state by binding :data:`sys.stdout`
690to a different stream.
Nick Coghlan8608d262013-10-20 00:30:51 +1000691
692
693.. _reusable-cms:
694
695Reusable context managers
696^^^^^^^^^^^^^^^^^^^^^^^^^
697
698Distinct from both single use and reentrant context managers are "reusable"
699context managers (or, to be completely explicit, "reusable, but not
700reentrant" context managers, since reentrant context managers are also
701reusable). These context managers support being used multiple times, but
702will fail (or otherwise not work correctly) if the specific context manager
703instance has already been used in a containing with statement.
704
Nick Coghlan8e113b42013-11-03 17:00:51 +1000705:class:`threading.Lock` is an example of a reusable, but not reentrant,
706context manager (for a reentrant lock, it is necessary to use
707:class:`threading.RLock` instead).
Nick Coghlan8608d262013-10-20 00:30:51 +1000708
Nick Coghlan8e113b42013-11-03 17:00:51 +1000709Another example of a reusable, but not reentrant, context manager is
710:class:`ExitStack`, as it invokes *all* currently registered callbacks
711when leaving any with statement, regardless of where those callbacks
712were added::
Nick Coghlan8608d262013-10-20 00:30:51 +1000713
Nick Coghlan8e113b42013-11-03 17:00:51 +1000714 >>> from contextlib import ExitStack
715 >>> stack = ExitStack()
716 >>> with stack:
717 ... stack.callback(print, "Callback: from first context")
718 ... print("Leaving first context")
Nick Coghlan8608d262013-10-20 00:30:51 +1000719 ...
Nick Coghlan8e113b42013-11-03 17:00:51 +1000720 Leaving first context
721 Callback: from first context
722 >>> with stack:
723 ... stack.callback(print, "Callback: from second context")
724 ... print("Leaving second context")
725 ...
726 Leaving second context
727 Callback: from second context
728 >>> with stack:
729 ... stack.callback(print, "Callback: from outer context")
730 ... with stack:
731 ... stack.callback(print, "Callback: from inner context")
732 ... print("Leaving inner context")
733 ... print("Leaving outer context")
734 ...
735 Leaving inner context
736 Callback: from inner context
737 Callback: from outer context
738 Leaving outer context
739
740As the output from the example shows, reusing a single stack object across
741multiple with statements works correctly, but attempting to nest them
742will cause the stack to be cleared at the end of the innermost with
743statement, which is unlikely to be desirable behaviour.
744
745Using separate :class:`ExitStack` instances instead of reusing a single
746instance avoids that problem::
747
748 >>> from contextlib import ExitStack
749 >>> with ExitStack() as outer_stack:
750 ... outer_stack.callback(print, "Callback: from outer context")
751 ... with ExitStack() as inner_stack:
752 ... inner_stack.callback(print, "Callback: from inner context")
753 ... print("Leaving inner context")
754 ... print("Leaving outer context")
755 ...
756 Leaving inner context
757 Callback: from inner context
758 Leaving outer context
759 Callback: from outer context