blob: 19793693b7ba68c9b41c09028ccbd086a2240493 [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
Brett Cannon516f5462016-06-09 15:55:52 -070023 An :term:`abstract base class` for classes that implement
Brett Cannon9e080e02016-04-08 12:15:27 -070024 :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
Jelle Zijlstra2e624692017-04-30 18:25:58 -070083.. decorator:: asynccontextmanager
84
85 Similar to :func:`~contextlib.contextmanager`, but creates an
86 :ref:`asynchronous context manager <async-context-managers>`.
87
88 This function is a :term:`decorator` that can be used to define a factory
89 function for :keyword:`async with` statement asynchronous context managers,
90 without needing to create a class or separate :meth:`__aenter__` and
91 :meth:`__aexit__` methods. It must be applied to an :term:`asynchronous
92 generator` function.
93
94 A simple example::
95
96 from contextlib import asynccontextmanager
97
98 @asynccontextmanager
99 async def get_connection():
100 conn = await acquire_db_connection()
101 try:
102 yield
103 finally:
104 await release_db_connection(conn)
105
106 async def get_all_users():
107 async with get_connection() as conn:
108 return conn.query('SELECT ...')
109
110 .. versionadded:: 3.7
111
112
Georg Brandl116aa622007-08-15 14:28:22 +0000113.. function:: closing(thing)
114
115 Return a context manager that closes *thing* upon completion of the block. This
116 is basically equivalent to::
117
118 from contextlib import contextmanager
119
120 @contextmanager
121 def closing(thing):
122 try:
123 yield thing
124 finally:
125 thing.close()
126
127 And lets you write code like this::
128
Georg Brandl116aa622007-08-15 14:28:22 +0000129 from contextlib import closing
Georg Brandl0f7ede42008-06-23 11:23:31 +0000130 from urllib.request import urlopen
Georg Brandl116aa622007-08-15 14:28:22 +0000131
Georg Brandl0f7ede42008-06-23 11:23:31 +0000132 with closing(urlopen('http://www.python.org')) as page:
Georg Brandl116aa622007-08-15 14:28:22 +0000133 for line in page:
Georg Brandl6911e3c2007-09-04 07:15:32 +0000134 print(line)
Georg Brandl116aa622007-08-15 14:28:22 +0000135
136 without needing to explicitly close ``page``. Even if an error occurs,
137 ``page.close()`` will be called when the :keyword:`with` block is exited.
138
Georg Brandla7c17e52013-10-13 22:25:10 +0200139
Nick Coghlan240f86d2013-10-17 23:40:57 +1000140.. function:: suppress(*exceptions)
Raymond Hettingere318a882013-03-10 22:26:51 -0700141
Nick Coghlan240f86d2013-10-17 23:40:57 +1000142 Return a context manager that suppresses any of the specified exceptions
143 if they occur in the body of a with statement and then resumes execution
144 with the first statement following the end of the with statement.
Raymond Hettingere318a882013-03-10 22:26:51 -0700145
Nick Coghlan240f86d2013-10-17 23:40:57 +1000146 As with any other mechanism that completely suppresses exceptions, this
147 context manager should be used only to cover very specific errors where
148 silently continuing with program execution is known to be the right
149 thing to do.
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000150
Raymond Hettingere318a882013-03-10 22:26:51 -0700151 For example::
152
Nick Coghlan240f86d2013-10-17 23:40:57 +1000153 from contextlib import suppress
Raymond Hettingere318a882013-03-10 22:26:51 -0700154
Nick Coghlan240f86d2013-10-17 23:40:57 +1000155 with suppress(FileNotFoundError):
Raymond Hettingere318a882013-03-10 22:26:51 -0700156 os.remove('somefile.tmp')
157
Nick Coghlan240f86d2013-10-17 23:40:57 +1000158 with suppress(FileNotFoundError):
159 os.remove('someotherfile.tmp')
160
Raymond Hettingere318a882013-03-10 22:26:51 -0700161 This code is equivalent to::
162
163 try:
164 os.remove('somefile.tmp')
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000165 except FileNotFoundError:
Raymond Hettingere318a882013-03-10 22:26:51 -0700166 pass
167
Nick Coghlan240f86d2013-10-17 23:40:57 +1000168 try:
169 os.remove('someotherfile.tmp')
170 except FileNotFoundError:
171 pass
172
Nick Coghlan8608d262013-10-20 00:30:51 +1000173 This context manager is :ref:`reentrant <reentrant-cms>`.
174
Raymond Hettingere318a882013-03-10 22:26:51 -0700175 .. versionadded:: 3.4
Georg Brandl116aa622007-08-15 14:28:22 +0000176
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000177
Raymond Hettinger088cbf22013-10-10 00:46:57 -0700178.. function:: redirect_stdout(new_target)
179
180 Context manager for temporarily redirecting :data:`sys.stdout` to
181 another file or file-like object.
182
183 This tool adds flexibility to existing functions or classes whose output
184 is hardwired to stdout.
185
186 For example, the output of :func:`help` normally is sent to *sys.stdout*.
Serhiy Storchakad65c9492015-11-02 14:10:23 +0200187 You can capture that output in a string by redirecting the output to an
Raymond Hettinger088cbf22013-10-10 00:46:57 -0700188 :class:`io.StringIO` object::
189
190 f = io.StringIO()
191 with redirect_stdout(f):
192 help(pow)
193 s = f.getvalue()
194
195 To send the output of :func:`help` to a file on disk, redirect the output
196 to a regular file::
197
198 with open('help.txt', 'w') as f:
199 with redirect_stdout(f):
200 help(pow)
201
202 To send the output of :func:`help` to *sys.stderr*::
203
204 with redirect_stdout(sys.stderr):
205 help(pow)
206
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000207 Note that the global side effect on :data:`sys.stdout` means that this
208 context manager is not suitable for use in library code and most threaded
209 applications. It also has no effect on the output of subprocesses.
210 However, it is still a useful approach for many utility scripts.
211
Nick Coghlan36d8ef92014-10-12 10:25:00 +1000212 This context manager is :ref:`reentrant <reentrant-cms>`.
Nick Coghlan8608d262013-10-20 00:30:51 +1000213
Raymond Hettinger088cbf22013-10-10 00:46:57 -0700214 .. versionadded:: 3.4
215
Georg Brandla7c17e52013-10-13 22:25:10 +0200216
Berker Peksagbb44fe02014-11-28 23:28:06 +0200217.. function:: redirect_stderr(new_target)
218
219 Similar to :func:`~contextlib.redirect_stdout` but redirecting
220 :data:`sys.stderr` to another file or file-like object.
221
222 This context manager is :ref:`reentrant <reentrant-cms>`.
223
224 .. versionadded:: 3.5
225
226
Michael Foordb3a89842010-06-30 12:17:50 +0000227.. class:: ContextDecorator()
228
229 A base class that enables a context manager to also be used as a decorator.
230
231 Context managers inheriting from ``ContextDecorator`` have to implement
232 ``__enter__`` and ``__exit__`` as normal. ``__exit__`` retains its optional
233 exception handling even when used as a decorator.
234
Georg Brandl86e78d12010-07-18 13:43:32 +0000235 ``ContextDecorator`` is used by :func:`contextmanager`, so you get this
236 functionality automatically.
237
238 Example of ``ContextDecorator``::
Michael Foordb3a89842010-06-30 12:17:50 +0000239
240 from contextlib import ContextDecorator
241
242 class mycontext(ContextDecorator):
Georg Brandl86e78d12010-07-18 13:43:32 +0000243 def __enter__(self):
244 print('Starting')
245 return self
Michael Foordb3a89842010-06-30 12:17:50 +0000246
Georg Brandl86e78d12010-07-18 13:43:32 +0000247 def __exit__(self, *exc):
248 print('Finishing')
249 return False
Michael Foordb3a89842010-06-30 12:17:50 +0000250
251 >>> @mycontext()
252 ... def function():
Georg Brandl86e78d12010-07-18 13:43:32 +0000253 ... print('The bit in the middle')
Michael Foordb3a89842010-06-30 12:17:50 +0000254 ...
255 >>> function()
256 Starting
257 The bit in the middle
258 Finishing
259
260 >>> with mycontext():
Georg Brandl86e78d12010-07-18 13:43:32 +0000261 ... print('The bit in the middle')
Michael Foordb3a89842010-06-30 12:17:50 +0000262 ...
263 Starting
264 The bit in the middle
265 Finishing
266
Georg Brandl86e78d12010-07-18 13:43:32 +0000267 This change is just syntactic sugar for any construct of the following form::
268
269 def f():
270 with cm():
271 # Do stuff
272
273 ``ContextDecorator`` lets you instead write::
274
275 @cm()
276 def f():
277 # Do stuff
278
279 It makes it clear that the ``cm`` applies to the whole function, rather than
280 just a piece of it (and saving an indentation level is nice, too).
281
Michael Foordb3a89842010-06-30 12:17:50 +0000282 Existing context managers that already have a base class can be extended by
283 using ``ContextDecorator`` as a mixin class::
284
285 from contextlib import ContextDecorator
286
287 class mycontext(ContextBaseClass, ContextDecorator):
Georg Brandl86e78d12010-07-18 13:43:32 +0000288 def __enter__(self):
289 return self
Michael Foordb3a89842010-06-30 12:17:50 +0000290
Georg Brandl86e78d12010-07-18 13:43:32 +0000291 def __exit__(self, *exc):
292 return False
Michael Foordb3a89842010-06-30 12:17:50 +0000293
Nick Coghlan0ded3e32011-05-05 23:49:25 +1000294 .. note::
295 As the decorated function must be able to be called multiple times, the
296 underlying context manager must support use in multiple :keyword:`with`
297 statements. If this is not the case, then the original construct with the
298 explicit :keyword:`with` statement inside the function should be used.
299
Michael Foordb3a89842010-06-30 12:17:50 +0000300 .. versionadded:: 3.2
301
302
Nick Coghlan3267a302012-05-21 22:54:43 +1000303.. class:: ExitStack()
304
305 A context manager that is designed to make it easy to programmatically
306 combine other context managers and cleanup functions, especially those
307 that are optional or otherwise driven by input data.
308
309 For example, a set of files may easily be handled in a single with
310 statement as follows::
311
312 with ExitStack() as stack:
313 files = [stack.enter_context(open(fname)) for fname in filenames]
314 # All opened files will automatically be closed at the end of
315 # the with statement, even if attempts to open files later
Andrew Svetlov5b898402012-12-18 21:26:36 +0200316 # in the list raise an exception
Nick Coghlan3267a302012-05-21 22:54:43 +1000317
318 Each instance maintains a stack of registered callbacks that are called in
319 reverse order when the instance is closed (either explicitly or implicitly
Nick Coghlan27228272012-05-31 22:17:08 +1000320 at the end of a :keyword:`with` statement). Note that callbacks are *not*
321 invoked implicitly when the context stack instance is garbage collected.
Nick Coghlan3267a302012-05-21 22:54:43 +1000322
323 This stack model is used so that context managers that acquire their
324 resources in their ``__init__`` method (such as file objects) can be
325 handled correctly.
326
327 Since registered callbacks are invoked in the reverse order of
Nick Coghlan27228272012-05-31 22:17:08 +1000328 registration, this ends up behaving as if multiple nested :keyword:`with`
Nick Coghlan3267a302012-05-21 22:54:43 +1000329 statements had been used with the registered set of callbacks. This even
330 extends to exception handling - if an inner callback suppresses or replaces
331 an exception, then outer callbacks will be passed arguments based on that
332 updated state.
333
334 This is a relatively low level API that takes care of the details of
335 correctly unwinding the stack of exit callbacks. It provides a suitable
336 foundation for higher level context managers that manipulate the exit
337 stack in application specific ways.
338
Nick Coghlana497b442012-05-22 23:02:00 +1000339 .. versionadded:: 3.3
340
Nick Coghlan3267a302012-05-21 22:54:43 +1000341 .. method:: enter_context(cm)
342
343 Enters a new context manager and adds its :meth:`__exit__` method to
344 the callback stack. The return value is the result of the context
345 manager's own :meth:`__enter__` method.
346
347 These context managers may suppress exceptions just as they normally
Nick Coghlan27228272012-05-31 22:17:08 +1000348 would if used directly as part of a :keyword:`with` statement.
Nick Coghlan3267a302012-05-21 22:54:43 +1000349
350 .. method:: push(exit)
351
352 Adds a context manager's :meth:`__exit__` method to the callback stack.
353
354 As ``__enter__`` is *not* invoked, this method can be used to cover
355 part of an :meth:`__enter__` implementation with a context manager's own
356 :meth:`__exit__` method.
357
358 If passed an object that is not a context manager, this method assumes
359 it is a callback with the same signature as a context manager's
360 :meth:`__exit__` method and adds it directly to the callback stack.
361
362 By returning true values, these callbacks can suppress exceptions the
363 same way context manager :meth:`__exit__` methods can.
364
365 The passed in object is returned from the function, allowing this
Nick Coghlan27228272012-05-31 22:17:08 +1000366 method to be used as a function decorator.
Nick Coghlan3267a302012-05-21 22:54:43 +1000367
368 .. method:: callback(callback, *args, **kwds)
369
370 Accepts an arbitrary callback function and arguments and adds it to
371 the callback stack.
372
373 Unlike the other methods, callbacks added this way cannot suppress
374 exceptions (as they are never passed the exception details).
375
376 The passed in callback is returned from the function, allowing this
Nick Coghlan27228272012-05-31 22:17:08 +1000377 method to be used as a function decorator.
Nick Coghlan3267a302012-05-21 22:54:43 +1000378
379 .. method:: pop_all()
380
381 Transfers the callback stack to a fresh :class:`ExitStack` instance
382 and returns it. No callbacks are invoked by this operation - instead,
383 they will now be invoked when the new stack is closed (either
Nick Coghlan27228272012-05-31 22:17:08 +1000384 explicitly or implicitly at the end of a :keyword:`with` statement).
Nick Coghlan3267a302012-05-21 22:54:43 +1000385
386 For example, a group of files can be opened as an "all or nothing"
387 operation as follows::
388
389 with ExitStack() as stack:
390 files = [stack.enter_context(open(fname)) for fname in filenames]
Barry Warsawd8f870d2013-05-10 11:35:38 -0400391 # Hold onto the close method, but don't call it yet.
392 close_files = stack.pop_all().close
Nick Coghlan3267a302012-05-21 22:54:43 +1000393 # If opening any file fails, all previously opened files will be
394 # closed automatically. If all files are opened successfully,
395 # they will remain open even after the with statement ends.
Barry Warsawd8f870d2013-05-10 11:35:38 -0400396 # close_files() can then be invoked explicitly to close them all.
Nick Coghlan3267a302012-05-21 22:54:43 +1000397
398 .. method:: close()
399
400 Immediately unwinds the callback stack, invoking callbacks in the
401 reverse order of registration. For any context managers and exit
402 callbacks registered, the arguments passed in will indicate that no
403 exception occurred.
404
Nick Coghlan3267a302012-05-21 22:54:43 +1000405
406Examples and Recipes
407--------------------
408
409This section describes some examples and recipes for making effective use of
410the tools provided by :mod:`contextlib`.
411
412
Nick Coghlan27228272012-05-31 22:17:08 +1000413Supporting a variable number of context managers
414^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
415
416The primary use case for :class:`ExitStack` is the one given in the class
417documentation: supporting a variable number of context managers and other
418cleanup operations in a single :keyword:`with` statement. The variability
419may come from the number of context managers needed being driven by user
420input (such as opening a user specified collection of files), or from
421some of the context managers being optional::
422
423 with ExitStack() as stack:
424 for resource in resources:
425 stack.enter_context(resource)
Raymond Hettingere8e2df32014-05-25 18:06:04 -0700426 if need_special_resource():
Nick Coghlan27228272012-05-31 22:17:08 +1000427 special = acquire_special_resource()
428 stack.callback(release_special_resource, special)
429 # Perform operations that use the acquired resources
430
431As shown, :class:`ExitStack` also makes it quite easy to use :keyword:`with`
432statements to manage arbitrary resources that don't natively support the
433context management protocol.
434
435
436Simplifying support for single optional context managers
437^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
438
439In the specific case of a single optional context manager, :class:`ExitStack`
440instances can be used as a "do nothing" context manager, allowing a context
Nick Coghlanb7a455f2012-05-31 22:34:59 +1000441manager to easily be omitted without affecting the overall structure of
Nick Coghlan27228272012-05-31 22:17:08 +1000442the source code::
443
444 def debug_trace(details):
445 if __debug__:
446 return TraceContext(details)
447 # Don't do anything special with the context in release mode
448 return ExitStack()
449
450 with debug_trace():
451 # Suite is traced in debug mode, but runs normally otherwise
452
453
454Catching exceptions from ``__enter__`` methods
455^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
456
457It is occasionally desirable to catch exceptions from an ``__enter__``
458method implementation, *without* inadvertently catching exceptions from
459the :keyword:`with` statement body or the context manager's ``__exit__``
460method. By using :class:`ExitStack` the steps in the context management
461protocol can be separated slightly in order to allow this::
462
463 stack = ExitStack()
464 try:
465 x = stack.enter_context(cm)
466 except Exception:
467 # handle __enter__ exception
468 else:
469 with stack:
470 # Handle normal case
471
472Actually needing to do this is likely to indicate that the underlying API
473should be providing a direct resource management interface for use with
474:keyword:`try`/:keyword:`except`/:keyword:`finally` statements, but not
475all APIs are well designed in that regard. When a context manager is the
476only resource management API provided, then :class:`ExitStack` can make it
477easier to handle various situations that can't be handled directly in a
478:keyword:`with` statement.
479
480
Nick Coghlan3267a302012-05-21 22:54:43 +1000481Cleaning up in an ``__enter__`` implementation
482^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
483
484As noted in the documentation of :meth:`ExitStack.push`, this
485method can be useful in cleaning up an already allocated resource if later
486steps in the :meth:`__enter__` implementation fail.
487
488Here's an example of doing this for a context manager that accepts resource
489acquisition and release functions, along with an optional validation function,
490and maps them to the context management protocol::
491
Brett Cannon9e080e02016-04-08 12:15:27 -0700492 from contextlib import contextmanager, AbstractContextManager, ExitStack
Nick Coghlan3267a302012-05-21 22:54:43 +1000493
Brett Cannon9e080e02016-04-08 12:15:27 -0700494 class ResourceManager(AbstractContextManager):
Nick Coghlan3267a302012-05-21 22:54:43 +1000495
496 def __init__(self, acquire_resource, release_resource, check_resource_ok=None):
497 self.acquire_resource = acquire_resource
498 self.release_resource = release_resource
499 if check_resource_ok is None:
500 def check_resource_ok(resource):
501 return True
502 self.check_resource_ok = check_resource_ok
503
504 @contextmanager
505 def _cleanup_on_error(self):
506 with ExitStack() as stack:
507 stack.push(self)
508 yield
509 # The validation check passed and didn't raise an exception
510 # Accordingly, we want to keep the resource, and pass it
511 # back to our caller
512 stack.pop_all()
513
514 def __enter__(self):
515 resource = self.acquire_resource()
516 with self._cleanup_on_error():
517 if not self.check_resource_ok(resource):
518 msg = "Failed validation for {!r}"
519 raise RuntimeError(msg.format(resource))
520 return resource
521
522 def __exit__(self, *exc_details):
523 # We don't need to duplicate any of our resource release logic
524 self.release_resource()
525
526
527Replacing any use of ``try-finally`` and flag variables
528^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
529
530A pattern you will sometimes see is a ``try-finally`` statement with a flag
531variable to indicate whether or not the body of the ``finally`` clause should
532be executed. In its simplest form (that can't already be handled just by
533using an ``except`` clause instead), it looks something like this::
534
535 cleanup_needed = True
536 try:
537 result = perform_operation()
538 if result:
539 cleanup_needed = False
540 finally:
541 if cleanup_needed:
542 cleanup_resources()
543
544As with any ``try`` statement based code, this can cause problems for
545development and review, because the setup code and the cleanup code can end
546up being separated by arbitrarily long sections of code.
547
548:class:`ExitStack` makes it possible to instead register a callback for
549execution at the end of a ``with`` statement, and then later decide to skip
550executing that callback::
551
552 from contextlib import ExitStack
553
554 with ExitStack() as stack:
555 stack.callback(cleanup_resources)
556 result = perform_operation()
557 if result:
558 stack.pop_all()
559
560This allows the intended cleanup up behaviour to be made explicit up front,
561rather than requiring a separate flag variable.
562
563If a particular application uses this pattern a lot, it can be simplified
564even further by means of a small helper class::
565
566 from contextlib import ExitStack
567
568 class Callback(ExitStack):
569 def __init__(self, callback, *args, **kwds):
570 super(Callback, self).__init__()
571 self.callback(callback, *args, **kwds)
572
573 def cancel(self):
574 self.pop_all()
575
576 with Callback(cleanup_resources) as cb:
577 result = perform_operation()
578 if result:
579 cb.cancel()
580
581If the resource cleanup isn't already neatly bundled into a standalone
582function, then it is still possible to use the decorator form of
583:meth:`ExitStack.callback` to declare the resource cleanup in
584advance::
585
586 from contextlib import ExitStack
587
588 with ExitStack() as stack:
589 @stack.callback
590 def cleanup_resources():
591 ...
592 result = perform_operation()
593 if result:
594 stack.pop_all()
595
596Due to the way the decorator protocol works, a callback function
597declared this way cannot take any parameters. Instead, any resources to
Martin Panterd21e0b52015-10-10 10:36:22 +0000598be released must be accessed as closure variables.
Nick Coghlan3267a302012-05-21 22:54:43 +1000599
600
601Using a context manager as a function decorator
602^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
603
604:class:`ContextDecorator` makes it possible to use a context manager in
605both an ordinary ``with`` statement and also as a function decorator.
606
607For example, it is sometimes useful to wrap functions or groups of statements
608with a logger that can track the time of entry and time of exit. Rather than
609writing both a function decorator and a context manager for the task,
610inheriting from :class:`ContextDecorator` provides both capabilities in a
611single definition::
612
613 from contextlib import ContextDecorator
614 import logging
615
616 logging.basicConfig(level=logging.INFO)
617
618 class track_entry_and_exit(ContextDecorator):
619 def __init__(self, name):
620 self.name = name
621
622 def __enter__(self):
Vinay Sajipdd917f82016-08-31 08:22:29 +0100623 logging.info('Entering: %s', self.name)
Nick Coghlan3267a302012-05-21 22:54:43 +1000624
625 def __exit__(self, exc_type, exc, exc_tb):
Vinay Sajipdd917f82016-08-31 08:22:29 +0100626 logging.info('Exiting: %s', self.name)
Nick Coghlan3267a302012-05-21 22:54:43 +1000627
628Instances of this class can be used as both a context manager::
629
630 with track_entry_and_exit('widget loader'):
631 print('Some time consuming activity goes here')
632 load_widget()
633
634And also as a function decorator::
635
636 @track_entry_and_exit('widget loader')
637 def activity():
638 print('Some time consuming activity goes here')
639 load_widget()
640
641Note that there is one additional limitation when using context managers
642as function decorators: there's no way to access the return value of
643:meth:`__enter__`. If that value is needed, then it is still necessary to use
644an explicit ``with`` statement.
645
Georg Brandl116aa622007-08-15 14:28:22 +0000646.. seealso::
647
Serhiy Storchakae4ba8722016-03-31 15:30:54 +0300648 :pep:`343` - The "with" statement
Georg Brandl116aa622007-08-15 14:28:22 +0000649 The specification, background, and examples for the Python :keyword:`with`
650 statement.
651
Nick Coghlan0acceb72013-10-20 13:22:21 +1000652.. _single-use-reusable-and-reentrant-cms:
Nick Coghlan8608d262013-10-20 00:30:51 +1000653
Nick Coghlan0acceb72013-10-20 13:22:21 +1000654Single use, reusable and reentrant context managers
655---------------------------------------------------
Nick Coghlan8608d262013-10-20 00:30:51 +1000656
657Most context managers are written in a way that means they can only be
658used effectively in a :keyword:`with` statement once. These single use
659context managers must be created afresh each time they're used -
660attempting to use them a second time will trigger an exception or
661otherwise not work correctly.
662
663This common limitation means that it is generally advisable to create
664context managers directly in the header of the :keyword:`with` statement
665where they are used (as shown in all of the usage examples above).
666
667Files are an example of effectively single use context managers, since
668the first :keyword:`with` statement will close the file, preventing any
669further IO operations using that file object.
670
671Context managers created using :func:`contextmanager` are also single use
672context managers, and will complain about the underlying generator failing
673to yield if an attempt is made to use them a second time::
674
675 >>> from contextlib import contextmanager
676 >>> @contextmanager
677 ... def singleuse():
678 ... print("Before")
679 ... yield
680 ... print("After")
681 ...
682 >>> cm = singleuse()
683 >>> with cm:
684 ... pass
685 ...
686 Before
687 After
688 >>> with cm:
Serhiy Storchakadba90392016-05-10 12:01:23 +0300689 ... pass
Nick Coghlan8608d262013-10-20 00:30:51 +1000690 ...
691 Traceback (most recent call last):
692 ...
693 RuntimeError: generator didn't yield
694
695
696.. _reentrant-cms:
697
698Reentrant context managers
699^^^^^^^^^^^^^^^^^^^^^^^^^^
700
701More sophisticated context managers may be "reentrant". These context
702managers can not only be used in multiple :keyword:`with` statements,
703but may also be used *inside* a :keyword:`with` statement that is already
704using the same context manager.
705
Nick Coghlan8e113b42013-11-03 17:00:51 +1000706:class:`threading.RLock` is an example of a reentrant context manager, as are
707:func:`suppress` and :func:`redirect_stdout`. Here's a very simple example of
708reentrant use::
Nick Coghlan8608d262013-10-20 00:30:51 +1000709
Nick Coghlan8e113b42013-11-03 17:00:51 +1000710 >>> from contextlib import redirect_stdout
711 >>> from io import StringIO
712 >>> stream = StringIO()
713 >>> write_to_stream = redirect_stdout(stream)
714 >>> with write_to_stream:
715 ... print("This is written to the stream rather than stdout")
716 ... with write_to_stream:
717 ... print("This is also written to the stream")
Nick Coghlan8608d262013-10-20 00:30:51 +1000718 ...
Nick Coghlan8e113b42013-11-03 17:00:51 +1000719 >>> print("This is written directly to stdout")
720 This is written directly to stdout
721 >>> print(stream.getvalue())
722 This is written to the stream rather than stdout
723 This is also written to the stream
724
725Real world examples of reentrancy are more likely to involve multiple
726functions calling each other and hence be far more complicated than this
727example.
728
729Note also that being reentrant is *not* the same thing as being thread safe.
730:func:`redirect_stdout`, for example, is definitely not thread safe, as it
731makes a global modification to the system state by binding :data:`sys.stdout`
732to a different stream.
Nick Coghlan8608d262013-10-20 00:30:51 +1000733
734
735.. _reusable-cms:
736
737Reusable context managers
738^^^^^^^^^^^^^^^^^^^^^^^^^
739
740Distinct from both single use and reentrant context managers are "reusable"
741context managers (or, to be completely explicit, "reusable, but not
742reentrant" context managers, since reentrant context managers are also
743reusable). These context managers support being used multiple times, but
744will fail (or otherwise not work correctly) if the specific context manager
745instance has already been used in a containing with statement.
746
Nick Coghlan8e113b42013-11-03 17:00:51 +1000747:class:`threading.Lock` is an example of a reusable, but not reentrant,
748context manager (for a reentrant lock, it is necessary to use
749:class:`threading.RLock` instead).
Nick Coghlan8608d262013-10-20 00:30:51 +1000750
Nick Coghlan8e113b42013-11-03 17:00:51 +1000751Another example of a reusable, but not reentrant, context manager is
752:class:`ExitStack`, as it invokes *all* currently registered callbacks
753when leaving any with statement, regardless of where those callbacks
754were added::
Nick Coghlan8608d262013-10-20 00:30:51 +1000755
Nick Coghlan8e113b42013-11-03 17:00:51 +1000756 >>> from contextlib import ExitStack
757 >>> stack = ExitStack()
758 >>> with stack:
759 ... stack.callback(print, "Callback: from first context")
760 ... print("Leaving first context")
Nick Coghlan8608d262013-10-20 00:30:51 +1000761 ...
Nick Coghlan8e113b42013-11-03 17:00:51 +1000762 Leaving first context
763 Callback: from first context
764 >>> with stack:
765 ... stack.callback(print, "Callback: from second context")
766 ... print("Leaving second context")
767 ...
768 Leaving second context
769 Callback: from second context
770 >>> with stack:
771 ... stack.callback(print, "Callback: from outer context")
772 ... with stack:
773 ... stack.callback(print, "Callback: from inner context")
774 ... print("Leaving inner context")
775 ... print("Leaving outer context")
776 ...
777 Leaving inner context
778 Callback: from inner context
779 Callback: from outer context
780 Leaving outer context
781
782As the output from the example shows, reusing a single stack object across
783multiple with statements works correctly, but attempting to nest them
784will cause the stack to be cleared at the end of the innermost with
785statement, which is unlikely to be desirable behaviour.
786
787Using separate :class:`ExitStack` instances instead of reusing a single
788instance avoids that problem::
789
790 >>> from contextlib import ExitStack
791 >>> with ExitStack() as outer_stack:
792 ... outer_stack.callback(print, "Callback: from outer context")
793 ... with ExitStack() as inner_stack:
794 ... inner_stack.callback(print, "Callback: from inner context")
795 ... print("Leaving inner context")
796 ... print("Leaving outer context")
797 ...
798 Leaving inner context
799 Callback: from inner context
800 Leaving outer context
801 Callback: from outer context