1:mod:`!contextlib` --- Utilities for :keyword:`!with`\ -statement contexts
2==========================================================================
3
4.. module:: contextlib
5   :synopsis: Utilities for with-statement contexts.
6
7**Source code:** :source:`Lib/contextlib.py`
8
9--------------
10
11This module provides utilities for common tasks involving the :keyword:`with`
12statement. For more information see also :ref:`typecontextmanager` and
13:ref:`context-managers`.
14
15
16Utilities
17---------
18
19Functions and classes provided:
20
21.. class:: AbstractContextManager
22
23   An :term:`abstract base class` for classes that implement
24   :meth:`object.__enter__` and :meth:`object.__exit__`. A default
25   implementation for :meth:`object.__enter__` is provided which returns
26   ``self`` while :meth:`object.__exit__` is an abstract method which by default
27   returns ``None``. See also the definition of :ref:`typecontextmanager`.
28
29   .. versionadded:: 3.6
30
31
32.. 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
43
44.. decorator:: contextmanager
45
46   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.
49
50   While many objects natively support use in with statements, sometimes a
51   resource needs to be managed that isn't a context manager in its own right,
52   and doesn't implement a ``close()`` method for use with ``contextlib.closing``
53
54   An abstract example would be the following to ensure correct resource
55   management::
56
57      from contextlib import contextmanager
58
59      @contextmanager
60      def managed_resource(*args, **kwds):
61          # Code to acquire resource, e.g.:
62          resource = acquire_resource(*args, **kwds)
63          try:
64              yield resource
65          finally:
66              # Code to release resource, e.g.:
67              release_resource(resource)
68
69   The function can then be used like this::
70
71      >>> with managed_resource(timeout=3600) as resource:
72      ...     # Resource is released at the end of this block,
73      ...     # even if code in the block raises an exception
74
75   The function being decorated must return a :term:`generator`-iterator when
76   called. This iterator must yield exactly one value, which will be bound to
77   the targets in the :keyword:`with` statement's :keyword:`!as` clause, if any.
78
79   At the point where the generator yields, the block nested in the :keyword:`with`
80   statement is executed.  The generator is then resumed after the block is exited.
81   If an unhandled exception occurs in the block, it is reraised inside the
82   generator at the point where the yield occurred.  Thus, you can use a
83   :keyword:`try`...\ :keyword:`except`...\ :keyword:`finally` statement to trap
84   the error (if any), or ensure that some cleanup takes place. If an exception is
85   trapped merely in order to log it or to perform some action (rather than to
86   suppress it entirely), the generator must reraise that exception. Otherwise the
87   generator context manager will indicate to the :keyword:`!with` statement that
88   the exception has been handled, and execution will resume with the statement
89   immediately following the :keyword:`!with` statement.
90
91   :func:`contextmanager` uses :class:`ContextDecorator` so the context managers
92   it creates can be used as decorators as well as in :keyword:`with` statements.
93   When used as a decorator, a new generator instance is implicitly created on
94   each function call (this allows the otherwise "one-shot" context managers
95   created by :func:`contextmanager` to meet the requirement that context
96   managers support multiple invocations in order to be used as decorators).
97
98   .. versionchanged:: 3.2
99      Use of :class:`ContextDecorator`.
100
101
102.. decorator:: asynccontextmanager
103
104   Similar to :func:`~contextlib.contextmanager`, but creates an
105   :ref:`asynchronous context manager <async-context-managers>`.
106
107   This function is a :term:`decorator` that can be used to define a factory
108   function for :keyword:`async with` statement asynchronous context managers,
109   without needing to create a class or separate :meth:`__aenter__` and
110   :meth:`__aexit__` methods. It must be applied to an :term:`asynchronous
111   generator` function.
112
113   A simple example::
114
115      from contextlib import asynccontextmanager
116
117      @asynccontextmanager
118      async def get_connection():
119          conn = await acquire_db_connection()
120          try:
121              yield conn
122          finally:
123              await release_db_connection(conn)
124
125      async def get_all_users():
126          async with get_connection() as conn:
127              return conn.query('SELECT ...')
128
129   .. versionadded:: 3.7
130
131   Context managers defined with :func:`asynccontextmanager` can be used
132   either as decorators or with :keyword:`async with` statements::
133
134     import time
135     from contextlib import asynccontextmanager
136
137     @asynccontextmanager
138     async def timeit():
139         now = time.monotonic()
140         try:
141             yield
142         finally:
143             print(f'it took {time.monotonic() - now}s to run')
144
145     @timeit()
146     async def main():
147         # ... async code ...
148
149   When used as a decorator, a new generator instance is implicitly created on
150   each function call. This allows the otherwise "one-shot" context managers
151   created by :func:`asynccontextmanager` to meet the requirement that context
152   managers support multiple invocations in order to be used as decorators.
153
154  .. versionchanged:: 3.10
155     Async context managers created with :func:`asynccontextmanager` can
156     be used as decorators.
157
158
159.. function:: closing(thing)
160
161   Return a context manager that closes *thing* upon completion of the block.  This
162   is basically equivalent to::
163
164      from contextlib import contextmanager
165
166      @contextmanager
167      def closing(thing):
168          try:
169              yield thing
170          finally:
171              thing.close()
172
173   And lets you write code like this::
174
175      from contextlib import closing
176      from urllib.request import urlopen
177
178      with closing(urlopen('https://www.python.org')) as page:
179          for line in page:
180              print(line)
181
182   without needing to explicitly close ``page``.  Even if an error occurs,
183   ``page.close()`` will be called when the :keyword:`with` block is exited.
184
185
186.. function:: aclosing(thing)
187
188   Return an async context manager that calls the ``aclose()`` method of *thing*
189   upon completion of the block.  This is basically equivalent to::
190
191      from contextlib import asynccontextmanager
192
193      @asynccontextmanager
194      async def aclosing(thing):
195          try:
196              yield thing
197          finally:
198              await thing.aclose()
199
200   Significantly, ``aclosing()`` supports deterministic cleanup of async
201   generators when they happen to exit early by :keyword:`break` or an
202   exception.  For example::
203
204      from contextlib import aclosing
205
206      async with aclosing(my_generator()) as values:
207          async for value in values:
208              if value == 42:
209                  break
210
211   This pattern ensures that the generator's async exit code is executed in
212   the same context as its iterations (so that exceptions and context
213   variables work as expected, and the exit code isn't run after the
214   lifetime of some task it depends on).
215
216   .. versionadded:: 3.10
217
218
219.. _simplifying-support-for-single-optional-context-managers:
220
221.. function:: nullcontext(enter_result=None)
222
223   Return a context manager that returns *enter_result* from ``__enter__``, but
224   otherwise does nothing. It is intended to be used as a stand-in for an
225   optional context manager, for example::
226
227      def myfunction(arg, ignore_exceptions=False):
228          if ignore_exceptions:
229              # Use suppress to ignore all exceptions.
230              cm = contextlib.suppress(Exception)
231          else:
232              # Do not ignore any exceptions, cm has no effect.
233              cm = contextlib.nullcontext()
234          with cm:
235              # Do something
236
237   An example using *enter_result*::
238
239      def process_file(file_or_path):
240          if isinstance(file_or_path, str):
241              # If string, open file
242              cm = open(file_or_path)
243          else:
244              # Caller is responsible for closing file
245              cm = nullcontext(file_or_path)
246
247          with cm as file:
248              # Perform processing on the file
249
250   It can also be used as a stand-in for
251   :ref:`asynchronous context managers <async-context-managers>`::
252
253       async def send_http(session=None):
254           if not session:
255               # If no http session, create it with aiohttp
256               cm = aiohttp.ClientSession()
257           else:
258               # Caller is responsible for closing the session
259               cm = nullcontext(session)
260
261           async with cm as session:
262               # Send http requests with session
263
264   .. versionadded:: 3.7
265
266   .. versionchanged:: 3.10
267      :term:`asynchronous context manager` support was added.
268
269
270
271.. function:: suppress(*exceptions)
272
273   Return a context manager that suppresses any of the specified exceptions
274   if they occur in the body of a :keyword:`!with` statement and then
275   resumes execution with the first statement following the end of the
276   :keyword:`!with` statement.
277
278   As with any other mechanism that completely suppresses exceptions, this
279   context manager should be used only to cover very specific errors where
280   silently continuing with program execution is known to be the right
281   thing to do.
282
283   For example::
284
285       from contextlib import suppress
286
287       with suppress(FileNotFoundError):
288           os.remove('somefile.tmp')
289
290       with suppress(FileNotFoundError):
291           os.remove('someotherfile.tmp')
292
293   This code is equivalent to::
294
295       try:
296           os.remove('somefile.tmp')
297       except FileNotFoundError:
298           pass
299
300       try:
301           os.remove('someotherfile.tmp')
302       except FileNotFoundError:
303           pass
304
305   This context manager is :ref:`reentrant <reentrant-cms>`.
306
307   .. versionadded:: 3.4
308
309
310.. function:: redirect_stdout(new_target)
311
312   Context manager for temporarily redirecting :data:`sys.stdout` to
313   another file or file-like object.
314
315   This tool adds flexibility to existing functions or classes whose output
316   is hardwired to stdout.
317
318   For example, the output of :func:`help` normally is sent to *sys.stdout*.
319   You can capture that output in a string by redirecting the output to an
320   :class:`io.StringIO` object. The replacement stream is returned from the
321   ``__enter__`` method and so is available as the target of the
322   :keyword:`with` statement::
323
324        with redirect_stdout(io.StringIO()) as f:
325            help(pow)
326        s = f.getvalue()
327
328   To send the output of :func:`help` to a file on disk, redirect the output
329   to a regular file::
330
331        with open('help.txt', 'w') as f:
332            with redirect_stdout(f):
333                help(pow)
334
335   To send the output of :func:`help` to *sys.stderr*::
336
337        with redirect_stdout(sys.stderr):
338            help(pow)
339
340   Note that the global side effect on :data:`sys.stdout` means that this
341   context manager is not suitable for use in library code and most threaded
342   applications. It also has no effect on the output of subprocesses.
343   However, it is still a useful approach for many utility scripts.
344
345   This context manager is :ref:`reentrant <reentrant-cms>`.
346
347   .. versionadded:: 3.4
348
349
350.. function:: redirect_stderr(new_target)
351
352   Similar to :func:`~contextlib.redirect_stdout` but redirecting
353   :data:`sys.stderr` to another file or file-like object.
354
355   This context manager is :ref:`reentrant <reentrant-cms>`.
356
357   .. versionadded:: 3.5
358
359
360.. function:: chdir(path)
361
362   Non parallel-safe context manager to change the current working directory.
363   As this changes a global state, the working directory, it is not suitable
364   for use in most threaded or async contexts. It is also not suitable for most
365   non-linear code execution, like generators, where the program execution is
366   temporarily relinquished -- unless explicitly desired, you should not yield
367   when this context manager is active.
368
369   This is a simple wrapper around :func:`~os.chdir`, it changes the current
370   working directory upon entering and restores the old one on exit.
371
372   This context manager is :ref:`reentrant <reentrant-cms>`.
373
374   .. versionadded:: 3.11
375
376
377.. class:: ContextDecorator()
378
379   A base class that enables a context manager to also be used as a decorator.
380
381   Context managers inheriting from ``ContextDecorator`` have to implement
382   ``__enter__`` and ``__exit__`` as normal. ``__exit__`` retains its optional
383   exception handling even when used as a decorator.
384
385   ``ContextDecorator`` is used by :func:`contextmanager`, so you get this
386   functionality automatically.
387
388   Example of ``ContextDecorator``::
389
390      from contextlib import ContextDecorator
391
392      class mycontext(ContextDecorator):
393          def __enter__(self):
394              print('Starting')
395              return self
396
397          def __exit__(self, *exc):
398              print('Finishing')
399              return False
400
401   The class can then be used like this::
402
403      >>> @mycontext()
404      ... def function():
405      ...     print('The bit in the middle')
406      ...
407      >>> function()
408      Starting
409      The bit in the middle
410      Finishing
411
412      >>> with mycontext():
413      ...     print('The bit in the middle')
414      ...
415      Starting
416      The bit in the middle
417      Finishing
418
419   This change is just syntactic sugar for any construct of the following form::
420
421      def f():
422          with cm():
423              # Do stuff
424
425   ``ContextDecorator`` lets you instead write::
426
427      @cm()
428      def f():
429          # Do stuff
430
431   It makes it clear that the ``cm`` applies to the whole function, rather than
432   just a piece of it (and saving an indentation level is nice, too).
433
434   Existing context managers that already have a base class can be extended by
435   using ``ContextDecorator`` as a mixin class::
436
437      from contextlib import ContextDecorator
438
439      class mycontext(ContextBaseClass, ContextDecorator):
440          def __enter__(self):
441              return self
442
443          def __exit__(self, *exc):
444              return False
445
446   .. note::
447      As the decorated function must be able to be called multiple times, the
448      underlying context manager must support use in multiple :keyword:`with`
449      statements. If this is not the case, then the original construct with the
450      explicit :keyword:`!with` statement inside the function should be used.
451
452   .. versionadded:: 3.2
453
454
455.. class:: AsyncContextDecorator
456
457   Similar to :class:`ContextDecorator` but only for asynchronous functions.
458
459   Example of ``AsyncContextDecorator``::
460
461      from asyncio import run
462      from contextlib import AsyncContextDecorator
463
464      class mycontext(AsyncContextDecorator):
465          async def __aenter__(self):
466              print('Starting')
467              return self
468
469          async def __aexit__(self, *exc):
470              print('Finishing')
471              return False
472
473   The class can then be used like this::
474
475      >>> @mycontext()
476      ... async def function():
477      ...     print('The bit in the middle')
478      ...
479      >>> run(function())
480      Starting
481      The bit in the middle
482      Finishing
483
484      >>> async def function():
485      ...    async with mycontext():
486      ...         print('The bit in the middle')
487      ...
488      >>> run(function())
489      Starting
490      The bit in the middle
491      Finishing
492
493   .. versionadded:: 3.10
494
495
496.. class:: ExitStack()
497
498   A context manager that is designed to make it easy to programmatically
499   combine other context managers and cleanup functions, especially those
500   that are optional or otherwise driven by input data.
501
502   For example, a set of files may easily be handled in a single with
503   statement as follows::
504
505      with ExitStack() as stack:
506          files = [stack.enter_context(open(fname)) for fname in filenames]
507          # All opened files will automatically be closed at the end of
508          # the with statement, even if attempts to open files later
509          # in the list raise an exception
510
511   The :meth:`__enter__` method returns the :class:`ExitStack` instance, and
512   performs no additional operations.
513
514   Each instance maintains a stack of registered callbacks that are called in
515   reverse order when the instance is closed (either explicitly or implicitly
516   at the end of a :keyword:`with` statement). Note that callbacks are *not*
517   invoked implicitly when the context stack instance is garbage collected.
518
519   This stack model is used so that context managers that acquire their
520   resources in their ``__init__`` method (such as file objects) can be
521   handled correctly.
522
523   Since registered callbacks are invoked in the reverse order of
524   registration, this ends up behaving as if multiple nested :keyword:`with`
525   statements had been used with the registered set of callbacks. This even
526   extends to exception handling - if an inner callback suppresses or replaces
527   an exception, then outer callbacks will be passed arguments based on that
528   updated state.
529
530   This is a relatively low level API that takes care of the details of
531   correctly unwinding the stack of exit callbacks. It provides a suitable
532   foundation for higher level context managers that manipulate the exit
533   stack in application specific ways.
534
535   .. versionadded:: 3.3
536
537   .. method:: enter_context(cm)
538
539      Enters a new context manager and adds its :meth:`__exit__` method to
540      the callback stack. The return value is the result of the context
541      manager's own :meth:`__enter__` method.
542
543      These context managers may suppress exceptions just as they normally
544      would if used directly as part of a :keyword:`with` statement.
545
546      .. versionchanged:: 3.11
547         Raises :exc:`TypeError` instead of :exc:`AttributeError` if *cm*
548         is not a context manager.
549
550   .. method:: push(exit)
551
552      Adds a context manager's :meth:`__exit__` method to the callback stack.
553
554      As ``__enter__`` is *not* invoked, this method can be used to cover
555      part of an :meth:`__enter__` implementation with a context manager's own
556      :meth:`__exit__` method.
557
558      If passed an object that is not a context manager, this method assumes
559      it is a callback with the same signature as a context manager's
560      :meth:`__exit__` method and adds it directly to the callback stack.
561
562      By returning true values, these callbacks can suppress exceptions the
563      same way context manager :meth:`__exit__` methods can.
564
565      The passed in object is returned from the function, allowing this
566      method to be used as a function decorator.
567
568   .. method:: callback(callback, /, *args, **kwds)
569
570      Accepts an arbitrary callback function and arguments and adds it to
571      the callback stack.
572
573      Unlike the other methods, callbacks added this way cannot suppress
574      exceptions (as they are never passed the exception details).
575
576      The passed in callback is returned from the function, allowing this
577      method to be used as a function decorator.
578
579   .. method:: pop_all()
580
581      Transfers the callback stack to a fresh :class:`ExitStack` instance
582      and returns it. No callbacks are invoked by this operation - instead,
583      they will now be invoked when the new stack is closed (either
584      explicitly or implicitly at the end of a :keyword:`with` statement).
585
586      For example, a group of files can be opened as an "all or nothing"
587      operation as follows::
588
589         with ExitStack() as stack:
590             files = [stack.enter_context(open(fname)) for fname in filenames]
591             # Hold onto the close method, but don't call it yet.
592             close_files = stack.pop_all().close
593             # If opening any file fails, all previously opened files will be
594             # closed automatically. If all files are opened successfully,
595             # they will remain open even after the with statement ends.
596             # close_files() can then be invoked explicitly to close them all.
597
598   .. method:: close()
599
600      Immediately unwinds the callback stack, invoking callbacks in the
601      reverse order of registration. For any context managers and exit
602      callbacks registered, the arguments passed in will indicate that no
603      exception occurred.
604
605.. class:: AsyncExitStack()
606
607   An :ref:`asynchronous context manager <async-context-managers>`, similar
608   to :class:`ExitStack`, that supports combining both synchronous and
609   asynchronous context managers, as well as having coroutines for
610   cleanup logic.
611
612   The :meth:`close` method is not implemented, :meth:`aclose` must be used
613   instead.
614
615   .. coroutinemethod:: enter_async_context(cm)
616
617      Similar to :meth:`enter_context` but expects an asynchronous context
618      manager.
619
620      .. versionchanged:: 3.11
621         Raises :exc:`TypeError` instead of :exc:`AttributeError` if *cm*
622         is not an asynchronous context manager.
623
624   .. method:: push_async_exit(exit)
625
626      Similar to :meth:`push` but expects either an asynchronous context manager
627      or a coroutine function.
628
629   .. method:: push_async_callback(callback, /, *args, **kwds)
630
631      Similar to :meth:`callback` but expects a coroutine function.
632
633   .. coroutinemethod:: aclose()
634
635      Similar to :meth:`close` but properly handles awaitables.
636
637   Continuing the example for :func:`asynccontextmanager`::
638
639      async with AsyncExitStack() as stack:
640          connections = [await stack.enter_async_context(get_connection())
641              for i in range(5)]
642          # All opened connections will automatically be released at the end of
643          # the async with statement, even if attempts to open a connection
644          # later in the list raise an exception.
645
646   .. versionadded:: 3.7
647
648Examples and Recipes
649--------------------
650
651This section describes some examples and recipes for making effective use of
652the tools provided by :mod:`contextlib`.
653
654
655Supporting a variable number of context managers
656^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
657
658The primary use case for :class:`ExitStack` is the one given in the class
659documentation: supporting a variable number of context managers and other
660cleanup operations in a single :keyword:`with` statement. The variability
661may come from the number of context managers needed being driven by user
662input (such as opening a user specified collection of files), or from
663some of the context managers being optional::
664
665    with ExitStack() as stack:
666        for resource in resources:
667            stack.enter_context(resource)
668        if need_special_resource():
669            special = acquire_special_resource()
670            stack.callback(release_special_resource, special)
671        # Perform operations that use the acquired resources
672
673As shown, :class:`ExitStack` also makes it quite easy to use :keyword:`with`
674statements to manage arbitrary resources that don't natively support the
675context management protocol.
676
677
678Catching exceptions from ``__enter__`` methods
679^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
680
681It is occasionally desirable to catch exceptions from an ``__enter__``
682method implementation, *without* inadvertently catching exceptions from
683the :keyword:`with` statement body or the context manager's ``__exit__``
684method. By using :class:`ExitStack` the steps in the context management
685protocol can be separated slightly in order to allow this::
686
687   stack = ExitStack()
688   try:
689       x = stack.enter_context(cm)
690   except Exception:
691       # handle __enter__ exception
692   else:
693       with stack:
694           # Handle normal case
695
696Actually needing to do this is likely to indicate that the underlying API
697should be providing a direct resource management interface for use with
698:keyword:`try`/:keyword:`except`/:keyword:`finally` statements, but not
699all APIs are well designed in that regard. When a context manager is the
700only resource management API provided, then :class:`ExitStack` can make it
701easier to handle various situations that can't be handled directly in a
702:keyword:`with` statement.
703
704
705Cleaning up in an ``__enter__`` implementation
706^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
707
708As noted in the documentation of :meth:`ExitStack.push`, this
709method can be useful in cleaning up an already allocated resource if later
710steps in the :meth:`__enter__` implementation fail.
711
712Here's an example of doing this for a context manager that accepts resource
713acquisition and release functions, along with an optional validation function,
714and maps them to the context management protocol::
715
716   from contextlib import contextmanager, AbstractContextManager, ExitStack
717
718   class ResourceManager(AbstractContextManager):
719
720       def __init__(self, acquire_resource, release_resource, check_resource_ok=None):
721           self.acquire_resource = acquire_resource
722           self.release_resource = release_resource
723           if check_resource_ok is None:
724               def check_resource_ok(resource):
725                   return True
726           self.check_resource_ok = check_resource_ok
727
728       @contextmanager
729       def _cleanup_on_error(self):
730           with ExitStack() as stack:
731               stack.push(self)
732               yield
733               # The validation check passed and didn't raise an exception
734               # Accordingly, we want to keep the resource, and pass it
735               # back to our caller
736               stack.pop_all()
737
738       def __enter__(self):
739           resource = self.acquire_resource()
740           with self._cleanup_on_error():
741               if not self.check_resource_ok(resource):
742                   msg = "Failed validation for {!r}"
743                   raise RuntimeError(msg.format(resource))
744           return resource
745
746       def __exit__(self, *exc_details):
747           # We don't need to duplicate any of our resource release logic
748           self.release_resource()
749
750
751Replacing any use of ``try-finally`` and flag variables
752^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
753
754A pattern you will sometimes see is a ``try-finally`` statement with a flag
755variable to indicate whether or not the body of the ``finally`` clause should
756be executed. In its simplest form (that can't already be handled just by
757using an ``except`` clause instead), it looks something like this::
758
759   cleanup_needed = True
760   try:
761       result = perform_operation()
762       if result:
763           cleanup_needed = False
764   finally:
765       if cleanup_needed:
766           cleanup_resources()
767
768As with any ``try`` statement based code, this can cause problems for
769development and review, because the setup code and the cleanup code can end
770up being separated by arbitrarily long sections of code.
771
772:class:`ExitStack` makes it possible to instead register a callback for
773execution at the end of a ``with`` statement, and then later decide to skip
774executing that callback::
775
776   from contextlib import ExitStack
777
778   with ExitStack() as stack:
779       stack.callback(cleanup_resources)
780       result = perform_operation()
781       if result:
782           stack.pop_all()
783
784This allows the intended cleanup up behaviour to be made explicit up front,
785rather than requiring a separate flag variable.
786
787If a particular application uses this pattern a lot, it can be simplified
788even further by means of a small helper class::
789
790   from contextlib import ExitStack
791
792   class Callback(ExitStack):
793       def __init__(self, callback, /, *args, **kwds):
794           super().__init__()
795           self.callback(callback, *args, **kwds)
796
797       def cancel(self):
798           self.pop_all()
799
800   with Callback(cleanup_resources) as cb:
801       result = perform_operation()
802       if result:
803           cb.cancel()
804
805If the resource cleanup isn't already neatly bundled into a standalone
806function, then it is still possible to use the decorator form of
807:meth:`ExitStack.callback` to declare the resource cleanup in
808advance::
809
810   from contextlib import ExitStack
811
812   with ExitStack() as stack:
813       @stack.callback
814       def cleanup_resources():
815           ...
816       result = perform_operation()
817       if result:
818           stack.pop_all()
819
820Due to the way the decorator protocol works, a callback function
821declared this way cannot take any parameters. Instead, any resources to
822be released must be accessed as closure variables.
823
824
825Using a context manager as a function decorator
826^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
827
828:class:`ContextDecorator` makes it possible to use a context manager in
829both an ordinary ``with`` statement and also as a function decorator.
830
831For example, it is sometimes useful to wrap functions or groups of statements
832with a logger that can track the time of entry and time of exit.  Rather than
833writing both a function decorator and a context manager for the task,
834inheriting from :class:`ContextDecorator` provides both capabilities in a
835single definition::
836
837    from contextlib import ContextDecorator
838    import logging
839
840    logging.basicConfig(level=logging.INFO)
841
842    class track_entry_and_exit(ContextDecorator):
843        def __init__(self, name):
844            self.name = name
845
846        def __enter__(self):
847            logging.info('Entering: %s', self.name)
848
849        def __exit__(self, exc_type, exc, exc_tb):
850            logging.info('Exiting: %s', self.name)
851
852Instances of this class can be used as both a context manager::
853
854    with track_entry_and_exit('widget loader'):
855        print('Some time consuming activity goes here')
856        load_widget()
857
858And also as a function decorator::
859
860    @track_entry_and_exit('widget loader')
861    def activity():
862        print('Some time consuming activity goes here')
863        load_widget()
864
865Note that there is one additional limitation when using context managers
866as function decorators: there's no way to access the return value of
867:meth:`__enter__`. If that value is needed, then it is still necessary to use
868an explicit ``with`` statement.
869
870.. seealso::
871
872   :pep:`343` - The "with" statement
873      The specification, background, and examples for the Python :keyword:`with`
874      statement.
875
876.. _single-use-reusable-and-reentrant-cms:
877
878Single use, reusable and reentrant context managers
879---------------------------------------------------
880
881Most context managers are written in a way that means they can only be
882used effectively in a :keyword:`with` statement once. These single use
883context managers must be created afresh each time they're used -
884attempting to use them a second time will trigger an exception or
885otherwise not work correctly.
886
887This common limitation means that it is generally advisable to create
888context managers directly in the header of the :keyword:`with` statement
889where they are used (as shown in all of the usage examples above).
890
891Files are an example of effectively single use context managers, since
892the first :keyword:`with` statement will close the file, preventing any
893further IO operations using that file object.
894
895Context managers created using :func:`contextmanager` are also single use
896context managers, and will complain about the underlying generator failing
897to yield if an attempt is made to use them a second time::
898
899    >>> from contextlib import contextmanager
900    >>> @contextmanager
901    ... def singleuse():
902    ...     print("Before")
903    ...     yield
904    ...     print("After")
905    ...
906    >>> cm = singleuse()
907    >>> with cm:
908    ...     pass
909    ...
910    Before
911    After
912    >>> with cm:
913    ...     pass
914    ...
915    Traceback (most recent call last):
916        ...
917    RuntimeError: generator didn't yield
918
919
920.. _reentrant-cms:
921
922Reentrant context managers
923^^^^^^^^^^^^^^^^^^^^^^^^^^
924
925More sophisticated context managers may be "reentrant". These context
926managers can not only be used in multiple :keyword:`with` statements,
927but may also be used *inside* a :keyword:`!with` statement that is already
928using the same context manager.
929
930:class:`threading.RLock` is an example of a reentrant context manager, as are
931:func:`suppress`, :func:`redirect_stdout`, and :func:`chdir`. Here's a very
932simple example of reentrant use::
933
934    >>> from contextlib import redirect_stdout
935    >>> from io import StringIO
936    >>> stream = StringIO()
937    >>> write_to_stream = redirect_stdout(stream)
938    >>> with write_to_stream:
939    ...     print("This is written to the stream rather than stdout")
940    ...     with write_to_stream:
941    ...         print("This is also written to the stream")
942    ...
943    >>> print("This is written directly to stdout")
944    This is written directly to stdout
945    >>> print(stream.getvalue())
946    This is written to the stream rather than stdout
947    This is also written to the stream
948
949Real world examples of reentrancy are more likely to involve multiple
950functions calling each other and hence be far more complicated than this
951example.
952
953Note also that being reentrant is *not* the same thing as being thread safe.
954:func:`redirect_stdout`, for example, is definitely not thread safe, as it
955makes a global modification to the system state by binding :data:`sys.stdout`
956to a different stream.
957
958
959.. _reusable-cms:
960
961Reusable context managers
962^^^^^^^^^^^^^^^^^^^^^^^^^
963
964Distinct from both single use and reentrant context managers are "reusable"
965context managers (or, to be completely explicit, "reusable, but not
966reentrant" context managers, since reentrant context managers are also
967reusable). These context managers support being used multiple times, but
968will fail (or otherwise not work correctly) if the specific context manager
969instance has already been used in a containing with statement.
970
971:class:`threading.Lock` is an example of a reusable, but not reentrant,
972context manager (for a reentrant lock, it is necessary to use
973:class:`threading.RLock` instead).
974
975Another example of a reusable, but not reentrant, context manager is
976:class:`ExitStack`, as it invokes *all* currently registered callbacks
977when leaving any with statement, regardless of where those callbacks
978were added::
979
980    >>> from contextlib import ExitStack
981    >>> stack = ExitStack()
982    >>> with stack:
983    ...     stack.callback(print, "Callback: from first context")
984    ...     print("Leaving first context")
985    ...
986    Leaving first context
987    Callback: from first context
988    >>> with stack:
989    ...     stack.callback(print, "Callback: from second context")
990    ...     print("Leaving second context")
991    ...
992    Leaving second context
993    Callback: from second context
994    >>> with stack:
995    ...     stack.callback(print, "Callback: from outer context")
996    ...     with stack:
997    ...         stack.callback(print, "Callback: from inner context")
998    ...         print("Leaving inner context")
999    ...     print("Leaving outer context")
1000    ...
1001    Leaving inner context
1002    Callback: from inner context
1003    Callback: from outer context
1004    Leaving outer context
1005
1006As the output from the example shows, reusing a single stack object across
1007multiple with statements works correctly, but attempting to nest them
1008will cause the stack to be cleared at the end of the innermost with
1009statement, which is unlikely to be desirable behaviour.
1010
1011Using separate :class:`ExitStack` instances instead of reusing a single
1012instance avoids that problem::
1013
1014    >>> from contextlib import ExitStack
1015    >>> with ExitStack() as outer_stack:
1016    ...     outer_stack.callback(print, "Callback: from outer context")
1017    ...     with ExitStack() as inner_stack:
1018    ...         inner_stack.callback(print, "Callback: from inner context")
1019    ...         print("Leaving inner context")
1020    ...     print("Leaving outer context")
1021    ...
1022    Leaving inner context
1023    Callback: from inner context
1024    Leaving outer context
1025    Callback: from outer context
1026