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