diff --git a/Doc/lib/libstdtypes.tex b/Doc/lib/libstdtypes.tex index ec96ed5e864..0656c35e2d0 100644 --- a/Doc/lib/libstdtypes.tex +++ b/Doc/lib/libstdtypes.tex @@ -1753,6 +1753,102 @@ implemented in C will have to provide a writable \end{memberdesc} +\subsection{Context Types \label{typecontext}} + +\versionadded{2.5} +\index{context protocol} +\index{context management protocol} +\index{protocol!context} +\index{protocol!context management} + +Python's \keyword{with} statement supports the concept of a runtime +context defined by a context object. This is implemented using three +distinct methods; these are used to allow user-defined classes to +define a context. + +The \dfn{context protocol} consists of a single method that needs +to be provided for an object to define a runtime context: + +\begin{methoddesc}[context]{__context__}{} + Return a context manager object. The object is required to support + the context management protocol described below. If an object + supports different kinds of runtime context, additional methods can + be provided to specifically request context managers for those + kinds of context. (An example of an object supporting multiple kinds + of context would be a synchronisation object which supported both + a locked context for normal thread synchronisation and an unlocked + context to temporarily release a held lock while performing a + potentially long running operation) +\end{methoddesc} + +The context manager objects themselves are required to support the +following three methods, which together form the +\dfn{context management protocol}: + +\begin{methoddesc}[context manager]{__context__}{} + Return the context manager object itself. This is required to + allow both contexts and context managers to be used with the + \keyword{with} statement. +\end{methoddesc} + +\begin{methoddesc}[context manager]{__enter__}{} + Set up the runtime context and return either the defining context + object or another object related to the runtime context. The value + returned by this method is bound to the identifier in the + \keyword{as} clause of \keyword{with} statements using this context. + (An example of a context with a context manager that returns the + original context object is file objects, which are returned from + __enter__() to allow \function{open()} to be used directly in a with + statement. An example of a context manager that returns a related + object is \code{decimal.Context} which returns a copy of the original + context to allow changes to be made to the current decimal context + without affecting code outside the \keyword{with} statement). +\end{methoddesc} + +\begin{methoddesc}[context manager]{__exit__}{exc_type, exc_val, exc_tb} + Tear down the runtime context and return a Boolean flag indicating if + an expection that occurred should be suppressed. If an exception + occurred while executing the body of the \keyword{with} statement, the + arguments contain the exception type, value and traceback information. + Otherwise, all three arguments are \var{None}. + Returning a true value from this method will cause the \keyword{with} + statement to suppress the exception and continue execution with the + statement immediately following the \keyword{with} statement. Otherwise + the exception continues propagating after this method has finished + executing. Exceptions that occur during execution of this method will + replace any exception that occurred in the body of the \keyword{with} + statement. + The exception passed in should never be reraised explicitly - instead, + this method should return a false value to indicate that the method + completed successfully and does not want to suppress the raised + exception. This allows context management code (such as + \code{contextlib.nested}) to easily detect whether or not an + \method{__exit__()} method has actually failed. +\end{methoddesc} + +Python defines several context objects to support easy thread +synchronisation, prompt closure of files or other objects, and +thread-safe manipulation of the decimal arithmetic context. The +specific types are not important beyond their implementation of +the context protocol. + +Python's generators and the \code{contextlib.contextmanager} +decorator provide a convenient way to implement the context +and context management protocols. If a context object's +\method{__context__()} method is implemented as a generator decorated +with the \code{contextlib.contextmanager} decorator, it will +automatically return a context manager object supplying the +necessary \method{__context__()}, \method{__enter__()} and +\method{__exit__()} methods. + +Note that there is no specific slot for any of these methods in the +type structure for Python objects in the Python/C API. Extension +types wanting to define these methods must provide them as a normal +Python accessible method. Compared to the overhead of setting up the +runtime context, the overhead of a single class dictionary lookup +is negligible. + + \subsection{Other Built-in Types \label{typesother}} The interpreter supports several other kinds of objects.