blob: faa6c8ac23bd2051ed06aa058d6d02e99bbb6820 [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
Jelle Zijlstra176baa32017-12-13 17:19:17 -080032.. class:: AbstractAsyncContextManager
33
34 An :term:`abstract base class` for classes that implement
35 :meth:`object.__aenter__` and :meth:`object.__aexit__`. A default
36 implementation for :meth:`object.__aenter__` is provided which returns
37 ``self`` while :meth:`object.__aexit__` is an abstract method which by default
38 returns ``None``. See also the definition of
39 :ref:`async-context-managers`.
40
41 .. versionadded:: 3.7
42
Brett Cannon9e080e02016-04-08 12:15:27 -070043
Georg Brandl8a1caa22010-07-29 16:01:11 +000044.. decorator:: contextmanager
Georg Brandl116aa622007-08-15 14:28:22 +000045
Christian Heimesd8654cf2007-12-02 15:22:16 +000046 This function is a :term:`decorator` that can be used to define a factory
47 function for :keyword:`with` statement context managers, without needing to
48 create a class or separate :meth:`__enter__` and :meth:`__exit__` methods.
Georg Brandl116aa622007-08-15 14:28:22 +000049
50 A simple example (this is not recommended as a real way of generating HTML!)::
51
Georg Brandl116aa622007-08-15 14:28:22 +000052 from contextlib import contextmanager
53
54 @contextmanager
55 def tag(name):
Georg Brandl6911e3c2007-09-04 07:15:32 +000056 print("<%s>" % name)
Georg Brandl116aa622007-08-15 14:28:22 +000057 yield
Georg Brandl6911e3c2007-09-04 07:15:32 +000058 print("</%s>" % name)
Georg Brandl116aa622007-08-15 14:28:22 +000059
60 >>> with tag("h1"):
Georg Brandl6911e3c2007-09-04 07:15:32 +000061 ... print("foo")
Georg Brandl116aa622007-08-15 14:28:22 +000062 ...
63 <h1>
64 foo
65 </h1>
66
Georg Brandl9afde1c2007-11-01 20:32:30 +000067 The function being decorated must return a :term:`generator`-iterator when
68 called. This iterator must yield exactly one value, which will be bound to
69 the targets in the :keyword:`with` statement's :keyword:`as` clause, if any.
Georg Brandl116aa622007-08-15 14:28:22 +000070
71 At the point where the generator yields, the block nested in the :keyword:`with`
72 statement is executed. The generator is then resumed after the block is exited.
73 If an unhandled exception occurs in the block, it is reraised inside the
74 generator at the point where the yield occurred. Thus, you can use a
75 :keyword:`try`...\ :keyword:`except`...\ :keyword:`finally` statement to trap
76 the error (if any), or ensure that some cleanup takes place. If an exception is
77 trapped merely in order to log it or to perform some action (rather than to
78 suppress it entirely), the generator must reraise that exception. Otherwise the
79 generator context manager will indicate to the :keyword:`with` statement that
80 the exception has been handled, and execution will resume with the statement
81 immediately following the :keyword:`with` statement.
82
Nick Coghlan0ded3e32011-05-05 23:49:25 +100083 :func:`contextmanager` uses :class:`ContextDecorator` so the context managers
84 it creates can be used as decorators as well as in :keyword:`with` statements.
85 When used as a decorator, a new generator instance is implicitly created on
86 each function call (this allows the otherwise "one-shot" context managers
87 created by :func:`contextmanager` to meet the requirement that context
88 managers support multiple invocations in order to be used as decorators).
Michael Foordb3a89842010-06-30 12:17:50 +000089
90 .. versionchanged:: 3.2
91 Use of :class:`ContextDecorator`.
Georg Brandl116aa622007-08-15 14:28:22 +000092
Georg Brandl86e78d12010-07-18 13:43:32 +000093
Jelle Zijlstra2e624692017-04-30 18:25:58 -070094.. decorator:: asynccontextmanager
95
96 Similar to :func:`~contextlib.contextmanager`, but creates an
97 :ref:`asynchronous context manager <async-context-managers>`.
98
99 This function is a :term:`decorator` that can be used to define a factory
100 function for :keyword:`async with` statement asynchronous context managers,
101 without needing to create a class or separate :meth:`__aenter__` and
102 :meth:`__aexit__` methods. It must be applied to an :term:`asynchronous
103 generator` function.
104
105 A simple example::
106
107 from contextlib import asynccontextmanager
108
109 @asynccontextmanager
110 async def get_connection():
111 conn = await acquire_db_connection()
112 try:
113 yield
114 finally:
115 await release_db_connection(conn)
116
117 async def get_all_users():
118 async with get_connection() as conn:
119 return conn.query('SELECT ...')
120
121 .. versionadded:: 3.7
122
123
Georg Brandl116aa622007-08-15 14:28:22 +0000124.. function:: closing(thing)
125
126 Return a context manager that closes *thing* upon completion of the block. This
127 is basically equivalent to::
128
129 from contextlib import contextmanager
130
131 @contextmanager
132 def closing(thing):
133 try:
134 yield thing
135 finally:
136 thing.close()
137
138 And lets you write code like this::
139
Georg Brandl116aa622007-08-15 14:28:22 +0000140 from contextlib import closing
Georg Brandl0f7ede42008-06-23 11:23:31 +0000141 from urllib.request import urlopen
Georg Brandl116aa622007-08-15 14:28:22 +0000142
Georg Brandl0f7ede42008-06-23 11:23:31 +0000143 with closing(urlopen('http://www.python.org')) as page:
Georg Brandl116aa622007-08-15 14:28:22 +0000144 for line in page:
Georg Brandl6911e3c2007-09-04 07:15:32 +0000145 print(line)
Georg Brandl116aa622007-08-15 14:28:22 +0000146
147 without needing to explicitly close ``page``. Even if an error occurs,
148 ``page.close()`` will be called when the :keyword:`with` block is exited.
149
Georg Brandla7c17e52013-10-13 22:25:10 +0200150
Jesse-Bakker0784a2e2017-11-23 01:23:28 +0100151.. _simplifying-support-for-single-optional-context-managers:
152
153.. function:: nullcontext(enter_result=None)
154
155 Return a context manager that returns enter_result from ``__enter__``, but
156 otherwise does nothing. It is intended to be used as a stand-in for an
157 optional context manager, for example::
158
159 def process_file(file_or_path):
160 if isinstance(file_or_path, str):
161 # If string, open file
162 cm = open(file_or_path)
163 else:
164 # Caller is responsible for closing file
165 cm = nullcontext(file_or_path)
166
167 with cm as file:
168 # Perform processing on the file
169
170 .. versionadded:: 3.7
171
172
Nick Coghlan240f86d2013-10-17 23:40:57 +1000173.. function:: suppress(*exceptions)
Raymond Hettingere318a882013-03-10 22:26:51 -0700174
Nick Coghlan240f86d2013-10-17 23:40:57 +1000175 Return a context manager that suppresses any of the specified exceptions
176 if they occur in the body of a with statement and then resumes execution
177 with the first statement following the end of the with statement.
Raymond Hettingere318a882013-03-10 22:26:51 -0700178
Nick Coghlan240f86d2013-10-17 23:40:57 +1000179 As with any other mechanism that completely suppresses exceptions, this
180 context manager should be used only to cover very specific errors where
181 silently continuing with program execution is known to be the right
182 thing to do.
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000183
Raymond Hettingere318a882013-03-10 22:26:51 -0700184 For example::
185
Nick Coghlan240f86d2013-10-17 23:40:57 +1000186 from contextlib import suppress
Raymond Hettingere318a882013-03-10 22:26:51 -0700187
Nick Coghlan240f86d2013-10-17 23:40:57 +1000188 with suppress(FileNotFoundError):
Raymond Hettingere318a882013-03-10 22:26:51 -0700189 os.remove('somefile.tmp')
190
Nick Coghlan240f86d2013-10-17 23:40:57 +1000191 with suppress(FileNotFoundError):
192 os.remove('someotherfile.tmp')
193
Raymond Hettingere318a882013-03-10 22:26:51 -0700194 This code is equivalent to::
195
196 try:
197 os.remove('somefile.tmp')
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000198 except FileNotFoundError:
Raymond Hettingere318a882013-03-10 22:26:51 -0700199 pass
200
Nick Coghlan240f86d2013-10-17 23:40:57 +1000201 try:
202 os.remove('someotherfile.tmp')
203 except FileNotFoundError:
204 pass
205
Nick Coghlan8608d262013-10-20 00:30:51 +1000206 This context manager is :ref:`reentrant <reentrant-cms>`.
207
Raymond Hettingere318a882013-03-10 22:26:51 -0700208 .. versionadded:: 3.4
Georg Brandl116aa622007-08-15 14:28:22 +0000209
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000210
Raymond Hettinger088cbf22013-10-10 00:46:57 -0700211.. function:: redirect_stdout(new_target)
212
213 Context manager for temporarily redirecting :data:`sys.stdout` to
214 another file or file-like object.
215
216 This tool adds flexibility to existing functions or classes whose output
217 is hardwired to stdout.
218
219 For example, the output of :func:`help` normally is sent to *sys.stdout*.
Serhiy Storchakad65c9492015-11-02 14:10:23 +0200220 You can capture that output in a string by redirecting the output to an
Raymond Hettinger088cbf22013-10-10 00:46:57 -0700221 :class:`io.StringIO` object::
222
223 f = io.StringIO()
224 with redirect_stdout(f):
225 help(pow)
226 s = f.getvalue()
227
228 To send the output of :func:`help` to a file on disk, redirect the output
229 to a regular file::
230
231 with open('help.txt', 'w') as f:
232 with redirect_stdout(f):
233 help(pow)
234
235 To send the output of :func:`help` to *sys.stderr*::
236
237 with redirect_stdout(sys.stderr):
238 help(pow)
239
Nick Coghlanb4534ae2013-10-13 23:23:08 +1000240 Note that the global side effect on :data:`sys.stdout` means that this
241 context manager is not suitable for use in library code and most threaded
242 applications. It also has no effect on the output of subprocesses.
243 However, it is still a useful approach for many utility scripts.
244
Nick Coghlan36d8ef92014-10-12 10:25:00 +1000245 This context manager is :ref:`reentrant <reentrant-cms>`.
Nick Coghlan8608d262013-10-20 00:30:51 +1000246
Raymond Hettinger088cbf22013-10-10 00:46:57 -0700247 .. versionadded:: 3.4
248
Georg Brandla7c17e52013-10-13 22:25:10 +0200249
Berker Peksagbb44fe02014-11-28 23:28:06 +0200250.. function:: redirect_stderr(new_target)
251
252 Similar to :func:`~contextlib.redirect_stdout` but redirecting
253 :data:`sys.stderr` to another file or file-like object.
254
255 This context manager is :ref:`reentrant <reentrant-cms>`.
256
257 .. versionadded:: 3.5
258
259
Michael Foordb3a89842010-06-30 12:17:50 +0000260.. class:: ContextDecorator()
261
262 A base class that enables a context manager to also be used as a decorator.
263
264 Context managers inheriting from ``ContextDecorator`` have to implement
265 ``__enter__`` and ``__exit__`` as normal. ``__exit__`` retains its optional
266 exception handling even when used as a decorator.
267
Georg Brandl86e78d12010-07-18 13:43:32 +0000268 ``ContextDecorator`` is used by :func:`contextmanager`, so you get this
269 functionality automatically.
270
271 Example of ``ContextDecorator``::
Michael Foordb3a89842010-06-30 12:17:50 +0000272
273 from contextlib import ContextDecorator
274
275 class mycontext(ContextDecorator):
Georg Brandl86e78d12010-07-18 13:43:32 +0000276 def __enter__(self):
277 print('Starting')
278 return self
Michael Foordb3a89842010-06-30 12:17:50 +0000279
Georg Brandl86e78d12010-07-18 13:43:32 +0000280 def __exit__(self, *exc):
281 print('Finishing')
282 return False
Michael Foordb3a89842010-06-30 12:17:50 +0000283
284 >>> @mycontext()
285 ... def function():
Georg Brandl86e78d12010-07-18 13:43:32 +0000286 ... print('The bit in the middle')
Michael Foordb3a89842010-06-30 12:17:50 +0000287 ...
288 >>> function()
289 Starting
290 The bit in the middle
291 Finishing
292
293 >>> with mycontext():
Georg Brandl86e78d12010-07-18 13:43:32 +0000294 ... print('The bit in the middle')
Michael Foordb3a89842010-06-30 12:17:50 +0000295 ...
296 Starting
297 The bit in the middle
298 Finishing
299
Georg Brandl86e78d12010-07-18 13:43:32 +0000300 This change is just syntactic sugar for any construct of the following form::
301
302 def f():
303 with cm():
304 # Do stuff
305
306 ``ContextDecorator`` lets you instead write::
307
308 @cm()
309 def f():
310 # Do stuff
311
312 It makes it clear that the ``cm`` applies to the whole function, rather than
313 just a piece of it (and saving an indentation level is nice, too).
314
Michael Foordb3a89842010-06-30 12:17:50 +0000315 Existing context managers that already have a base class can be extended by
316 using ``ContextDecorator`` as a mixin class::
317
318 from contextlib import ContextDecorator
319
320 class mycontext(ContextBaseClass, ContextDecorator):
Georg Brandl86e78d12010-07-18 13:43:32 +0000321 def __enter__(self):
322 return self
Michael Foordb3a89842010-06-30 12:17:50 +0000323
Georg Brandl86e78d12010-07-18 13:43:32 +0000324 def __exit__(self, *exc):
325 return False
Michael Foordb3a89842010-06-30 12:17:50 +0000326
Nick Coghlan0ded3e32011-05-05 23:49:25 +1000327 .. note::
328 As the decorated function must be able to be called multiple times, the
329 underlying context manager must support use in multiple :keyword:`with`
330 statements. If this is not the case, then the original construct with the
331 explicit :keyword:`with` statement inside the function should be used.
332
Michael Foordb3a89842010-06-30 12:17:50 +0000333 .. versionadded:: 3.2
334
335
Nick Coghlan3267a302012-05-21 22:54:43 +1000336.. class:: ExitStack()
337
338 A context manager that is designed to make it easy to programmatically
339 combine other context managers and cleanup functions, especially those
340 that are optional or otherwise driven by input data.
341
342 For example, a set of files may easily be handled in a single with
343 statement as follows::
344
345 with ExitStack() as stack:
346 files = [stack.enter_context(open(fname)) for fname in filenames]
347 # All opened files will automatically be closed at the end of
348 # the with statement, even if attempts to open files later
Andrew Svetlov5b898402012-12-18 21:26:36 +0200349 # in the list raise an exception
Nick Coghlan3267a302012-05-21 22:54:43 +1000350
351 Each instance maintains a stack of registered callbacks that are called in
352 reverse order when the instance is closed (either explicitly or implicitly
Nick Coghlan27228272012-05-31 22:17:08 +1000353 at the end of a :keyword:`with` statement). Note that callbacks are *not*
354 invoked implicitly when the context stack instance is garbage collected.
Nick Coghlan3267a302012-05-21 22:54:43 +1000355
356 This stack model is used so that context managers that acquire their
357 resources in their ``__init__`` method (such as file objects) can be
358 handled correctly.
359
360 Since registered callbacks are invoked in the reverse order of
Nick Coghlan27228272012-05-31 22:17:08 +1000361 registration, this ends up behaving as if multiple nested :keyword:`with`
Nick Coghlan3267a302012-05-21 22:54:43 +1000362 statements had been used with the registered set of callbacks. This even
363 extends to exception handling - if an inner callback suppresses or replaces
364 an exception, then outer callbacks will be passed arguments based on that
365 updated state.
366
367 This is a relatively low level API that takes care of the details of
368 correctly unwinding the stack of exit callbacks. It provides a suitable
369 foundation for higher level context managers that manipulate the exit
370 stack in application specific ways.
371
Nick Coghlana497b442012-05-22 23:02:00 +1000372 .. versionadded:: 3.3
373
Nick Coghlan3267a302012-05-21 22:54:43 +1000374 .. method:: enter_context(cm)
375
376 Enters a new context manager and adds its :meth:`__exit__` method to
377 the callback stack. The return value is the result of the context
378 manager's own :meth:`__enter__` method.
379
380 These context managers may suppress exceptions just as they normally
Nick Coghlan27228272012-05-31 22:17:08 +1000381 would if used directly as part of a :keyword:`with` statement.
Nick Coghlan3267a302012-05-21 22:54:43 +1000382
383 .. method:: push(exit)
384
385 Adds a context manager's :meth:`__exit__` method to the callback stack.
386
387 As ``__enter__`` is *not* invoked, this method can be used to cover
388 part of an :meth:`__enter__` implementation with a context manager's own
389 :meth:`__exit__` method.
390
391 If passed an object that is not a context manager, this method assumes
392 it is a callback with the same signature as a context manager's
393 :meth:`__exit__` method and adds it directly to the callback stack.
394
395 By returning true values, these callbacks can suppress exceptions the
396 same way context manager :meth:`__exit__` methods can.
397
398 The passed in object is returned from the function, allowing this
Nick Coghlan27228272012-05-31 22:17:08 +1000399 method to be used as a function decorator.
Nick Coghlan3267a302012-05-21 22:54:43 +1000400
401 .. method:: callback(callback, *args, **kwds)
402
403 Accepts an arbitrary callback function and arguments and adds it to
404 the callback stack.
405
406 Unlike the other methods, callbacks added this way cannot suppress
407 exceptions (as they are never passed the exception details).
408
409 The passed in callback is returned from the function, allowing this
Nick Coghlan27228272012-05-31 22:17:08 +1000410 method to be used as a function decorator.
Nick Coghlan3267a302012-05-21 22:54:43 +1000411
412 .. method:: pop_all()
413
414 Transfers the callback stack to a fresh :class:`ExitStack` instance
415 and returns it. No callbacks are invoked by this operation - instead,
416 they will now be invoked when the new stack is closed (either
Nick Coghlan27228272012-05-31 22:17:08 +1000417 explicitly or implicitly at the end of a :keyword:`with` statement).
Nick Coghlan3267a302012-05-21 22:54:43 +1000418
419 For example, a group of files can be opened as an "all or nothing"
420 operation as follows::
421
422 with ExitStack() as stack:
423 files = [stack.enter_context(open(fname)) for fname in filenames]
Barry Warsawd8f870d2013-05-10 11:35:38 -0400424 # Hold onto the close method, but don't call it yet.
425 close_files = stack.pop_all().close
Nick Coghlan3267a302012-05-21 22:54:43 +1000426 # If opening any file fails, all previously opened files will be
427 # closed automatically. If all files are opened successfully,
428 # they will remain open even after the with statement ends.
Barry Warsawd8f870d2013-05-10 11:35:38 -0400429 # close_files() can then be invoked explicitly to close them all.
Nick Coghlan3267a302012-05-21 22:54:43 +1000430
431 .. method:: close()
432
433 Immediately unwinds the callback stack, invoking callbacks in the
434 reverse order of registration. For any context managers and exit
435 callbacks registered, the arguments passed in will indicate that no
436 exception occurred.
437
Nick Coghlan3267a302012-05-21 22:54:43 +1000438
439Examples and Recipes
440--------------------
441
442This section describes some examples and recipes for making effective use of
443the tools provided by :mod:`contextlib`.
444
445
Nick Coghlan27228272012-05-31 22:17:08 +1000446Supporting a variable number of context managers
447^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
448
449The primary use case for :class:`ExitStack` is the one given in the class
450documentation: supporting a variable number of context managers and other
451cleanup operations in a single :keyword:`with` statement. The variability
452may come from the number of context managers needed being driven by user
453input (such as opening a user specified collection of files), or from
454some of the context managers being optional::
455
456 with ExitStack() as stack:
457 for resource in resources:
458 stack.enter_context(resource)
Raymond Hettingere8e2df32014-05-25 18:06:04 -0700459 if need_special_resource():
Nick Coghlan27228272012-05-31 22:17:08 +1000460 special = acquire_special_resource()
461 stack.callback(release_special_resource, special)
462 # Perform operations that use the acquired resources
463
464As shown, :class:`ExitStack` also makes it quite easy to use :keyword:`with`
465statements to manage arbitrary resources that don't natively support the
466context management protocol.
467
468
Nick Coghlan27228272012-05-31 22:17:08 +1000469Catching exceptions from ``__enter__`` methods
470^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
471
472It is occasionally desirable to catch exceptions from an ``__enter__``
473method implementation, *without* inadvertently catching exceptions from
474the :keyword:`with` statement body or the context manager's ``__exit__``
475method. By using :class:`ExitStack` the steps in the context management
476protocol can be separated slightly in order to allow this::
477
478 stack = ExitStack()
479 try:
480 x = stack.enter_context(cm)
481 except Exception:
482 # handle __enter__ exception
483 else:
484 with stack:
485 # Handle normal case
486
487Actually needing to do this is likely to indicate that the underlying API
488should be providing a direct resource management interface for use with
489:keyword:`try`/:keyword:`except`/:keyword:`finally` statements, but not
490all APIs are well designed in that regard. When a context manager is the
491only resource management API provided, then :class:`ExitStack` can make it
492easier to handle various situations that can't be handled directly in a
493:keyword:`with` statement.
494
495
Nick Coghlan3267a302012-05-21 22:54:43 +1000496Cleaning up in an ``__enter__`` implementation
497^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
498
499As noted in the documentation of :meth:`ExitStack.push`, this
500method can be useful in cleaning up an already allocated resource if later
501steps in the :meth:`__enter__` implementation fail.
502
503Here's an example of doing this for a context manager that accepts resource
504acquisition and release functions, along with an optional validation function,
505and maps them to the context management protocol::
506
Brett Cannon9e080e02016-04-08 12:15:27 -0700507 from contextlib import contextmanager, AbstractContextManager, ExitStack
Nick Coghlan3267a302012-05-21 22:54:43 +1000508
Brett Cannon9e080e02016-04-08 12:15:27 -0700509 class ResourceManager(AbstractContextManager):
Nick Coghlan3267a302012-05-21 22:54:43 +1000510
511 def __init__(self, acquire_resource, release_resource, check_resource_ok=None):
512 self.acquire_resource = acquire_resource
513 self.release_resource = release_resource
514 if check_resource_ok is None:
515 def check_resource_ok(resource):
516 return True
517 self.check_resource_ok = check_resource_ok
518
519 @contextmanager
520 def _cleanup_on_error(self):
521 with ExitStack() as stack:
522 stack.push(self)
523 yield
524 # The validation check passed and didn't raise an exception
525 # Accordingly, we want to keep the resource, and pass it
526 # back to our caller
527 stack.pop_all()
528
529 def __enter__(self):
530 resource = self.acquire_resource()
531 with self._cleanup_on_error():
532 if not self.check_resource_ok(resource):
533 msg = "Failed validation for {!r}"
534 raise RuntimeError(msg.format(resource))
535 return resource
536
537 def __exit__(self, *exc_details):
538 # We don't need to duplicate any of our resource release logic
539 self.release_resource()
540
541
542Replacing any use of ``try-finally`` and flag variables
543^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
544
545A pattern you will sometimes see is a ``try-finally`` statement with a flag
546variable to indicate whether or not the body of the ``finally`` clause should
547be executed. In its simplest form (that can't already be handled just by
548using an ``except`` clause instead), it looks something like this::
549
550 cleanup_needed = True
551 try:
552 result = perform_operation()
553 if result:
554 cleanup_needed = False
555 finally:
556 if cleanup_needed:
557 cleanup_resources()
558
559As with any ``try`` statement based code, this can cause problems for
560development and review, because the setup code and the cleanup code can end
561up being separated by arbitrarily long sections of code.
562
563:class:`ExitStack` makes it possible to instead register a callback for
564execution at the end of a ``with`` statement, and then later decide to skip
565executing that callback::
566
567 from contextlib import ExitStack
568
569 with ExitStack() as stack:
570 stack.callback(cleanup_resources)
571 result = perform_operation()
572 if result:
573 stack.pop_all()
574
575This allows the intended cleanup up behaviour to be made explicit up front,
576rather than requiring a separate flag variable.
577
578If a particular application uses this pattern a lot, it can be simplified
579even further by means of a small helper class::
580
581 from contextlib import ExitStack
582
583 class Callback(ExitStack):
584 def __init__(self, callback, *args, **kwds):
585 super(Callback, self).__init__()
586 self.callback(callback, *args, **kwds)
587
588 def cancel(self):
589 self.pop_all()
590
591 with Callback(cleanup_resources) as cb:
592 result = perform_operation()
593 if result:
594 cb.cancel()
595
596If the resource cleanup isn't already neatly bundled into a standalone
597function, then it is still possible to use the decorator form of
598:meth:`ExitStack.callback` to declare the resource cleanup in
599advance::
600
601 from contextlib import ExitStack
602
603 with ExitStack() as stack:
604 @stack.callback
605 def cleanup_resources():
606 ...
607 result = perform_operation()
608 if result:
609 stack.pop_all()
610
611Due to the way the decorator protocol works, a callback function
612declared this way cannot take any parameters. Instead, any resources to
Martin Panterd21e0b52015-10-10 10:36:22 +0000613be released must be accessed as closure variables.
Nick Coghlan3267a302012-05-21 22:54:43 +1000614
615
616Using a context manager as a function decorator
617^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
618
619:class:`ContextDecorator` makes it possible to use a context manager in
620both an ordinary ``with`` statement and also as a function decorator.
621
622For example, it is sometimes useful to wrap functions or groups of statements
623with a logger that can track the time of entry and time of exit. Rather than
624writing both a function decorator and a context manager for the task,
625inheriting from :class:`ContextDecorator` provides both capabilities in a
626single definition::
627
628 from contextlib import ContextDecorator
629 import logging
630
631 logging.basicConfig(level=logging.INFO)
632
633 class track_entry_and_exit(ContextDecorator):
634 def __init__(self, name):
635 self.name = name
636
637 def __enter__(self):
Vinay Sajipdd917f82016-08-31 08:22:29 +0100638 logging.info('Entering: %s', self.name)
Nick Coghlan3267a302012-05-21 22:54:43 +1000639
640 def __exit__(self, exc_type, exc, exc_tb):
Vinay Sajipdd917f82016-08-31 08:22:29 +0100641 logging.info('Exiting: %s', self.name)
Nick Coghlan3267a302012-05-21 22:54:43 +1000642
643Instances of this class can be used as both a context manager::
644
645 with track_entry_and_exit('widget loader'):
646 print('Some time consuming activity goes here')
647 load_widget()
648
649And also as a function decorator::
650
651 @track_entry_and_exit('widget loader')
652 def activity():
653 print('Some time consuming activity goes here')
654 load_widget()
655
656Note that there is one additional limitation when using context managers
657as function decorators: there's no way to access the return value of
658:meth:`__enter__`. If that value is needed, then it is still necessary to use
659an explicit ``with`` statement.
660
Georg Brandl116aa622007-08-15 14:28:22 +0000661.. seealso::
662
Serhiy Storchakae4ba8722016-03-31 15:30:54 +0300663 :pep:`343` - The "with" statement
Georg Brandl116aa622007-08-15 14:28:22 +0000664 The specification, background, and examples for the Python :keyword:`with`
665 statement.
666
Nick Coghlan0acceb72013-10-20 13:22:21 +1000667.. _single-use-reusable-and-reentrant-cms:
Nick Coghlan8608d262013-10-20 00:30:51 +1000668
Nick Coghlan0acceb72013-10-20 13:22:21 +1000669Single use, reusable and reentrant context managers
670---------------------------------------------------
Nick Coghlan8608d262013-10-20 00:30:51 +1000671
672Most context managers are written in a way that means they can only be
673used effectively in a :keyword:`with` statement once. These single use
674context managers must be created afresh each time they're used -
675attempting to use them a second time will trigger an exception or
676otherwise not work correctly.
677
678This common limitation means that it is generally advisable to create
679context managers directly in the header of the :keyword:`with` statement
680where they are used (as shown in all of the usage examples above).
681
682Files are an example of effectively single use context managers, since
683the first :keyword:`with` statement will close the file, preventing any
684further IO operations using that file object.
685
686Context managers created using :func:`contextmanager` are also single use
687context managers, and will complain about the underlying generator failing
688to yield if an attempt is made to use them a second time::
689
690 >>> from contextlib import contextmanager
691 >>> @contextmanager
692 ... def singleuse():
693 ... print("Before")
694 ... yield
695 ... print("After")
696 ...
697 >>> cm = singleuse()
698 >>> with cm:
699 ... pass
700 ...
701 Before
702 After
703 >>> with cm:
Serhiy Storchakadba90392016-05-10 12:01:23 +0300704 ... pass
Nick Coghlan8608d262013-10-20 00:30:51 +1000705 ...
706 Traceback (most recent call last):
707 ...
708 RuntimeError: generator didn't yield
709
710
711.. _reentrant-cms:
712
713Reentrant context managers
714^^^^^^^^^^^^^^^^^^^^^^^^^^
715
716More sophisticated context managers may be "reentrant". These context
717managers can not only be used in multiple :keyword:`with` statements,
718but may also be used *inside* a :keyword:`with` statement that is already
719using the same context manager.
720
Nick Coghlan8e113b42013-11-03 17:00:51 +1000721:class:`threading.RLock` is an example of a reentrant context manager, as are
722:func:`suppress` and :func:`redirect_stdout`. Here's a very simple example of
723reentrant use::
Nick Coghlan8608d262013-10-20 00:30:51 +1000724
Nick Coghlan8e113b42013-11-03 17:00:51 +1000725 >>> from contextlib import redirect_stdout
726 >>> from io import StringIO
727 >>> stream = StringIO()
728 >>> write_to_stream = redirect_stdout(stream)
729 >>> with write_to_stream:
730 ... print("This is written to the stream rather than stdout")
731 ... with write_to_stream:
732 ... print("This is also written to the stream")
Nick Coghlan8608d262013-10-20 00:30:51 +1000733 ...
Nick Coghlan8e113b42013-11-03 17:00:51 +1000734 >>> print("This is written directly to stdout")
735 This is written directly to stdout
736 >>> print(stream.getvalue())
737 This is written to the stream rather than stdout
738 This is also written to the stream
739
740Real world examples of reentrancy are more likely to involve multiple
741functions calling each other and hence be far more complicated than this
742example.
743
744Note also that being reentrant is *not* the same thing as being thread safe.
745:func:`redirect_stdout`, for example, is definitely not thread safe, as it
746makes a global modification to the system state by binding :data:`sys.stdout`
747to a different stream.
Nick Coghlan8608d262013-10-20 00:30:51 +1000748
749
750.. _reusable-cms:
751
752Reusable context managers
753^^^^^^^^^^^^^^^^^^^^^^^^^
754
755Distinct from both single use and reentrant context managers are "reusable"
756context managers (or, to be completely explicit, "reusable, but not
757reentrant" context managers, since reentrant context managers are also
758reusable). These context managers support being used multiple times, but
759will fail (or otherwise not work correctly) if the specific context manager
760instance has already been used in a containing with statement.
761
Nick Coghlan8e113b42013-11-03 17:00:51 +1000762:class:`threading.Lock` is an example of a reusable, but not reentrant,
763context manager (for a reentrant lock, it is necessary to use
764:class:`threading.RLock` instead).
Nick Coghlan8608d262013-10-20 00:30:51 +1000765
Nick Coghlan8e113b42013-11-03 17:00:51 +1000766Another example of a reusable, but not reentrant, context manager is
767:class:`ExitStack`, as it invokes *all* currently registered callbacks
768when leaving any with statement, regardless of where those callbacks
769were added::
Nick Coghlan8608d262013-10-20 00:30:51 +1000770
Nick Coghlan8e113b42013-11-03 17:00:51 +1000771 >>> from contextlib import ExitStack
772 >>> stack = ExitStack()
773 >>> with stack:
774 ... stack.callback(print, "Callback: from first context")
775 ... print("Leaving first context")
Nick Coghlan8608d262013-10-20 00:30:51 +1000776 ...
Nick Coghlan8e113b42013-11-03 17:00:51 +1000777 Leaving first context
778 Callback: from first context
779 >>> with stack:
780 ... stack.callback(print, "Callback: from second context")
781 ... print("Leaving second context")
782 ...
783 Leaving second context
784 Callback: from second context
785 >>> with stack:
786 ... stack.callback(print, "Callback: from outer context")
787 ... with stack:
788 ... stack.callback(print, "Callback: from inner context")
789 ... print("Leaving inner context")
790 ... print("Leaving outer context")
791 ...
792 Leaving inner context
793 Callback: from inner context
794 Callback: from outer context
795 Leaving outer context
796
797As the output from the example shows, reusing a single stack object across
798multiple with statements works correctly, but attempting to nest them
799will cause the stack to be cleared at the end of the innermost with
800statement, which is unlikely to be desirable behaviour.
801
802Using separate :class:`ExitStack` instances instead of reusing a single
803instance avoids that problem::
804
805 >>> from contextlib import ExitStack
806 >>> with ExitStack() as outer_stack:
807 ... outer_stack.callback(print, "Callback: from outer context")
808 ... with ExitStack() as inner_stack:
809 ... inner_stack.callback(print, "Callback: from inner context")
810 ... print("Leaving inner context")
811 ... print("Leaving outer context")
812 ...
813 Leaving inner context
814 Callback: from inner context
815 Leaving outer context
816 Callback: from outer context