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