Home | History | Annotate | Download | only in library
      1 :mod:`contextlib` --- Utilities for :keyword:`with`\ -statement contexts
      2 ========================================================================
      3 
      4 .. module:: contextlib
      5    :synopsis: Utilities for with-statement contexts.
      6 
      7 
      8 .. versionadded:: 2.5
      9 
     10 **Source code:** :source:`Lib/contextlib.py`
     11 
     12 --------------
     13 
     14 This module provides utilities for common tasks involving the :keyword:`with`
     15 statement. For more information see also :ref:`typecontextmanager` and
     16 :ref:`context-managers`.
     17 
     18 Functions provided:
     19 
     20 
     21 .. function:: contextmanager(func)
     22 
     23    This function is a :term:`decorator` that can be used to define a factory
     24    function for :keyword:`with` statement context managers, without needing to
     25    create a class or separate :meth:`__enter__` and :meth:`__exit__` methods.
     26 
     27    A simple example (this is not recommended as a real way of generating HTML!)::
     28 
     29       from contextlib import contextmanager
     30 
     31       @contextmanager
     32       def tag(name):
     33           print "<%s>" % name
     34           yield
     35           print "</%s>" % name
     36 
     37       >>> with tag("h1"):
     38       ...    print "foo"
     39       ...
     40       <h1>
     41       foo
     42       </h1>
     43 
     44    The function being decorated must return a :term:`generator`-iterator when
     45    called. This iterator must yield exactly one value, which will be bound to
     46    the targets in the :keyword:`with` statement's :keyword:`as` clause, if any.
     47 
     48    At the point where the generator yields, the block nested in the :keyword:`with`
     49    statement is executed.  The generator is then resumed after the block is exited.
     50    If an unhandled exception occurs in the block, it is reraised inside the
     51    generator at the point where the yield occurred.  Thus, you can use a
     52    :keyword:`try`...\ :keyword:`except`...\ :keyword:`finally` statement to trap
     53    the error (if any), or ensure that some cleanup takes place. If an exception is
     54    trapped merely in order to log it or to perform some action (rather than to
     55    suppress it entirely), the generator must reraise that exception. Otherwise the
     56    generator context manager will indicate to the :keyword:`with` statement that
     57    the exception has been handled, and execution will resume with the statement
     58    immediately following the :keyword:`with` statement.
     59 
     60 
     61 .. function:: nested(mgr1[, mgr2[, ...]])
     62 
     63    Combine multiple context managers into a single nested context manager.
     64 
     65    This function has been deprecated in favour of the multiple manager form
     66    of the :keyword:`with` statement.
     67 
     68    The one advantage of this function over the multiple manager form of the
     69    :keyword:`with` statement is that argument unpacking allows it to be
     70    used with a variable number of context managers as follows::
     71 
     72       from contextlib import nested
     73 
     74       with nested(*managers):
     75           do_something()
     76 
     77    Note that if the :meth:`__exit__` method of one of the nested context managers
     78    indicates an exception should be suppressed, no exception information will be
     79    passed to any remaining outer context managers. Similarly, if the
     80    :meth:`__exit__` method of one of the nested managers raises an exception, any
     81    previous exception state will be lost; the new exception will be passed to the
     82    :meth:`__exit__` methods of any remaining outer context managers. In general,
     83    :meth:`__exit__` methods should avoid raising exceptions, and in particular they
     84    should not re-raise a passed-in exception.
     85 
     86    This function has two major quirks that have led to it being deprecated. Firstly,
     87    as the context managers are all constructed before the function is invoked, the
     88    :meth:`__new__` and :meth:`__init__` methods of the inner context managers are
     89    not actually covered by the scope of the outer context managers. That means, for
     90    example, that using :func:`nested` to open two files is a programming error as the
     91    first file will not be closed promptly if an exception is thrown when opening
     92    the second file.
     93 
     94    Secondly, if the :meth:`__enter__` method of one of the inner context managers
     95    raises an exception that is caught and suppressed by the :meth:`__exit__` method
     96    of one of the outer context managers, this construct will raise
     97    :exc:`RuntimeError` rather than skipping the body of the :keyword:`with`
     98    statement.
     99 
    100    Developers that need to support nesting of a variable number of context managers
    101    can either use the :mod:`warnings` module to suppress the DeprecationWarning
    102    raised by this function or else use this function as a model for an application
    103    specific implementation.
    104 
    105    .. deprecated:: 2.7
    106       The with-statement now supports this functionality directly (without the
    107       confusing error prone quirks).
    108 
    109 .. function:: closing(thing)
    110 
    111    Return a context manager that closes *thing* upon completion of the block.  This
    112    is basically equivalent to::
    113 
    114       from contextlib import contextmanager
    115 
    116       @contextmanager
    117       def closing(thing):
    118           try:
    119               yield thing
    120           finally:
    121               thing.close()
    122 
    123    And lets you write code like this::
    124 
    125       from contextlib import closing
    126       import urllib
    127 
    128       with closing(urllib.urlopen('http://www.python.org')) as page:
    129           for line in page:
    130               print line
    131 
    132    without needing to explicitly close ``page``.  Even if an error occurs,
    133    ``page.close()`` will be called when the :keyword:`with` block is exited.
    134 
    135 
    136 .. seealso::
    137 
    138    :pep:`343` - The "with" statement
    139       The specification, background, and examples for the Python :keyword:`with`
    140       statement.
    141 
    142