blob: 7876e7aa1ae2e282033f5d189571fa5a5d0e2b8a [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
Brett Cannon9e080e02016-04-08 12:15:27 -070021.. class:: AbstractContextManager
22
23 An abstract base class for classes that implement
24 :meth:`object.__enter__` and :meth:`object.__exit__`. A default
25 implementation for :meth:`object.__enter__` is provided which returns
26 ``self`` while :meth:`object.__exit__` is an abstract method which by default
27 returns ``None``. See also the definition of :ref:`typecontextmanager`.
28
29 .. versionadded:: 3.6
30
31
32
Georg Brandl8a1caa22010-07-29 16:01:11 +000033.. decorator:: contextmanager
Georg Brandl116aa622007-08-15 14:28:22 +000034
Christian Heimesd8654cf2007-12-02 15:22:16 +000035 This function is a :term:`decorator` that can be used to define a factory
36 function for :keyword:`with` statement context managers, without needing to
37 create a class or separate :meth:`__enter__` and :meth:`__exit__` methods.
Georg Brandl116aa622007-08-15 14:28:22 +000038
39 A simple example (this is not recommended as a real way of generating HTML!)::
40
Georg Brandl116aa622007-08-15 14:28:22 +000041 from contextlib import contextmanager
42
43 @contextmanager
44 def tag(name):
Georg Brandl6911e3c2007-09-04 07:15:32 +000045 print("<%s>" % name)
Georg Brandl116aa622007-08-15 14:28:22 +000046 yield
Georg Brandl6911e3c2007-09-04 07:15:32 +000047 print("</%s>" % name)
Georg Brandl116aa622007-08-15 14:28:22 +000048
49 >>> with tag("h1"):
Georg Brandl6911e3c2007-09-04 07:15:32 +000050 ... print("foo")
Georg Brandl116aa622007-08-15 14:28:22 +000051 ...
52 <h1>
53 foo
54 </h1>
55
Georg Brandl9afde1c2007-11-01 20:32:30 +000056 The function being decorated must return a :term:`generator`-iterator when
57 called. This iterator must yield exactly one value, which will be bound to
58 the targets in the :keyword:`with` statement's :keyword:`as` clause, if any.
Georg Brandl116aa622007-08-15 14:28:22 +000059
60 At the point where the generator yields, the block nested in the :keyword:`with`
61 statement is executed. The generator is then resumed after the block is exited.
62 If an unhandled exception occurs in the block, it is reraised inside the
63 generator at the point where the yield occurred. Thus, you can use a
64 :keyword:`try`...\ :keyword:`except`...\ :keyword:`finally` statement to trap
65 the error (if any), or ensure that some cleanup takes place. If an exception is
66 trapped merely in order to log it or to perform some action (rather than to
67 suppress it entirely), the generator must reraise that exception. Otherwise the
68 generator context manager will indicate to the :keyword:`with` statement that
69 the exception has been handled, and execution will resume with the statement
70 immediately following the :keyword:`with` statement.
71
Nick Coghlan0ded3e32011-05-05 23:49:25 +100072 :func:`contextmanager` uses :class:`ContextDecorator` so the context managers
73 it creates can be used as decorators as well as in :keyword:`with` statements.
74 When used as a decorator, a new generator instance is implicitly created on
75 each function call (this allows the otherwise "one-shot" context managers
76 created by :func:`contextmanager` to meet the requirement that context
77 managers support multiple invocations in order to be used as decorators).
Michael Foordb3a89842010-06-30 12:17:50 +000078
79 .. versionchanged:: 3.2
80 Use of :class:`ContextDecorator`.
Georg Brandl116aa622007-08-15 14:28:22 +000081
Georg Brandl86e78d12010-07-18 13:43:32 +000082
Georg Brandl116aa622007-08-15 14:28:22 +000083.. function:: closing(thing)
84
85 Return a context manager that closes *thing* upon completion of the block. This
86 is basically equivalent to::
87
88 from contextlib import contextmanager
89
90 @contextmanager
91 def closing(thing):
92 try:
93 yield thing
94 finally:
95 thing.close()
96
97 And lets you write code like this::
98
Georg Brandl116aa622007-08-15 14:28:22 +000099 from contextlib import closing
Georg Brandl0f7ede42008-06-23 11:23:31 +0000100 from urllib.request import urlopen
Georg Brandl116aa622007-08-15 14:28:22 +0000101
Georg Brandl0f7ede42008-06-23 11:23:31 +0000102 with closing(urlopen('http://www.python.org')) as page:
Georg Brandl116aa622007-08-15 14:28:22 +0000103 for line in page:
Georg Brandl6911e3c2007-09-04 07:15:32 +0000104 print(line)
Georg Brandl116aa622007-08-15 14:28:22 +0000105
106 without needing to explicitly close ``page``. Even if an error occurs,
107 ``page.close()`` will be called when the :keyword:`with` block is exited.
108
Georg Brandla7c17e52013-10-13 22:25:10 +0200109
Nick Coghlan240f86d2013-10-17 23:40:57 +1000110.. function:: suppress(*exceptions)
Raymond Hettingere318a882013-03-10 22:26:51 -0700111
Nick Coghlan240f86d2013-10-17 23:40:57 +1000112 Return a context manager that suppresses any of the specified exceptions
113 if they occur in the body of a with statement and then resumes execution
114 with the first statement following the end of the with statement.
Raymond Hettingere318a882013-03-10 22:26:51 -0700115
Nick Coghlan240f86d2013-10-17 23:40:57 +1000116 As with any other mechanism that completely suppresses exceptions, this
117 context manager should be used only to cover very specific errors where
118 silently continuing with program execution is known to be the right
119 thing to do.
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000120
Raymond Hettingere318a882013-03-10 22:26:51 -0700121 For example::
122
Nick Coghlan240f86d2013-10-17 23:40:57 +1000123 from contextlib import suppress
Raymond Hettingere318a882013-03-10 22:26:51 -0700124
Nick Coghlan240f86d2013-10-17 23:40:57 +1000125 with suppress(FileNotFoundError):
Raymond Hettingere318a882013-03-10 22:26:51 -0700126 os.remove('somefile.tmp')
127
Nick Coghlan240f86d2013-10-17 23:40:57 +1000128 with suppress(FileNotFoundError):
129 os.remove('someotherfile.tmp')
130
Raymond Hettingere318a882013-03-10 22:26:51 -0700131 This code is equivalent to::
132
133 try:
134 os.remove('somefile.tmp')
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000135 except FileNotFoundError:
Raymond Hettingere318a882013-03-10 22:26:51 -0700136 pass
137
Nick Coghlan240f86d2013-10-17 23:40:57 +1000138 try:
139 os.remove('someotherfile.tmp')
140 except FileNotFoundError:
141 pass
142
Nick Coghlan8608d262013-10-20 00:30:51 +1000143 This context manager is :ref:`reentrant <reentrant-cms>`.
144
Raymond Hettingere318a882013-03-10 22:26:51 -0700145 .. versionadded:: 3.4
Georg Brandl116aa622007-08-15 14:28:22 +0000146
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000147
Raymond Hettinger088cbf22013-10-10 00:46:57 -0700148.. function:: redirect_stdout(new_target)
149
150 Context manager for temporarily redirecting :data:`sys.stdout` to
151 another file or file-like object.
152
153 This tool adds flexibility to existing functions or classes whose output
154 is hardwired to stdout.
155
156 For example, the output of :func:`help` normally is sent to *sys.stdout*.
Serhiy Storchakad65c9492015-11-02 14:10:23 +0200157 You can capture that output in a string by redirecting the output to an
Raymond Hettinger088cbf22013-10-10 00:46:57 -0700158 :class:`io.StringIO` object::
159
160 f = io.StringIO()
161 with redirect_stdout(f):
162 help(pow)
163 s = f.getvalue()
164
165 To send the output of :func:`help` to a file on disk, redirect the output
166 to a regular file::
167
168 with open('help.txt', 'w') as f:
169 with redirect_stdout(f):
170 help(pow)
171
172 To send the output of :func:`help` to *sys.stderr*::
173
174 with redirect_stdout(sys.stderr):
175 help(pow)
176
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000177 Note that the global side effect on :data:`sys.stdout` means that this
178 context manager is not suitable for use in library code and most threaded
179 applications. It also has no effect on the output of subprocesses.
180 However, it is still a useful approach for many utility scripts.
181
Nick Coghlan36d8ef92014-10-12 10:25:00 +1000182 This context manager is :ref:`reentrant <reentrant-cms>`.
Nick Coghlan8608d262013-10-20 00:30:51 +1000183
Raymond Hettinger088cbf22013-10-10 00:46:57 -0700184 .. versionadded:: 3.4
185
Georg Brandla7c17e52013-10-13 22:25:10 +0200186
Berker Peksagbb44fe02014-11-28 23:28:06 +0200187.. function:: redirect_stderr(new_target)
188
189 Similar to :func:`~contextlib.redirect_stdout` but redirecting
190 :data:`sys.stderr` to another file or file-like object.
191
192 This context manager is :ref:`reentrant <reentrant-cms>`.
193
194 .. versionadded:: 3.5
195
196
Michael Foordb3a89842010-06-30 12:17:50 +0000197.. class:: ContextDecorator()
198
199 A base class that enables a context manager to also be used as a decorator.
200
201 Context managers inheriting from ``ContextDecorator`` have to implement
202 ``__enter__`` and ``__exit__`` as normal. ``__exit__`` retains its optional
203 exception handling even when used as a decorator.
204
Georg Brandl86e78d12010-07-18 13:43:32 +0000205 ``ContextDecorator`` is used by :func:`contextmanager`, so you get this
206 functionality automatically.
207
208 Example of ``ContextDecorator``::
Michael Foordb3a89842010-06-30 12:17:50 +0000209
210 from contextlib import ContextDecorator
211
212 class mycontext(ContextDecorator):
Georg Brandl86e78d12010-07-18 13:43:32 +0000213 def __enter__(self):
214 print('Starting')
215 return self
Michael Foordb3a89842010-06-30 12:17:50 +0000216
Georg Brandl86e78d12010-07-18 13:43:32 +0000217 def __exit__(self, *exc):
218 print('Finishing')
219 return False
Michael Foordb3a89842010-06-30 12:17:50 +0000220
221 >>> @mycontext()
222 ... def function():
Georg Brandl86e78d12010-07-18 13:43:32 +0000223 ... print('The bit in the middle')
Michael Foordb3a89842010-06-30 12:17:50 +0000224 ...
225 >>> function()
226 Starting
227 The bit in the middle
228 Finishing
229
230 >>> with mycontext():
Georg Brandl86e78d12010-07-18 13:43:32 +0000231 ... print('The bit in the middle')
Michael Foordb3a89842010-06-30 12:17:50 +0000232 ...
233 Starting
234 The bit in the middle
235 Finishing
236
Georg Brandl86e78d12010-07-18 13:43:32 +0000237 This change is just syntactic sugar for any construct of the following form::
238
239 def f():
240 with cm():
241 # Do stuff
242
243 ``ContextDecorator`` lets you instead write::
244
245 @cm()
246 def f():
247 # Do stuff
248
249 It makes it clear that the ``cm`` applies to the whole function, rather than
250 just a piece of it (and saving an indentation level is nice, too).
251
Michael Foordb3a89842010-06-30 12:17:50 +0000252 Existing context managers that already have a base class can be extended by
253 using ``ContextDecorator`` as a mixin class::
254
255 from contextlib import ContextDecorator
256
257 class mycontext(ContextBaseClass, ContextDecorator):
Georg Brandl86e78d12010-07-18 13:43:32 +0000258 def __enter__(self):
259 return self
Michael Foordb3a89842010-06-30 12:17:50 +0000260
Georg Brandl86e78d12010-07-18 13:43:32 +0000261 def __exit__(self, *exc):
262 return False
Michael Foordb3a89842010-06-30 12:17:50 +0000263
Nick Coghlan0ded3e32011-05-05 23:49:25 +1000264 .. note::
265 As the decorated function must be able to be called multiple times, the
266 underlying context manager must support use in multiple :keyword:`with`
267 statements. If this is not the case, then the original construct with the
268 explicit :keyword:`with` statement inside the function should be used.
269
Michael Foordb3a89842010-06-30 12:17:50 +0000270 .. versionadded:: 3.2
271
272
Nick Coghlan3267a302012-05-21 22:54:43 +1000273.. class:: ExitStack()
274
275 A context manager that is designed to make it easy to programmatically
276 combine other context managers and cleanup functions, especially those
277 that are optional or otherwise driven by input data.
278
279 For example, a set of files may easily be handled in a single with
280 statement as follows::
281
282 with ExitStack() as stack:
283 files = [stack.enter_context(open(fname)) for fname in filenames]
284 # All opened files will automatically be closed at the end of
285 # the with statement, even if attempts to open files later
Andrew Svetlov5b898402012-12-18 21:26:36 +0200286 # in the list raise an exception
Nick Coghlan3267a302012-05-21 22:54:43 +1000287
288 Each instance maintains a stack of registered callbacks that are called in
289 reverse order when the instance is closed (either explicitly or implicitly
Nick Coghlan27228272012-05-31 22:17:08 +1000290 at the end of a :keyword:`with` statement). Note that callbacks are *not*
291 invoked implicitly when the context stack instance is garbage collected.
Nick Coghlan3267a302012-05-21 22:54:43 +1000292
293 This stack model is used so that context managers that acquire their
294 resources in their ``__init__`` method (such as file objects) can be
295 handled correctly.
296
297 Since registered callbacks are invoked in the reverse order of
Nick Coghlan27228272012-05-31 22:17:08 +1000298 registration, this ends up behaving as if multiple nested :keyword:`with`
Nick Coghlan3267a302012-05-21 22:54:43 +1000299 statements had been used with the registered set of callbacks. This even
300 extends to exception handling - if an inner callback suppresses or replaces
301 an exception, then outer callbacks will be passed arguments based on that
302 updated state.
303
304 This is a relatively low level API that takes care of the details of
305 correctly unwinding the stack of exit callbacks. It provides a suitable
306 foundation for higher level context managers that manipulate the exit
307 stack in application specific ways.
308
Nick Coghlana497b442012-05-22 23:02:00 +1000309 .. versionadded:: 3.3
310
Nick Coghlan3267a302012-05-21 22:54:43 +1000311 .. method:: enter_context(cm)
312
313 Enters a new context manager and adds its :meth:`__exit__` method to
314 the callback stack. The return value is the result of the context
315 manager's own :meth:`__enter__` method.
316
317 These context managers may suppress exceptions just as they normally
Nick Coghlan27228272012-05-31 22:17:08 +1000318 would if used directly as part of a :keyword:`with` statement.
Nick Coghlan3267a302012-05-21 22:54:43 +1000319
320 .. method:: push(exit)
321
322 Adds a context manager's :meth:`__exit__` method to the callback stack.
323
324 As ``__enter__`` is *not* invoked, this method can be used to cover
325 part of an :meth:`__enter__` implementation with a context manager's own
326 :meth:`__exit__` method.
327
328 If passed an object that is not a context manager, this method assumes
329 it is a callback with the same signature as a context manager's
330 :meth:`__exit__` method and adds it directly to the callback stack.
331
332 By returning true values, these callbacks can suppress exceptions the
333 same way context manager :meth:`__exit__` methods can.
334
335 The passed in object is returned from the function, allowing this
Nick Coghlan27228272012-05-31 22:17:08 +1000336 method to be used as a function decorator.
Nick Coghlan3267a302012-05-21 22:54:43 +1000337
338 .. method:: callback(callback, *args, **kwds)
339
340 Accepts an arbitrary callback function and arguments and adds it to
341 the callback stack.
342
343 Unlike the other methods, callbacks added this way cannot suppress
344 exceptions (as they are never passed the exception details).
345
346 The passed in callback is returned from the function, allowing this
Nick Coghlan27228272012-05-31 22:17:08 +1000347 method to be used as a function decorator.
Nick Coghlan3267a302012-05-21 22:54:43 +1000348
349 .. method:: pop_all()
350
351 Transfers the callback stack to a fresh :class:`ExitStack` instance
352 and returns it. No callbacks are invoked by this operation - instead,
353 they will now be invoked when the new stack is closed (either
Nick Coghlan27228272012-05-31 22:17:08 +1000354 explicitly or implicitly at the end of a :keyword:`with` statement).
Nick Coghlan3267a302012-05-21 22:54:43 +1000355
356 For example, a group of files can be opened as an "all or nothing"
357 operation as follows::
358
359 with ExitStack() as stack:
360 files = [stack.enter_context(open(fname)) for fname in filenames]
Barry Warsawd8f870d2013-05-10 11:35:38 -0400361 # Hold onto the close method, but don't call it yet.
362 close_files = stack.pop_all().close
Nick Coghlan3267a302012-05-21 22:54:43 +1000363 # If opening any file fails, all previously opened files will be
364 # closed automatically. If all files are opened successfully,
365 # they will remain open even after the with statement ends.
Barry Warsawd8f870d2013-05-10 11:35:38 -0400366 # close_files() can then be invoked explicitly to close them all.
Nick Coghlan3267a302012-05-21 22:54:43 +1000367
368 .. method:: close()
369
370 Immediately unwinds the callback stack, invoking callbacks in the
371 reverse order of registration. For any context managers and exit
372 callbacks registered, the arguments passed in will indicate that no
373 exception occurred.
374
Nick Coghlan3267a302012-05-21 22:54:43 +1000375
376Examples and Recipes
377--------------------
378
379This section describes some examples and recipes for making effective use of
380the tools provided by :mod:`contextlib`.
381
382
Nick Coghlan27228272012-05-31 22:17:08 +1000383Supporting a variable number of context managers
384^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
385
386The primary use case for :class:`ExitStack` is the one given in the class
387documentation: supporting a variable number of context managers and other
388cleanup operations in a single :keyword:`with` statement. The variability
389may come from the number of context managers needed being driven by user
390input (such as opening a user specified collection of files), or from
391some of the context managers being optional::
392
393 with ExitStack() as stack:
394 for resource in resources:
395 stack.enter_context(resource)
Raymond Hettingere8e2df32014-05-25 18:06:04 -0700396 if need_special_resource():
Nick Coghlan27228272012-05-31 22:17:08 +1000397 special = acquire_special_resource()
398 stack.callback(release_special_resource, special)
399 # Perform operations that use the acquired resources
400
401As shown, :class:`ExitStack` also makes it quite easy to use :keyword:`with`
402statements to manage arbitrary resources that don't natively support the
403context management protocol.
404
405
406Simplifying support for single optional context managers
407^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
408
409In the specific case of a single optional context manager, :class:`ExitStack`
410instances can be used as a "do nothing" context manager, allowing a context
Nick Coghlanb7a455f2012-05-31 22:34:59 +1000411manager to easily be omitted without affecting the overall structure of
Nick Coghlan27228272012-05-31 22:17:08 +1000412the source code::
413
414 def debug_trace(details):
415 if __debug__:
416 return TraceContext(details)
417 # Don't do anything special with the context in release mode
418 return ExitStack()
419
420 with debug_trace():
421 # Suite is traced in debug mode, but runs normally otherwise
422
423
424Catching exceptions from ``__enter__`` methods
425^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
426
427It is occasionally desirable to catch exceptions from an ``__enter__``
428method implementation, *without* inadvertently catching exceptions from
429the :keyword:`with` statement body or the context manager's ``__exit__``
430method. By using :class:`ExitStack` the steps in the context management
431protocol can be separated slightly in order to allow this::
432
433 stack = ExitStack()
434 try:
435 x = stack.enter_context(cm)
436 except Exception:
437 # handle __enter__ exception
438 else:
439 with stack:
440 # Handle normal case
441
442Actually needing to do this is likely to indicate that the underlying API
443should be providing a direct resource management interface for use with
444:keyword:`try`/:keyword:`except`/:keyword:`finally` statements, but not
445all APIs are well designed in that regard. When a context manager is the
446only resource management API provided, then :class:`ExitStack` can make it
447easier to handle various situations that can't be handled directly in a
448:keyword:`with` statement.
449
450
Nick Coghlan3267a302012-05-21 22:54:43 +1000451Cleaning up in an ``__enter__`` implementation
452^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
453
454As noted in the documentation of :meth:`ExitStack.push`, this
455method can be useful in cleaning up an already allocated resource if later
456steps in the :meth:`__enter__` implementation fail.
457
458Here's an example of doing this for a context manager that accepts resource
459acquisition and release functions, along with an optional validation function,
460and maps them to the context management protocol::
461
Brett Cannon9e080e02016-04-08 12:15:27 -0700462 from contextlib import contextmanager, AbstractContextManager, ExitStack
Nick Coghlan3267a302012-05-21 22:54:43 +1000463
Brett Cannon9e080e02016-04-08 12:15:27 -0700464 class ResourceManager(AbstractContextManager):
Nick Coghlan3267a302012-05-21 22:54:43 +1000465
466 def __init__(self, acquire_resource, release_resource, check_resource_ok=None):
467 self.acquire_resource = acquire_resource
468 self.release_resource = release_resource
469 if check_resource_ok is None:
470 def check_resource_ok(resource):
471 return True
472 self.check_resource_ok = check_resource_ok
473
474 @contextmanager
475 def _cleanup_on_error(self):
476 with ExitStack() as stack:
477 stack.push(self)
478 yield
479 # The validation check passed and didn't raise an exception
480 # Accordingly, we want to keep the resource, and pass it
481 # back to our caller
482 stack.pop_all()
483
484 def __enter__(self):
485 resource = self.acquire_resource()
486 with self._cleanup_on_error():
487 if not self.check_resource_ok(resource):
488 msg = "Failed validation for {!r}"
489 raise RuntimeError(msg.format(resource))
490 return resource
491
492 def __exit__(self, *exc_details):
493 # We don't need to duplicate any of our resource release logic
494 self.release_resource()
495
496
497Replacing any use of ``try-finally`` and flag variables
498^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
499
500A pattern you will sometimes see is a ``try-finally`` statement with a flag
501variable to indicate whether or not the body of the ``finally`` clause should
502be executed. In its simplest form (that can't already be handled just by
503using an ``except`` clause instead), it looks something like this::
504
505 cleanup_needed = True
506 try:
507 result = perform_operation()
508 if result:
509 cleanup_needed = False
510 finally:
511 if cleanup_needed:
512 cleanup_resources()
513
514As with any ``try`` statement based code, this can cause problems for
515development and review, because the setup code and the cleanup code can end
516up being separated by arbitrarily long sections of code.
517
518:class:`ExitStack` makes it possible to instead register a callback for
519execution at the end of a ``with`` statement, and then later decide to skip
520executing that callback::
521
522 from contextlib import ExitStack
523
524 with ExitStack() as stack:
525 stack.callback(cleanup_resources)
526 result = perform_operation()
527 if result:
528 stack.pop_all()
529
530This allows the intended cleanup up behaviour to be made explicit up front,
531rather than requiring a separate flag variable.
532
533If a particular application uses this pattern a lot, it can be simplified
534even further by means of a small helper class::
535
536 from contextlib import ExitStack
537
538 class Callback(ExitStack):
539 def __init__(self, callback, *args, **kwds):
540 super(Callback, self).__init__()
541 self.callback(callback, *args, **kwds)
542
543 def cancel(self):
544 self.pop_all()
545
546 with Callback(cleanup_resources) as cb:
547 result = perform_operation()
548 if result:
549 cb.cancel()
550
551If the resource cleanup isn't already neatly bundled into a standalone
552function, then it is still possible to use the decorator form of
553:meth:`ExitStack.callback` to declare the resource cleanup in
554advance::
555
556 from contextlib import ExitStack
557
558 with ExitStack() as stack:
559 @stack.callback
560 def cleanup_resources():
561 ...
562 result = perform_operation()
563 if result:
564 stack.pop_all()
565
566Due to the way the decorator protocol works, a callback function
567declared this way cannot take any parameters. Instead, any resources to
Martin Panterd21e0b52015-10-10 10:36:22 +0000568be released must be accessed as closure variables.
Nick Coghlan3267a302012-05-21 22:54:43 +1000569
570
571Using a context manager as a function decorator
572^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
573
574:class:`ContextDecorator` makes it possible to use a context manager in
575both an ordinary ``with`` statement and also as a function decorator.
576
577For example, it is sometimes useful to wrap functions or groups of statements
578with a logger that can track the time of entry and time of exit. Rather than
579writing both a function decorator and a context manager for the task,
580inheriting from :class:`ContextDecorator` provides both capabilities in a
581single definition::
582
583 from contextlib import ContextDecorator
584 import logging
585
586 logging.basicConfig(level=logging.INFO)
587
588 class track_entry_and_exit(ContextDecorator):
589 def __init__(self, name):
590 self.name = name
591
592 def __enter__(self):
Terry Jan Reedyf9bd9202014-10-10 16:00:18 -0400593 logging.info('Entering: {}'.format(self.name))
Nick Coghlan3267a302012-05-21 22:54:43 +1000594
595 def __exit__(self, exc_type, exc, exc_tb):
Terry Jan Reedyf9bd9202014-10-10 16:00:18 -0400596 logging.info('Exiting: {}'.format(self.name))
Nick Coghlan3267a302012-05-21 22:54:43 +1000597
598Instances of this class can be used as both a context manager::
599
600 with track_entry_and_exit('widget loader'):
601 print('Some time consuming activity goes here')
602 load_widget()
603
604And also as a function decorator::
605
606 @track_entry_and_exit('widget loader')
607 def activity():
608 print('Some time consuming activity goes here')
609 load_widget()
610
611Note that there is one additional limitation when using context managers
612as function decorators: there's no way to access the return value of
613:meth:`__enter__`. If that value is needed, then it is still necessary to use
614an explicit ``with`` statement.
615
Georg Brandl116aa622007-08-15 14:28:22 +0000616.. seealso::
617
Serhiy Storchakae4ba8722016-03-31 15:30:54 +0300618 :pep:`343` - The "with" statement
Georg Brandl116aa622007-08-15 14:28:22 +0000619 The specification, background, and examples for the Python :keyword:`with`
620 statement.
621
Nick Coghlan0acceb72013-10-20 13:22:21 +1000622.. _single-use-reusable-and-reentrant-cms:
Nick Coghlan8608d262013-10-20 00:30:51 +1000623
Nick Coghlan0acceb72013-10-20 13:22:21 +1000624Single use, reusable and reentrant context managers
625---------------------------------------------------
Nick Coghlan8608d262013-10-20 00:30:51 +1000626
627Most context managers are written in a way that means they can only be
628used effectively in a :keyword:`with` statement once. These single use
629context managers must be created afresh each time they're used -
630attempting to use them a second time will trigger an exception or
631otherwise not work correctly.
632
633This common limitation means that it is generally advisable to create
634context managers directly in the header of the :keyword:`with` statement
635where they are used (as shown in all of the usage examples above).
636
637Files are an example of effectively single use context managers, since
638the first :keyword:`with` statement will close the file, preventing any
639further IO operations using that file object.
640
641Context managers created using :func:`contextmanager` are also single use
642context managers, and will complain about the underlying generator failing
643to yield if an attempt is made to use them a second time::
644
645 >>> from contextlib import contextmanager
646 >>> @contextmanager
647 ... def singleuse():
648 ... print("Before")
649 ... yield
650 ... print("After")
651 ...
652 >>> cm = singleuse()
653 >>> with cm:
654 ... pass
655 ...
656 Before
657 After
658 >>> with cm:
659 ... pass
660 ...
661 Traceback (most recent call last):
662 ...
663 RuntimeError: generator didn't yield
664
665
666.. _reentrant-cms:
667
668Reentrant context managers
669^^^^^^^^^^^^^^^^^^^^^^^^^^
670
671More sophisticated context managers may be "reentrant". These context
672managers can not only be used in multiple :keyword:`with` statements,
673but may also be used *inside* a :keyword:`with` statement that is already
674using the same context manager.
675
Nick Coghlan8e113b42013-11-03 17:00:51 +1000676:class:`threading.RLock` is an example of a reentrant context manager, as are
677:func:`suppress` and :func:`redirect_stdout`. Here's a very simple example of
678reentrant use::
Nick Coghlan8608d262013-10-20 00:30:51 +1000679
Nick Coghlan8e113b42013-11-03 17:00:51 +1000680 >>> from contextlib import redirect_stdout
681 >>> from io import StringIO
682 >>> stream = StringIO()
683 >>> write_to_stream = redirect_stdout(stream)
684 >>> with write_to_stream:
685 ... print("This is written to the stream rather than stdout")
686 ... with write_to_stream:
687 ... print("This is also written to the stream")
Nick Coghlan8608d262013-10-20 00:30:51 +1000688 ...
Nick Coghlan8e113b42013-11-03 17:00:51 +1000689 >>> print("This is written directly to stdout")
690 This is written directly to stdout
691 >>> print(stream.getvalue())
692 This is written to the stream rather than stdout
693 This is also written to the stream
694
695Real world examples of reentrancy are more likely to involve multiple
696functions calling each other and hence be far more complicated than this
697example.
698
699Note also that being reentrant is *not* the same thing as being thread safe.
700:func:`redirect_stdout`, for example, is definitely not thread safe, as it
701makes a global modification to the system state by binding :data:`sys.stdout`
702to a different stream.
Nick Coghlan8608d262013-10-20 00:30:51 +1000703
704
705.. _reusable-cms:
706
707Reusable context managers
708^^^^^^^^^^^^^^^^^^^^^^^^^
709
710Distinct from both single use and reentrant context managers are "reusable"
711context managers (or, to be completely explicit, "reusable, but not
712reentrant" context managers, since reentrant context managers are also
713reusable). These context managers support being used multiple times, but
714will fail (or otherwise not work correctly) if the specific context manager
715instance has already been used in a containing with statement.
716
Nick Coghlan8e113b42013-11-03 17:00:51 +1000717:class:`threading.Lock` is an example of a reusable, but not reentrant,
718context manager (for a reentrant lock, it is necessary to use
719:class:`threading.RLock` instead).
Nick Coghlan8608d262013-10-20 00:30:51 +1000720
Nick Coghlan8e113b42013-11-03 17:00:51 +1000721Another example of a reusable, but not reentrant, context manager is
722:class:`ExitStack`, as it invokes *all* currently registered callbacks
723when leaving any with statement, regardless of where those callbacks
724were added::
Nick Coghlan8608d262013-10-20 00:30:51 +1000725
Nick Coghlan8e113b42013-11-03 17:00:51 +1000726 >>> from contextlib import ExitStack
727 >>> stack = ExitStack()
728 >>> with stack:
729 ... stack.callback(print, "Callback: from first context")
730 ... print("Leaving first context")
Nick Coghlan8608d262013-10-20 00:30:51 +1000731 ...
Nick Coghlan8e113b42013-11-03 17:00:51 +1000732 Leaving first context
733 Callback: from first context
734 >>> with stack:
735 ... stack.callback(print, "Callback: from second context")
736 ... print("Leaving second context")
737 ...
738 Leaving second context
739 Callback: from second context
740 >>> with stack:
741 ... stack.callback(print, "Callback: from outer context")
742 ... with stack:
743 ... stack.callback(print, "Callback: from inner context")
744 ... print("Leaving inner context")
745 ... print("Leaving outer context")
746 ...
747 Leaving inner context
748 Callback: from inner context
749 Callback: from outer context
750 Leaving outer context
751
752As the output from the example shows, reusing a single stack object across
753multiple with statements works correctly, but attempting to nest them
754will cause the stack to be cleared at the end of the innermost with
755statement, which is unlikely to be desirable behaviour.
756
757Using separate :class:`ExitStack` instances instead of reusing a single
758instance avoids that problem::
759
760 >>> from contextlib import ExitStack
761 >>> with ExitStack() as outer_stack:
762 ... outer_stack.callback(print, "Callback: from outer context")
763 ... with ExitStack() as inner_stack:
764 ... inner_stack.callback(print, "Callback: from inner context")
765 ... print("Leaving inner context")
766 ... print("Leaving outer context")
767 ...
768 Leaving inner context
769 Callback: from inner context
770 Leaving outer context
771 Callback: from outer context