From b3a89844888d1b8eacdacc14cc6db1e2125d2d6a Mon Sep 17 00:00:00 2001 From: Michael Foord Date: Wed, 30 Jun 2010 12:17:50 +0000 Subject: Issue 9110. Adding ContextDecorator to contextlib. This enables the creation of APIs that act as decorators as well as context managers. contextlib.contextmanager changed to use ContextDecorator. --- Doc/library/contextlib.rst | 57 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'Doc/library/contextlib.rst') diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index 2ee9e8d989..7a46834a13 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -51,6 +51,11 @@ Functions provided: the exception has been handled, and execution will resume with the statement immediately following the :keyword:`with` statement. + contextmanager uses :class:`ContextDecorator` so the context managers it + creates can be used as decorators as well as in :keyword:`with` statements. + + .. versionchanged:: 3.2 + Use of :class:`ContextDecorator`. .. function:: closing(thing) @@ -79,6 +84,58 @@ Functions provided: ``page.close()`` will be called when the :keyword:`with` block is exited. +.. class:: ContextDecorator() + + A base class that enables a context manager to also be used as a decorator. + + Context managers inheriting from ``ContextDecorator`` have to implement + ``__enter__`` and ``__exit__`` as normal. ``__exit__`` retains its optional + exception handling even when used as a decorator. + + Example:: + + from contextlib import ContextDecorator + + class mycontext(ContextDecorator): + def __enter__(self): + print('Starting') + return self + + def __exit__(self, *exc): + print('Finishing') + return False + + >>> @mycontext() + ... def function(): + ... print('The bit in the middle') + ... + >>> function() + Starting + The bit in the middle + Finishing + + >>> with mycontext(): + ... print('The bit in the middle') + ... + Starting + The bit in the middle + Finishing + + Existing context managers that already have a base class can be extended by + using ``ContextDecorator`` as a mixin class:: + + from contextlib import ContextDecorator + + class mycontext(ContextBaseClass, ContextDecorator): + def __enter__(self): + return self + + def __exit__(self, *exc): + return False + + .. versionadded:: 3.2 + + .. seealso:: :pep:`0343` - The "with" statement -- cgit v1.2.1