blob: 54d3a8e4296b069bc45de37cd4c0b3f6e782313d [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
Ilya Kulakov1aa094f2018-01-25 12:51:18 -0800438.. class:: AsyncExitStack()
439
440 An :ref:`asynchronous context manager <async-context-managers>`, similar
441 to :class:`ExitStack`, that supports combining both synchronous and
442 asynchronous context managers, as well as having coroutines for
443 cleanup logic.
444
445 The :meth:`close` method is not implemented, :meth:`aclose` must be used
446 instead.
447
448 .. method:: enter_async_context(cm)
449
450 Similar to :meth:`enter_context` but expects an asynchronous context
451 manager.
452
453 .. method:: push_async_exit(exit)
454
455 Similar to :meth:`push` but expects either an asynchronous context manager
456 or a coroutine.
457
458 .. method:: push_async_callback(callback, *args, **kwds)
459
460 Similar to :meth:`callback` but expects a coroutine.
461
462 .. method:: aclose()
463
464 Similar to :meth:`close` but properly handles awaitables.
465
466 Continuing the example for :func:`asynccontextmanager`::
467
468 async with AsyncExitStack() as stack:
469 connections = [await stack.enter_async_context(get_connection())
470 for i in range(5)]
471 # All opened connections will automatically be released at the end of
472 # the async with statement, even if attempts to open a connection
473 # later in the list raise an exception.
474
475 .. versionadded:: 3.7
Nick Coghlan3267a302012-05-21 22:54:43 +1000476
477Examples and Recipes
478--------------------
479
480This section describes some examples and recipes for making effective use of
481the tools provided by :mod:`contextlib`.
482
483
Nick Coghlan27228272012-05-31 22:17:08 +1000484Supporting a variable number of context managers
485^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
486
487The primary use case for :class:`ExitStack` is the one given in the class
488documentation: supporting a variable number of context managers and other
489cleanup operations in a single :keyword:`with` statement. The variability
490may come from the number of context managers needed being driven by user
491input (such as opening a user specified collection of files), or from
492some of the context managers being optional::
493
494 with ExitStack() as stack:
495 for resource in resources:
496 stack.enter_context(resource)
Raymond Hettingere8e2df32014-05-25 18:06:04 -0700497 if need_special_resource():
Nick Coghlan27228272012-05-31 22:17:08 +1000498 special = acquire_special_resource()
499 stack.callback(release_special_resource, special)
500 # Perform operations that use the acquired resources
501
502As shown, :class:`ExitStack` also makes it quite easy to use :keyword:`with`
503statements to manage arbitrary resources that don't natively support the
504context management protocol.
505
506
Nick Coghlan27228272012-05-31 22:17:08 +1000507Catching exceptions from ``__enter__`` methods
508^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
509
510It is occasionally desirable to catch exceptions from an ``__enter__``
511method implementation, *without* inadvertently catching exceptions from
512the :keyword:`with` statement body or the context manager's ``__exit__``
513method. By using :class:`ExitStack` the steps in the context management
514protocol can be separated slightly in order to allow this::
515
516 stack = ExitStack()
517 try:
518 x = stack.enter_context(cm)
519 except Exception:
520 # handle __enter__ exception
521 else:
522 with stack:
523 # Handle normal case
524
525Actually needing to do this is likely to indicate that the underlying API
526should be providing a direct resource management interface for use with
527:keyword:`try`/:keyword:`except`/:keyword:`finally` statements, but not
528all APIs are well designed in that regard. When a context manager is the
529only resource management API provided, then :class:`ExitStack` can make it
530easier to handle various situations that can't be handled directly in a
531:keyword:`with` statement.
532
533
Nick Coghlan3267a302012-05-21 22:54:43 +1000534Cleaning up in an ``__enter__`` implementation
535^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
536
537As noted in the documentation of :meth:`ExitStack.push`, this
538method can be useful in cleaning up an already allocated resource if later
539steps in the :meth:`__enter__` implementation fail.
540
541Here's an example of doing this for a context manager that accepts resource
542acquisition and release functions, along with an optional validation function,
543and maps them to the context management protocol::
544
Brett Cannon9e080e02016-04-08 12:15:27 -0700545 from contextlib import contextmanager, AbstractContextManager, ExitStack
Nick Coghlan3267a302012-05-21 22:54:43 +1000546
Brett Cannon9e080e02016-04-08 12:15:27 -0700547 class ResourceManager(AbstractContextManager):
Nick Coghlan3267a302012-05-21 22:54:43 +1000548
549 def __init__(self, acquire_resource, release_resource, check_resource_ok=None):
550 self.acquire_resource = acquire_resource
551 self.release_resource = release_resource
552 if check_resource_ok is None:
553 def check_resource_ok(resource):
554 return True
555 self.check_resource_ok = check_resource_ok
556
557 @contextmanager
558 def _cleanup_on_error(self):
559 with ExitStack() as stack:
560 stack.push(self)
561 yield
562 # The validation check passed and didn't raise an exception
563 # Accordingly, we want to keep the resource, and pass it
564 # back to our caller
565 stack.pop_all()
566
567 def __enter__(self):
568 resource = self.acquire_resource()
569 with self._cleanup_on_error():
570 if not self.check_resource_ok(resource):
571 msg = "Failed validation for {!r}"
572 raise RuntimeError(msg.format(resource))
573 return resource
574
575 def __exit__(self, *exc_details):
576 # We don't need to duplicate any of our resource release logic
577 self.release_resource()
578
579
580Replacing any use of ``try-finally`` and flag variables
581^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
582
583A pattern you will sometimes see is a ``try-finally`` statement with a flag
584variable to indicate whether or not the body of the ``finally`` clause should
585be executed. In its simplest form (that can't already be handled just by
586using an ``except`` clause instead), it looks something like this::
587
588 cleanup_needed = True
589 try:
590 result = perform_operation()
591 if result:
592 cleanup_needed = False
593 finally:
594 if cleanup_needed:
595 cleanup_resources()
596
597As with any ``try`` statement based code, this can cause problems for
598development and review, because the setup code and the cleanup code can end
599up being separated by arbitrarily long sections of code.
600
601:class:`ExitStack` makes it possible to instead register a callback for
602execution at the end of a ``with`` statement, and then later decide to skip
603executing that callback::
604
605 from contextlib import ExitStack
606
607 with ExitStack() as stack:
608 stack.callback(cleanup_resources)
609 result = perform_operation()
610 if result:
611 stack.pop_all()
612
613This allows the intended cleanup up behaviour to be made explicit up front,
614rather than requiring a separate flag variable.
615
616If a particular application uses this pattern a lot, it can be simplified
617even further by means of a small helper class::
618
619 from contextlib import ExitStack
620
621 class Callback(ExitStack):
622 def __init__(self, callback, *args, **kwds):
623 super(Callback, self).__init__()
624 self.callback(callback, *args, **kwds)
625
626 def cancel(self):
627 self.pop_all()
628
629 with Callback(cleanup_resources) as cb:
630 result = perform_operation()
631 if result:
632 cb.cancel()
633
634If the resource cleanup isn't already neatly bundled into a standalone
635function, then it is still possible to use the decorator form of
636:meth:`ExitStack.callback` to declare the resource cleanup in
637advance::
638
639 from contextlib import ExitStack
640
641 with ExitStack() as stack:
642 @stack.callback
643 def cleanup_resources():
644 ...
645 result = perform_operation()
646 if result:
647 stack.pop_all()
648
649Due to the way the decorator protocol works, a callback function
650declared this way cannot take any parameters. Instead, any resources to
Martin Panterd21e0b52015-10-10 10:36:22 +0000651be released must be accessed as closure variables.
Nick Coghlan3267a302012-05-21 22:54:43 +1000652
653
654Using a context manager as a function decorator
655^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
656
657:class:`ContextDecorator` makes it possible to use a context manager in
658both an ordinary ``with`` statement and also as a function decorator.
659
660For example, it is sometimes useful to wrap functions or groups of statements
661with a logger that can track the time of entry and time of exit. Rather than
662writing both a function decorator and a context manager for the task,
663inheriting from :class:`ContextDecorator` provides both capabilities in a
664single definition::
665
666 from contextlib import ContextDecorator
667 import logging
668
669 logging.basicConfig(level=logging.INFO)
670
671 class track_entry_and_exit(ContextDecorator):
672 def __init__(self, name):
673 self.name = name
674
675 def __enter__(self):
Vinay Sajipdd917f82016-08-31 08:22:29 +0100676 logging.info('Entering: %s', self.name)
Nick Coghlan3267a302012-05-21 22:54:43 +1000677
678 def __exit__(self, exc_type, exc, exc_tb):
Vinay Sajipdd917f82016-08-31 08:22:29 +0100679 logging.info('Exiting: %s', self.name)
Nick Coghlan3267a302012-05-21 22:54:43 +1000680
681Instances of this class can be used as both a context manager::
682
683 with track_entry_and_exit('widget loader'):
684 print('Some time consuming activity goes here')
685 load_widget()
686
687And also as a function decorator::
688
689 @track_entry_and_exit('widget loader')
690 def activity():
691 print('Some time consuming activity goes here')
692 load_widget()
693
694Note that there is one additional limitation when using context managers
695as function decorators: there's no way to access the return value of
696:meth:`__enter__`. If that value is needed, then it is still necessary to use
697an explicit ``with`` statement.
698
Georg Brandl116aa622007-08-15 14:28:22 +0000699.. seealso::
700
Serhiy Storchakae4ba8722016-03-31 15:30:54 +0300701 :pep:`343` - The "with" statement
Georg Brandl116aa622007-08-15 14:28:22 +0000702 The specification, background, and examples for the Python :keyword:`with`
703 statement.
704
Nick Coghlan0acceb72013-10-20 13:22:21 +1000705.. _single-use-reusable-and-reentrant-cms:
Nick Coghlan8608d262013-10-20 00:30:51 +1000706
Nick Coghlan0acceb72013-10-20 13:22:21 +1000707Single use, reusable and reentrant context managers
708---------------------------------------------------
Nick Coghlan8608d262013-10-20 00:30:51 +1000709
710Most context managers are written in a way that means they can only be
711used effectively in a :keyword:`with` statement once. These single use
712context managers must be created afresh each time they're used -
713attempting to use them a second time will trigger an exception or
714otherwise not work correctly.
715
716This common limitation means that it is generally advisable to create
717context managers directly in the header of the :keyword:`with` statement
718where they are used (as shown in all of the usage examples above).
719
720Files are an example of effectively single use context managers, since
721the first :keyword:`with` statement will close the file, preventing any
722further IO operations using that file object.
723
724Context managers created using :func:`contextmanager` are also single use
725context managers, and will complain about the underlying generator failing
726to yield if an attempt is made to use them a second time::
727
728 >>> from contextlib import contextmanager
729 >>> @contextmanager
730 ... def singleuse():
731 ... print("Before")
732 ... yield
733 ... print("After")
734 ...
735 >>> cm = singleuse()
736 >>> with cm:
737 ... pass
738 ...
739 Before
740 After
741 >>> with cm:
Serhiy Storchakadba90392016-05-10 12:01:23 +0300742 ... pass
Nick Coghlan8608d262013-10-20 00:30:51 +1000743 ...
744 Traceback (most recent call last):
745 ...
746 RuntimeError: generator didn't yield
747
748
749.. _reentrant-cms:
750
751Reentrant context managers
752^^^^^^^^^^^^^^^^^^^^^^^^^^
753
754More sophisticated context managers may be "reentrant". These context
755managers can not only be used in multiple :keyword:`with` statements,
756but may also be used *inside* a :keyword:`with` statement that is already
757using the same context manager.
758
Nick Coghlan8e113b42013-11-03 17:00:51 +1000759:class:`threading.RLock` is an example of a reentrant context manager, as are
760:func:`suppress` and :func:`redirect_stdout`. Here's a very simple example of
761reentrant use::
Nick Coghlan8608d262013-10-20 00:30:51 +1000762
Nick Coghlan8e113b42013-11-03 17:00:51 +1000763 >>> from contextlib import redirect_stdout
764 >>> from io import StringIO
765 >>> stream = StringIO()
766 >>> write_to_stream = redirect_stdout(stream)
767 >>> with write_to_stream:
768 ... print("This is written to the stream rather than stdout")
769 ... with write_to_stream:
770 ... print("This is also written to the stream")
Nick Coghlan8608d262013-10-20 00:30:51 +1000771 ...
Nick Coghlan8e113b42013-11-03 17:00:51 +1000772 >>> print("This is written directly to stdout")
773 This is written directly to stdout
774 >>> print(stream.getvalue())
775 This is written to the stream rather than stdout
776 This is also written to the stream
777
778Real world examples of reentrancy are more likely to involve multiple
779functions calling each other and hence be far more complicated than this
780example.
781
782Note also that being reentrant is *not* the same thing as being thread safe.
783:func:`redirect_stdout`, for example, is definitely not thread safe, as it
784makes a global modification to the system state by binding :data:`sys.stdout`
785to a different stream.
Nick Coghlan8608d262013-10-20 00:30:51 +1000786
787
788.. _reusable-cms:
789
790Reusable context managers
791^^^^^^^^^^^^^^^^^^^^^^^^^
792
793Distinct from both single use and reentrant context managers are "reusable"
794context managers (or, to be completely explicit, "reusable, but not
795reentrant" context managers, since reentrant context managers are also
796reusable). These context managers support being used multiple times, but
797will fail (or otherwise not work correctly) if the specific context manager
798instance has already been used in a containing with statement.
799
Nick Coghlan8e113b42013-11-03 17:00:51 +1000800:class:`threading.Lock` is an example of a reusable, but not reentrant,
801context manager (for a reentrant lock, it is necessary to use
802:class:`threading.RLock` instead).
Nick Coghlan8608d262013-10-20 00:30:51 +1000803
Nick Coghlan8e113b42013-11-03 17:00:51 +1000804Another example of a reusable, but not reentrant, context manager is
805:class:`ExitStack`, as it invokes *all* currently registered callbacks
806when leaving any with statement, regardless of where those callbacks
807were added::
Nick Coghlan8608d262013-10-20 00:30:51 +1000808
Nick Coghlan8e113b42013-11-03 17:00:51 +1000809 >>> from contextlib import ExitStack
810 >>> stack = ExitStack()
811 >>> with stack:
812 ... stack.callback(print, "Callback: from first context")
813 ... print("Leaving first context")
Nick Coghlan8608d262013-10-20 00:30:51 +1000814 ...
Nick Coghlan8e113b42013-11-03 17:00:51 +1000815 Leaving first context
816 Callback: from first context
817 >>> with stack:
818 ... stack.callback(print, "Callback: from second context")
819 ... print("Leaving second context")
820 ...
821 Leaving second context
822 Callback: from second context
823 >>> with stack:
824 ... stack.callback(print, "Callback: from outer context")
825 ... with stack:
826 ... stack.callback(print, "Callback: from inner context")
827 ... print("Leaving inner context")
828 ... print("Leaving outer context")
829 ...
830 Leaving inner context
831 Callback: from inner context
832 Callback: from outer context
833 Leaving outer context
834
835As the output from the example shows, reusing a single stack object across
836multiple with statements works correctly, but attempting to nest them
837will cause the stack to be cleared at the end of the innermost with
838statement, which is unlikely to be desirable behaviour.
839
840Using separate :class:`ExitStack` instances instead of reusing a single
841instance avoids that problem::
842
843 >>> from contextlib import ExitStack
844 >>> with ExitStack() as outer_stack:
845 ... outer_stack.callback(print, "Callback: from outer context")
846 ... with ExitStack() as inner_stack:
847 ... inner_stack.callback(print, "Callback: from inner context")
848 ... print("Leaving inner context")
849 ... print("Leaving outer context")
850 ...
851 Leaving inner context
852 Callback: from inner context
853 Leaving outer context
854 Callback: from outer context