| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 1 |  | 
 | 2 | :mod:`contextlib` --- Utilities for :keyword:`with`\ -statement contexts. | 
 | 3 | ========================================================================= | 
 | 4 |  | 
 | 5 | .. module:: contextlib | 
 | 6 |    :synopsis: Utilities for with-statement contexts. | 
 | 7 |  | 
 | 8 |  | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 9 | This module provides utilities for common tasks involving the :keyword:`with` | 
 | 10 | statement. For more information see also :ref:`typecontextmanager` and | 
 | 11 | :ref:`context-managers`. | 
 | 12 |  | 
 | 13 | Functions provided: | 
 | 14 |  | 
 | 15 |  | 
 | 16 | .. function:: contextmanager(func) | 
 | 17 |  | 
 | 18 |    This function is a decorator that can be used to define a factory function for | 
 | 19 |    :keyword:`with` statement context managers, without needing to create a class or | 
 | 20 |    separate :meth:`__enter__` and :meth:`__exit__` methods. | 
 | 21 |  | 
 | 22 |    A simple example (this is not recommended as a real way of generating HTML!):: | 
 | 23 |  | 
 | 24 |       from __future__ import with_statement | 
 | 25 |       from contextlib import contextmanager | 
 | 26 |  | 
 | 27 |       @contextmanager | 
 | 28 |       def tag(name): | 
| Georg Brandl | 6911e3c | 2007-09-04 07:15:32 +0000 | [diff] [blame] | 29 |           print("<%s>" % name) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 30 |           yield | 
| Georg Brandl | 6911e3c | 2007-09-04 07:15:32 +0000 | [diff] [blame] | 31 |           print("</%s>" % name) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 32 |  | 
 | 33 |       >>> with tag("h1"): | 
| Georg Brandl | 6911e3c | 2007-09-04 07:15:32 +0000 | [diff] [blame] | 34 |       ...    print("foo") | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 35 |       ... | 
 | 36 |       <h1> | 
 | 37 |       foo | 
 | 38 |       </h1> | 
 | 39 |  | 
| Georg Brandl | 9afde1c | 2007-11-01 20:32:30 +0000 | [diff] [blame] | 40 |    The function being decorated must return a :term:`generator`-iterator when | 
 | 41 |    called. This iterator must yield exactly one value, which will be bound to | 
 | 42 |    the targets in the :keyword:`with` statement's :keyword:`as` clause, if any. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 43 |  | 
 | 44 |    At the point where the generator yields, the block nested in the :keyword:`with` | 
 | 45 |    statement is executed.  The generator is then resumed after the block is exited. | 
 | 46 |    If an unhandled exception occurs in the block, it is reraised inside the | 
 | 47 |    generator at the point where the yield occurred.  Thus, you can use a | 
 | 48 |    :keyword:`try`...\ :keyword:`except`...\ :keyword:`finally` statement to trap | 
 | 49 |    the error (if any), or ensure that some cleanup takes place. If an exception is | 
 | 50 |    trapped merely in order to log it or to perform some action (rather than to | 
 | 51 |    suppress it entirely), the generator must reraise that exception. Otherwise the | 
 | 52 |    generator context manager will indicate to the :keyword:`with` statement that | 
 | 53 |    the exception has been handled, and execution will resume with the statement | 
 | 54 |    immediately following the :keyword:`with` statement. | 
 | 55 |  | 
 | 56 |  | 
 | 57 | .. function:: nested(mgr1[, mgr2[, ...]]) | 
 | 58 |  | 
 | 59 |    Combine multiple context managers into a single nested context manager. | 
 | 60 |  | 
 | 61 |    Code like this:: | 
 | 62 |  | 
 | 63 |       from contextlib import nested | 
 | 64 |  | 
 | 65 |       with nested(A, B, C) as (X, Y, Z): | 
 | 66 |           do_something() | 
 | 67 |  | 
 | 68 |    is equivalent to this:: | 
 | 69 |  | 
 | 70 |       with A as X: | 
 | 71 |           with B as Y: | 
 | 72 |               with C as Z: | 
 | 73 |                   do_something() | 
 | 74 |  | 
 | 75 |    Note that if the :meth:`__exit__` method of one of the nested context managers | 
 | 76 |    indicates an exception should be suppressed, no exception information will be | 
 | 77 |    passed to any remaining outer context managers. Similarly, if the | 
 | 78 |    :meth:`__exit__` method of one of the nested managers raises an exception, any | 
 | 79 |    previous exception state will be lost; the new exception will be passed to the | 
 | 80 |    :meth:`__exit__` methods of any remaining outer context managers. In general, | 
 | 81 |    :meth:`__exit__` methods should avoid raising exceptions, and in particular they | 
 | 82 |    should not re-raise a passed-in exception. | 
 | 83 |  | 
 | 84 |  | 
 | 85 | .. function:: closing(thing) | 
 | 86 |  | 
 | 87 |    Return a context manager that closes *thing* upon completion of the block.  This | 
 | 88 |    is basically equivalent to:: | 
 | 89 |  | 
 | 90 |       from contextlib import contextmanager | 
 | 91 |  | 
 | 92 |       @contextmanager | 
 | 93 |       def closing(thing): | 
 | 94 |           try: | 
 | 95 |               yield thing | 
 | 96 |           finally: | 
 | 97 |               thing.close() | 
 | 98 |  | 
 | 99 |    And lets you write code like this:: | 
 | 100 |  | 
 | 101 |       from __future__ import with_statement | 
 | 102 |       from contextlib import closing | 
 | 103 |       import urllib | 
 | 104 |  | 
 | 105 |       with closing(urllib.urlopen('http://www.python.org')) as page: | 
 | 106 |           for line in page: | 
| Georg Brandl | 6911e3c | 2007-09-04 07:15:32 +0000 | [diff] [blame] | 107 |               print(line) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 108 |  | 
 | 109 |    without needing to explicitly close ``page``.  Even if an error occurs, | 
 | 110 |    ``page.close()`` will be called when the :keyword:`with` block is exited. | 
 | 111 |  | 
 | 112 |  | 
 | 113 | .. seealso:: | 
 | 114 |  | 
 | 115 |    :pep:`0343` - The "with" statement | 
 | 116 |       The specification, background, and examples for the Python :keyword:`with` | 
 | 117 |       statement. | 
 | 118 |  |