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.. function:: chdir(path) 359 360 Non parallel-safe context manager to change the current working directory. 361 As this changes a global state, the working directory, it is not suitable 362 for use in most threaded or async contexts. It is also not suitable for most 363 non-linear code execution, like generators, where the program execution is 364 temporarily relinquished -- unless explicitely desired, you should not yield 365 when this context manager is active. 366 367 This is a simple wrapper around :func:`~os.chdir`, it changes the current 368 working directory upon entering and restores the old one on exit. 369 370 This context manager is :ref:`reentrant <reentrant-cms>`. 371 372 .. versionadded:: 3.11 373 374 375.. class:: ContextDecorator() 376 377 A base class that enables a context manager to also be used as a decorator. 378 379 Context managers inheriting from ``ContextDecorator`` have to implement 380 ``__enter__`` and ``__exit__`` as normal. ``__exit__`` retains its optional 381 exception handling even when used as a decorator. 382 383 ``ContextDecorator`` is used by :func:`contextmanager`, so you get this 384 functionality automatically. 385 386 Example of ``ContextDecorator``:: 387 388 from contextlib import ContextDecorator 389 390 class mycontext(ContextDecorator): 391 def __enter__(self): 392 print('Starting') 393 return self 394 395 def __exit__(self, *exc): 396 print('Finishing') 397 return False 398 399 >>> @mycontext() 400 ... def function(): 401 ... print('The bit in the middle') 402 ... 403 >>> function() 404 Starting 405 The bit in the middle 406 Finishing 407 408 >>> with mycontext(): 409 ... print('The bit in the middle') 410 ... 411 Starting 412 The bit in the middle 413 Finishing 414 415 This change is just syntactic sugar for any construct of the following form:: 416 417 def f(): 418 with cm(): 419 # Do stuff 420 421 ``ContextDecorator`` lets you instead write:: 422 423 @cm() 424 def f(): 425 # Do stuff 426 427 It makes it clear that the ``cm`` applies to the whole function, rather than 428 just a piece of it (and saving an indentation level is nice, too). 429 430 Existing context managers that already have a base class can be extended by 431 using ``ContextDecorator`` as a mixin class:: 432 433 from contextlib import ContextDecorator 434 435 class mycontext(ContextBaseClass, ContextDecorator): 436 def __enter__(self): 437 return self 438 439 def __exit__(self, *exc): 440 return False 441 442 .. note:: 443 As the decorated function must be able to be called multiple times, the 444 underlying context manager must support use in multiple :keyword:`with` 445 statements. If this is not the case, then the original construct with the 446 explicit :keyword:`!with` statement inside the function should be used. 447 448 .. versionadded:: 3.2 449 450 451.. class:: AsyncContextDecorator 452 453 Similar to :class:`ContextDecorator` but only for asynchronous functions. 454 455 Example of ``AsyncContextDecorator``:: 456 457 from asyncio import run 458 from contextlib import AsyncContextDecorator 459 460 class mycontext(AsyncContextDecorator): 461 async def __aenter__(self): 462 print('Starting') 463 return self 464 465 async def __aexit__(self, *exc): 466 print('Finishing') 467 return False 468 469 >>> @mycontext() 470 ... async def function(): 471 ... print('The bit in the middle') 472 ... 473 >>> run(function()) 474 Starting 475 The bit in the middle 476 Finishing 477 478 >>> async def function(): 479 ... async with mycontext(): 480 ... print('The bit in the middle') 481 ... 482 >>> run(function()) 483 Starting 484 The bit in the middle 485 Finishing 486 487 .. versionadded:: 3.10 488 489 490.. class:: ExitStack() 491 492 A context manager that is designed to make it easy to programmatically 493 combine other context managers and cleanup functions, especially those 494 that are optional or otherwise driven by input data. 495 496 For example, a set of files may easily be handled in a single with 497 statement as follows:: 498 499 with ExitStack() as stack: 500 files = [stack.enter_context(open(fname)) for fname in filenames] 501 # All opened files will automatically be closed at the end of 502 # the with statement, even if attempts to open files later 503 # in the list raise an exception 504 505 Each instance maintains a stack of registered callbacks that are called in 506 reverse order when the instance is closed (either explicitly or implicitly 507 at the end of a :keyword:`with` statement). Note that callbacks are *not* 508 invoked implicitly when the context stack instance is garbage collected. 509 510 This stack model is used so that context managers that acquire their 511 resources in their ``__init__`` method (such as file objects) can be 512 handled correctly. 513 514 Since registered callbacks are invoked in the reverse order of 515 registration, this ends up behaving as if multiple nested :keyword:`with` 516 statements had been used with the registered set of callbacks. This even 517 extends to exception handling - if an inner callback suppresses or replaces 518 an exception, then outer callbacks will be passed arguments based on that 519 updated state. 520 521 This is a relatively low level API that takes care of the details of 522 correctly unwinding the stack of exit callbacks. It provides a suitable 523 foundation for higher level context managers that manipulate the exit 524 stack in application specific ways. 525 526 .. versionadded:: 3.3 527 528 .. method:: enter_context(cm) 529 530 Enters a new context manager and adds its :meth:`__exit__` method to 531 the callback stack. The return value is the result of the context 532 manager's own :meth:`__enter__` method. 533 534 These context managers may suppress exceptions just as they normally 535 would if used directly as part of a :keyword:`with` statement. 536 537 .. versionchanged:: 3.11 538 Raises :exc:`TypeError` instead of :exc:`AttributeError` if *cm* 539 is not a context manager. 540 541 .. method:: push(exit) 542 543 Adds a context manager's :meth:`__exit__` method to the callback stack. 544 545 As ``__enter__`` is *not* invoked, this method can be used to cover 546 part of an :meth:`__enter__` implementation with a context manager's own 547 :meth:`__exit__` method. 548 549 If passed an object that is not a context manager, this method assumes 550 it is a callback with the same signature as a context manager's 551 :meth:`__exit__` method and adds it directly to the callback stack. 552 553 By returning true values, these callbacks can suppress exceptions the 554 same way context manager :meth:`__exit__` methods can. 555 556 The passed in object is returned from the function, allowing this 557 method to be used as a function decorator. 558 559 .. method:: callback(callback, /, *args, **kwds) 560 561 Accepts an arbitrary callback function and arguments and adds it to 562 the callback stack. 563 564 Unlike the other methods, callbacks added this way cannot suppress 565 exceptions (as they are never passed the exception details). 566 567 The passed in callback is returned from the function, allowing this 568 method to be used as a function decorator. 569 570 .. method:: pop_all() 571 572 Transfers the callback stack to a fresh :class:`ExitStack` instance 573 and returns it. No callbacks are invoked by this operation - instead, 574 they will now be invoked when the new stack is closed (either 575 explicitly or implicitly at the end of a :keyword:`with` statement). 576 577 For example, a group of files can be opened as an "all or nothing" 578 operation as follows:: 579 580 with ExitStack() as stack: 581 files = [stack.enter_context(open(fname)) for fname in filenames] 582 # Hold onto the close method, but don't call it yet. 583 close_files = stack.pop_all().close 584 # If opening any file fails, all previously opened files will be 585 # closed automatically. If all files are opened successfully, 586 # they will remain open even after the with statement ends. 587 # close_files() can then be invoked explicitly to close them all. 588 589 .. method:: close() 590 591 Immediately unwinds the callback stack, invoking callbacks in the 592 reverse order of registration. For any context managers and exit 593 callbacks registered, the arguments passed in will indicate that no 594 exception occurred. 595 596.. class:: AsyncExitStack() 597 598 An :ref:`asynchronous context manager <async-context-managers>`, similar 599 to :class:`ExitStack`, that supports combining both synchronous and 600 asynchronous context managers, as well as having coroutines for 601 cleanup logic. 602 603 The :meth:`close` method is not implemented, :meth:`aclose` must be used 604 instead. 605 606 .. coroutinemethod:: enter_async_context(cm) 607 608 Similar to :meth:`enter_context` but expects an asynchronous context 609 manager. 610 611 .. versionchanged:: 3.11 612 Raises :exc:`TypeError` instead of :exc:`AttributeError` if *cm* 613 is not an asynchronous context manager. 614 615 .. method:: push_async_exit(exit) 616 617 Similar to :meth:`push` but expects either an asynchronous context manager 618 or a coroutine function. 619 620 .. method:: push_async_callback(callback, /, *args, **kwds) 621 622 Similar to :meth:`callback` but expects a coroutine function. 623 624 .. coroutinemethod:: aclose() 625 626 Similar to :meth:`close` but properly handles awaitables. 627 628 Continuing the example for :func:`asynccontextmanager`:: 629 630 async with AsyncExitStack() as stack: 631 connections = [await stack.enter_async_context(get_connection()) 632 for i in range(5)] 633 # All opened connections will automatically be released at the end of 634 # the async with statement, even if attempts to open a connection 635 # later in the list raise an exception. 636 637 .. versionadded:: 3.7 638 639Examples and Recipes 640-------------------- 641 642This section describes some examples and recipes for making effective use of 643the tools provided by :mod:`contextlib`. 644 645 646Supporting a variable number of context managers 647^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 648 649The primary use case for :class:`ExitStack` is the one given in the class 650documentation: supporting a variable number of context managers and other 651cleanup operations in a single :keyword:`with` statement. The variability 652may come from the number of context managers needed being driven by user 653input (such as opening a user specified collection of files), or from 654some of the context managers being optional:: 655 656 with ExitStack() as stack: 657 for resource in resources: 658 stack.enter_context(resource) 659 if need_special_resource(): 660 special = acquire_special_resource() 661 stack.callback(release_special_resource, special) 662 # Perform operations that use the acquired resources 663 664As shown, :class:`ExitStack` also makes it quite easy to use :keyword:`with` 665statements to manage arbitrary resources that don't natively support the 666context management protocol. 667 668 669Catching exceptions from ``__enter__`` methods 670^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 671 672It is occasionally desirable to catch exceptions from an ``__enter__`` 673method implementation, *without* inadvertently catching exceptions from 674the :keyword:`with` statement body or the context manager's ``__exit__`` 675method. By using :class:`ExitStack` the steps in the context management 676protocol can be separated slightly in order to allow this:: 677 678 stack = ExitStack() 679 try: 680 x = stack.enter_context(cm) 681 except Exception: 682 # handle __enter__ exception 683 else: 684 with stack: 685 # Handle normal case 686 687Actually needing to do this is likely to indicate that the underlying API 688should be providing a direct resource management interface for use with 689:keyword:`try`/:keyword:`except`/:keyword:`finally` statements, but not 690all APIs are well designed in that regard. When a context manager is the 691only resource management API provided, then :class:`ExitStack` can make it 692easier to handle various situations that can't be handled directly in a 693:keyword:`with` statement. 694 695 696Cleaning up in an ``__enter__`` implementation 697^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 698 699As noted in the documentation of :meth:`ExitStack.push`, this 700method can be useful in cleaning up an already allocated resource if later 701steps in the :meth:`__enter__` implementation fail. 702 703Here's an example of doing this for a context manager that accepts resource 704acquisition and release functions, along with an optional validation function, 705and maps them to the context management protocol:: 706 707 from contextlib import contextmanager, AbstractContextManager, ExitStack 708 709 class ResourceManager(AbstractContextManager): 710 711 def __init__(self, acquire_resource, release_resource, check_resource_ok=None): 712 self.acquire_resource = acquire_resource 713 self.release_resource = release_resource 714 if check_resource_ok is None: 715 def check_resource_ok(resource): 716 return True 717 self.check_resource_ok = check_resource_ok 718 719 @contextmanager 720 def _cleanup_on_error(self): 721 with ExitStack() as stack: 722 stack.push(self) 723 yield 724 # The validation check passed and didn't raise an exception 725 # Accordingly, we want to keep the resource, and pass it 726 # back to our caller 727 stack.pop_all() 728 729 def __enter__(self): 730 resource = self.acquire_resource() 731 with self._cleanup_on_error(): 732 if not self.check_resource_ok(resource): 733 msg = "Failed validation for {!r}" 734 raise RuntimeError(msg.format(resource)) 735 return resource 736 737 def __exit__(self, *exc_details): 738 # We don't need to duplicate any of our resource release logic 739 self.release_resource() 740 741 742Replacing any use of ``try-finally`` and flag variables 743^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 744 745A pattern you will sometimes see is a ``try-finally`` statement with a flag 746variable to indicate whether or not the body of the ``finally`` clause should 747be executed. In its simplest form (that can't already be handled just by 748using an ``except`` clause instead), it looks something like this:: 749 750 cleanup_needed = True 751 try: 752 result = perform_operation() 753 if result: 754 cleanup_needed = False 755 finally: 756 if cleanup_needed: 757 cleanup_resources() 758 759As with any ``try`` statement based code, this can cause problems for 760development and review, because the setup code and the cleanup code can end 761up being separated by arbitrarily long sections of code. 762 763:class:`ExitStack` makes it possible to instead register a callback for 764execution at the end of a ``with`` statement, and then later decide to skip 765executing that callback:: 766 767 from contextlib import ExitStack 768 769 with ExitStack() as stack: 770 stack.callback(cleanup_resources) 771 result = perform_operation() 772 if result: 773 stack.pop_all() 774 775This allows the intended cleanup up behaviour to be made explicit up front, 776rather than requiring a separate flag variable. 777 778If a particular application uses this pattern a lot, it can be simplified 779even further by means of a small helper class:: 780 781 from contextlib import ExitStack 782 783 class Callback(ExitStack): 784 def __init__(self, callback, /, *args, **kwds): 785 super().__init__() 786 self.callback(callback, *args, **kwds) 787 788 def cancel(self): 789 self.pop_all() 790 791 with Callback(cleanup_resources) as cb: 792 result = perform_operation() 793 if result: 794 cb.cancel() 795 796If the resource cleanup isn't already neatly bundled into a standalone 797function, then it is still possible to use the decorator form of 798:meth:`ExitStack.callback` to declare the resource cleanup in 799advance:: 800 801 from contextlib import ExitStack 802 803 with ExitStack() as stack: 804 @stack.callback 805 def cleanup_resources(): 806 ... 807 result = perform_operation() 808 if result: 809 stack.pop_all() 810 811Due to the way the decorator protocol works, a callback function 812declared this way cannot take any parameters. Instead, any resources to 813be released must be accessed as closure variables. 814 815 816Using a context manager as a function decorator 817^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 818 819:class:`ContextDecorator` makes it possible to use a context manager in 820both an ordinary ``with`` statement and also as a function decorator. 821 822For example, it is sometimes useful to wrap functions or groups of statements 823with a logger that can track the time of entry and time of exit. Rather than 824writing both a function decorator and a context manager for the task, 825inheriting from :class:`ContextDecorator` provides both capabilities in a 826single definition:: 827 828 from contextlib import ContextDecorator 829 import logging 830 831 logging.basicConfig(level=logging.INFO) 832 833 class track_entry_and_exit(ContextDecorator): 834 def __init__(self, name): 835 self.name = name 836 837 def __enter__(self): 838 logging.info('Entering: %s', self.name) 839 840 def __exit__(self, exc_type, exc, exc_tb): 841 logging.info('Exiting: %s', self.name) 842 843Instances of this class can be used as both a context manager:: 844 845 with track_entry_and_exit('widget loader'): 846 print('Some time consuming activity goes here') 847 load_widget() 848 849And also as a function decorator:: 850 851 @track_entry_and_exit('widget loader') 852 def activity(): 853 print('Some time consuming activity goes here') 854 load_widget() 855 856Note that there is one additional limitation when using context managers 857as function decorators: there's no way to access the return value of 858:meth:`__enter__`. If that value is needed, then it is still necessary to use 859an explicit ``with`` statement. 860 861.. seealso:: 862 863 :pep:`343` - The "with" statement 864 The specification, background, and examples for the Python :keyword:`with` 865 statement. 866 867.. _single-use-reusable-and-reentrant-cms: 868 869Single use, reusable and reentrant context managers 870--------------------------------------------------- 871 872Most context managers are written in a way that means they can only be 873used effectively in a :keyword:`with` statement once. These single use 874context managers must be created afresh each time they're used - 875attempting to use them a second time will trigger an exception or 876otherwise not work correctly. 877 878This common limitation means that it is generally advisable to create 879context managers directly in the header of the :keyword:`with` statement 880where they are used (as shown in all of the usage examples above). 881 882Files are an example of effectively single use context managers, since 883the first :keyword:`with` statement will close the file, preventing any 884further IO operations using that file object. 885 886Context managers created using :func:`contextmanager` are also single use 887context managers, and will complain about the underlying generator failing 888to yield if an attempt is made to use them a second time:: 889 890 >>> from contextlib import contextmanager 891 >>> @contextmanager 892 ... def singleuse(): 893 ... print("Before") 894 ... yield 895 ... print("After") 896 ... 897 >>> cm = singleuse() 898 >>> with cm: 899 ... pass 900 ... 901 Before 902 After 903 >>> with cm: 904 ... pass 905 ... 906 Traceback (most recent call last): 907 ... 908 RuntimeError: generator didn't yield 909 910 911.. _reentrant-cms: 912 913Reentrant context managers 914^^^^^^^^^^^^^^^^^^^^^^^^^^ 915 916More sophisticated context managers may be "reentrant". These context 917managers can not only be used in multiple :keyword:`with` statements, 918but may also be used *inside* a :keyword:`!with` statement that is already 919using the same context manager. 920 921:class:`threading.RLock` is an example of a reentrant context manager, as are 922:func:`suppress`, :func:`redirect_stdout`, and :func:`chdir`. Here's a very 923simple example of reentrant use:: 924 925 >>> from contextlib import redirect_stdout 926 >>> from io import StringIO 927 >>> stream = StringIO() 928 >>> write_to_stream = redirect_stdout(stream) 929 >>> with write_to_stream: 930 ... print("This is written to the stream rather than stdout") 931 ... with write_to_stream: 932 ... print("This is also written to the stream") 933 ... 934 >>> print("This is written directly to stdout") 935 This is written directly to stdout 936 >>> print(stream.getvalue()) 937 This is written to the stream rather than stdout 938 This is also written to the stream 939 940Real world examples of reentrancy are more likely to involve multiple 941functions calling each other and hence be far more complicated than this 942example. 943 944Note also that being reentrant is *not* the same thing as being thread safe. 945:func:`redirect_stdout`, for example, is definitely not thread safe, as it 946makes a global modification to the system state by binding :data:`sys.stdout` 947to a different stream. 948 949 950.. _reusable-cms: 951 952Reusable context managers 953^^^^^^^^^^^^^^^^^^^^^^^^^ 954 955Distinct from both single use and reentrant context managers are "reusable" 956context managers (or, to be completely explicit, "reusable, but not 957reentrant" context managers, since reentrant context managers are also 958reusable). These context managers support being used multiple times, but 959will fail (or otherwise not work correctly) if the specific context manager 960instance has already been used in a containing with statement. 961 962:class:`threading.Lock` is an example of a reusable, but not reentrant, 963context manager (for a reentrant lock, it is necessary to use 964:class:`threading.RLock` instead). 965 966Another example of a reusable, but not reentrant, context manager is 967:class:`ExitStack`, as it invokes *all* currently registered callbacks 968when leaving any with statement, regardless of where those callbacks 969were added:: 970 971 >>> from contextlib import ExitStack 972 >>> stack = ExitStack() 973 >>> with stack: 974 ... stack.callback(print, "Callback: from first context") 975 ... print("Leaving first context") 976 ... 977 Leaving first context 978 Callback: from first context 979 >>> with stack: 980 ... stack.callback(print, "Callback: from second context") 981 ... print("Leaving second context") 982 ... 983 Leaving second context 984 Callback: from second context 985 >>> with stack: 986 ... stack.callback(print, "Callback: from outer context") 987 ... with stack: 988 ... stack.callback(print, "Callback: from inner context") 989 ... print("Leaving inner context") 990 ... print("Leaving outer context") 991 ... 992 Leaving inner context 993 Callback: from inner context 994 Callback: from outer context 995 Leaving outer context 996 997As the output from the example shows, reusing a single stack object across 998multiple with statements works correctly, but attempting to nest them 999will cause the stack to be cleared at the end of the innermost with 1000statement, which is unlikely to be desirable behaviour. 1001 1002Using separate :class:`ExitStack` instances instead of reusing a single 1003instance avoids that problem:: 1004 1005 >>> from contextlib import ExitStack 1006 >>> with ExitStack() as outer_stack: 1007 ... outer_stack.callback(print, "Callback: from outer context") 1008 ... with ExitStack() as inner_stack: 1009 ... inner_stack.callback(print, "Callback: from inner context") 1010 ... print("Leaving inner context") 1011 ... print("Leaving outer context") 1012 ... 1013 Leaving inner context 1014 Callback: from inner context 1015 Leaving outer context 1016 Callback: from outer context 1017