mirror of
https://github.com/jazzband/contextlib2.git
synced 2026-03-17 06:00:23 +00:00
453 lines
14 KiB
Diff
453 lines
14 KiB
Diff
--- /home/ncoghlan/devel/contextlib2/../cpython/Doc/library/contextlib.rst 2024-05-20 12:53:59.936907756 +1000
|
|
+++ /home/ncoghlan/devel/contextlib2/docs/contextlib2.rst 2024-05-23 17:39:52.671083724 +1000
|
|
@@ -1,20 +1,5 @@
|
|
-:mod:`!contextlib` --- Utilities for :keyword:`!with`\ -statement contexts
|
|
-==========================================================================
|
|
-
|
|
-.. module:: contextlib
|
|
- :synopsis: Utilities for with-statement contexts.
|
|
-
|
|
-**Source code:** :source:`Lib/contextlib.py`
|
|
-
|
|
---------------
|
|
-
|
|
-This module provides utilities for common tasks involving the :keyword:`with`
|
|
-statement. For more information see also :ref:`typecontextmanager` and
|
|
-:ref:`context-managers`.
|
|
-
|
|
-
|
|
-Utilities
|
|
----------
|
|
+API Reference
|
|
+-------------
|
|
|
|
Functions and classes provided:
|
|
|
|
@@ -26,8 +11,8 @@
|
|
``self`` while :meth:`object.__exit__` is an abstract method which by default
|
|
returns ``None``. See also the definition of :ref:`typecontextmanager`.
|
|
|
|
- .. versionadded:: 3.6
|
|
-
|
|
+ .. versionadded:: 0.6.0
|
|
+ Part of the standard library in Python 3.6 and later
|
|
|
|
.. class:: AbstractAsyncContextManager
|
|
|
|
@@ -38,8 +23,8 @@
|
|
returns ``None``. See also the definition of
|
|
:ref:`async-context-managers`.
|
|
|
|
- .. versionadded:: 3.7
|
|
-
|
|
+ .. versionadded:: 21.6.0
|
|
+ Part of the standard library in Python 3.7 and later
|
|
|
|
.. decorator:: contextmanager
|
|
|
|
@@ -49,12 +34,12 @@
|
|
|
|
While many objects natively support use in with statements, sometimes a
|
|
resource needs to be managed that isn't a context manager in its own right,
|
|
- and doesn't implement a ``close()`` method for use with ``contextlib.closing``
|
|
+ and doesn't implement a ``close()`` method for use with ``contextlib2.closing``
|
|
|
|
An abstract example would be the following to ensure correct resource
|
|
management::
|
|
|
|
- from contextlib import contextmanager
|
|
+ from contextlib2 import contextmanager
|
|
|
|
@contextmanager
|
|
def managed_resource(*args, **kwds):
|
|
@@ -95,13 +80,10 @@
|
|
created by :func:`contextmanager` to meet the requirement that context
|
|
managers support multiple invocations in order to be used as decorators).
|
|
|
|
- .. versionchanged:: 3.2
|
|
- Use of :class:`ContextDecorator`.
|
|
-
|
|
|
|
.. decorator:: asynccontextmanager
|
|
|
|
- Similar to :func:`~contextlib.contextmanager`, but creates an
|
|
+ Similar to :func:`~contextlib2.contextmanager`, but creates an
|
|
:ref:`asynchronous context manager <async-context-managers>`.
|
|
|
|
This function is a :term:`decorator` that can be used to define a factory
|
|
@@ -112,7 +94,7 @@
|
|
|
|
A simple example::
|
|
|
|
- from contextlib import asynccontextmanager
|
|
+ from contextlib2 import asynccontextmanager
|
|
|
|
@asynccontextmanager
|
|
async def get_connection():
|
|
@@ -126,13 +108,16 @@
|
|
async with get_connection() as conn:
|
|
return conn.query('SELECT ...')
|
|
|
|
- .. versionadded:: 3.7
|
|
+ .. versionadded:: 21.6.0
|
|
+ Part of the standard library in Python 3.7 and later, enhanced in
|
|
+ Python 3.10 and later to allow created async context managers to be used
|
|
+ as async function decorators.
|
|
|
|
Context managers defined with :func:`asynccontextmanager` can be used
|
|
either as decorators or with :keyword:`async with` statements::
|
|
|
|
import time
|
|
- from contextlib import asynccontextmanager
|
|
+ from contextlib2 import asynccontextmanager
|
|
|
|
@asynccontextmanager
|
|
async def timeit():
|
|
@@ -151,17 +136,13 @@
|
|
created by :func:`asynccontextmanager` to meet the requirement that context
|
|
managers support multiple invocations in order to be used as decorators.
|
|
|
|
- .. versionchanged:: 3.10
|
|
- Async context managers created with :func:`asynccontextmanager` can
|
|
- be used as decorators.
|
|
-
|
|
|
|
.. function:: closing(thing)
|
|
|
|
Return a context manager that closes *thing* upon completion of the block. This
|
|
is basically equivalent to::
|
|
|
|
- from contextlib import contextmanager
|
|
+ from contextlib2 import contextmanager
|
|
|
|
@contextmanager
|
|
def closing(thing):
|
|
@@ -172,7 +153,7 @@
|
|
|
|
And lets you write code like this::
|
|
|
|
- from contextlib import closing
|
|
+ from contextlib2 import closing
|
|
from urllib.request import urlopen
|
|
|
|
with closing(urlopen('https://www.python.org')) as page:
|
|
@@ -196,7 +177,7 @@
|
|
Return an async context manager that calls the ``aclose()`` method of *thing*
|
|
upon completion of the block. This is basically equivalent to::
|
|
|
|
- from contextlib import asynccontextmanager
|
|
+ from contextlib2 import asynccontextmanager
|
|
|
|
@asynccontextmanager
|
|
async def aclosing(thing):
|
|
@@ -209,7 +190,7 @@
|
|
generators when they happen to exit early by :keyword:`break` or an
|
|
exception. For example::
|
|
|
|
- from contextlib import aclosing
|
|
+ from contextlib2 import aclosing
|
|
|
|
async with aclosing(my_generator()) as values:
|
|
async for value in values:
|
|
@@ -221,7 +202,8 @@
|
|
variables work as expected, and the exit code isn't run after the
|
|
lifetime of some task it depends on).
|
|
|
|
- .. versionadded:: 3.10
|
|
+ .. versionadded:: 21.6.0
|
|
+ Part of the standard library in Python 3.10 and later
|
|
|
|
|
|
.. _simplifying-support-for-single-optional-context-managers:
|
|
@@ -235,10 +217,10 @@
|
|
def myfunction(arg, ignore_exceptions=False):
|
|
if ignore_exceptions:
|
|
# Use suppress to ignore all exceptions.
|
|
- cm = contextlib.suppress(Exception)
|
|
+ cm = contextlib2.suppress(Exception)
|
|
else:
|
|
# Do not ignore any exceptions, cm has no effect.
|
|
- cm = contextlib.nullcontext()
|
|
+ cm = contextlib2.nullcontext()
|
|
with cm:
|
|
# Do something
|
|
|
|
@@ -269,11 +251,11 @@
|
|
async with cm as session:
|
|
# Send http requests with session
|
|
|
|
- .. versionadded:: 3.7
|
|
-
|
|
- .. versionchanged:: 3.10
|
|
- :term:`asynchronous context manager` support was added.
|
|
+ .. versionadded:: 0.6.0
|
|
+ Part of the standard library in Python 3.7 and later
|
|
|
|
+ .. versionchanged:: 21.6.0
|
|
+ Updated to Python 3.10 version with :term:`asynchronous context manager` support
|
|
|
|
|
|
.. function:: suppress(*exceptions)
|
|
@@ -290,7 +272,7 @@
|
|
|
|
For example::
|
|
|
|
- from contextlib import suppress
|
|
+ from contextlib2 import suppress
|
|
|
|
with suppress(FileNotFoundError):
|
|
os.remove('somefile.tmp')
|
|
@@ -314,13 +296,15 @@
|
|
|
|
If the code within the :keyword:`!with` block raises a
|
|
:exc:`BaseExceptionGroup`, suppressed exceptions are removed from the
|
|
- group. If any exceptions in the group are not suppressed, a group containing them is re-raised.
|
|
+ group. If any exceptions in the group are not suppressed, a group containing
|
|
+ them is re-raised.
|
|
|
|
- .. versionadded:: 3.4
|
|
+ .. versionadded:: 0.5
|
|
+ Part of the standard library in Python 3.4 and later
|
|
|
|
- .. versionchanged:: 3.12
|
|
- ``suppress`` now supports suppressing exceptions raised as
|
|
- part of an :exc:`BaseExceptionGroup`.
|
|
+ .. versionchanged:: 24.6.0
|
|
+ Updated to Python 3.12 version that supports suppressing exceptions raised
|
|
+ as part of a :exc:`BaseExceptionGroup`.
|
|
|
|
.. function:: redirect_stdout(new_target)
|
|
|
|
@@ -359,17 +343,19 @@
|
|
|
|
This context manager is :ref:`reentrant <reentrant-cms>`.
|
|
|
|
- .. versionadded:: 3.4
|
|
+ .. versionadded:: 0.5
|
|
+ Part of the standard library in Python 3.4 and later
|
|
|
|
|
|
.. function:: redirect_stderr(new_target)
|
|
|
|
- Similar to :func:`~contextlib.redirect_stdout` but redirecting
|
|
+ Similar to :func:`~contextlib2.redirect_stdout` but redirecting
|
|
:data:`sys.stderr` to another file or file-like object.
|
|
|
|
This context manager is :ref:`reentrant <reentrant-cms>`.
|
|
|
|
- .. versionadded:: 3.5
|
|
+ .. versionadded:: 0.5
|
|
+ Part of the standard library in Python 3.5 and later
|
|
|
|
|
|
.. function:: chdir(path)
|
|
@@ -386,7 +372,8 @@
|
|
|
|
This context manager is :ref:`reentrant <reentrant-cms>`.
|
|
|
|
- .. versionadded:: 3.11
|
|
+ .. versionadded:: 24.6.0
|
|
+ Part of the standard library in Python 3.11 and later
|
|
|
|
|
|
.. class:: ContextDecorator()
|
|
@@ -402,7 +389,7 @@
|
|
|
|
Example of ``ContextDecorator``::
|
|
|
|
- from contextlib import ContextDecorator
|
|
+ from contextlib2 import ContextDecorator
|
|
|
|
class mycontext(ContextDecorator):
|
|
def __enter__(self):
|
|
@@ -449,7 +436,7 @@
|
|
Existing context managers that already have a base class can be extended by
|
|
using ``ContextDecorator`` as a mixin class::
|
|
|
|
- from contextlib import ContextDecorator
|
|
+ from contextlib2 import ContextDecorator
|
|
|
|
class mycontext(ContextBaseClass, ContextDecorator):
|
|
def __enter__(self):
|
|
@@ -464,8 +451,6 @@
|
|
statements. If this is not the case, then the original construct with the
|
|
explicit :keyword:`!with` statement inside the function should be used.
|
|
|
|
- .. versionadded:: 3.2
|
|
-
|
|
|
|
.. class:: AsyncContextDecorator
|
|
|
|
@@ -474,7 +459,7 @@
|
|
Example of ``AsyncContextDecorator``::
|
|
|
|
from asyncio import run
|
|
- from contextlib import AsyncContextDecorator
|
|
+ from contextlib2 import AsyncContextDecorator
|
|
|
|
class mycontext(AsyncContextDecorator):
|
|
async def __aenter__(self):
|
|
@@ -505,7 +490,8 @@
|
|
The bit in the middle
|
|
Finishing
|
|
|
|
- .. versionadded:: 3.10
|
|
+ .. versionadded:: 21.6.0
|
|
+ Part of the standard library in Python 3.10 and later
|
|
|
|
|
|
.. class:: ExitStack()
|
|
@@ -547,7 +533,8 @@
|
|
foundation for higher level context managers that manipulate the exit
|
|
stack in application specific ways.
|
|
|
|
- .. versionadded:: 3.3
|
|
+ .. versionadded:: 0.4
|
|
+ Part of the standard library in Python 3.3 and later
|
|
|
|
.. method:: enter_context(cm)
|
|
|
|
@@ -558,9 +545,10 @@
|
|
These context managers may suppress exceptions just as they normally
|
|
would if used directly as part of a :keyword:`with` statement.
|
|
|
|
- .. versionchanged:: 3.11
|
|
- Raises :exc:`TypeError` instead of :exc:`AttributeError` if *cm*
|
|
- is not a context manager.
|
|
+ .. versionchanged:: 24.6.0
|
|
+ When running on Python 3.11 or later, raises :exc:`TypeError` instead
|
|
+ of :exc:`AttributeError` if *cm* is not a context manager. This aligns
|
|
+ with the behaviour of :keyword:`with` statements in Python 3.11+.
|
|
|
|
.. method:: push(exit)
|
|
|
|
@@ -627,14 +615,16 @@
|
|
The :meth:`~ExitStack.close` method is not implemented; :meth:`aclose` must be used
|
|
instead.
|
|
|
|
- .. coroutinemethod:: enter_async_context(cm)
|
|
+ .. method:: enter_async_context(cm)
|
|
+ :async:
|
|
|
|
Similar to :meth:`ExitStack.enter_context` but expects an asynchronous context
|
|
manager.
|
|
|
|
- .. versionchanged:: 3.11
|
|
- Raises :exc:`TypeError` instead of :exc:`AttributeError` if *cm*
|
|
- is not an asynchronous context manager.
|
|
+ .. versionchanged:: 24.6.0
|
|
+ When running on Python 3.11 or later, raises :exc:`TypeError` instead
|
|
+ of :exc:`AttributeError` if *cm* is not an asynchronous context manager.
|
|
+ This aligns with the behaviour of ``async with`` statements in Python 3.11+.
|
|
|
|
.. method:: push_async_exit(exit)
|
|
|
|
@@ -645,7 +635,8 @@
|
|
|
|
Similar to :meth:`ExitStack.callback` but expects a coroutine function.
|
|
|
|
- .. coroutinemethod:: aclose()
|
|
+ .. method:: aclose()
|
|
+ :async:
|
|
|
|
Similar to :meth:`ExitStack.close` but properly handles awaitables.
|
|
|
|
@@ -658,13 +649,15 @@
|
|
# the async with statement, even if attempts to open a connection
|
|
# later in the list raise an exception.
|
|
|
|
- .. versionadded:: 3.7
|
|
+ .. versionadded:: 21.6.0
|
|
+ Part of the standard library in Python 3.7 and later
|
|
+
|
|
|
|
Examples and Recipes
|
|
--------------------
|
|
|
|
This section describes some examples and recipes for making effective use of
|
|
-the tools provided by :mod:`contextlib`.
|
|
+the tools provided by :mod:`contextlib2`.
|
|
|
|
|
|
Supporting a variable number of context managers
|
|
@@ -728,7 +721,7 @@
|
|
acquisition and release functions, along with an optional validation function,
|
|
and maps them to the context management protocol::
|
|
|
|
- from contextlib import contextmanager, AbstractContextManager, ExitStack
|
|
+ from contextlib2 import contextmanager, AbstractContextManager, ExitStack
|
|
|
|
class ResourceManager(AbstractContextManager):
|
|
|
|
@@ -788,7 +781,7 @@
|
|
execution at the end of a ``with`` statement, and then later decide to skip
|
|
executing that callback::
|
|
|
|
- from contextlib import ExitStack
|
|
+ from contextlib2 import ExitStack
|
|
|
|
with ExitStack() as stack:
|
|
stack.callback(cleanup_resources)
|
|
@@ -802,7 +795,7 @@
|
|
If a particular application uses this pattern a lot, it can be simplified
|
|
even further by means of a small helper class::
|
|
|
|
- from contextlib import ExitStack
|
|
+ from contextlib2 import ExitStack
|
|
|
|
class Callback(ExitStack):
|
|
def __init__(self, callback, /, *args, **kwds):
|
|
@@ -822,7 +815,7 @@
|
|
:meth:`ExitStack.callback` to declare the resource cleanup in
|
|
advance::
|
|
|
|
- from contextlib import ExitStack
|
|
+ from contextlib2 import ExitStack
|
|
|
|
with ExitStack() as stack:
|
|
@stack.callback
|
|
@@ -849,7 +842,7 @@
|
|
inheriting from :class:`ContextDecorator` provides both capabilities in a
|
|
single definition::
|
|
|
|
- from contextlib import ContextDecorator
|
|
+ from contextlib2 import ContextDecorator
|
|
import logging
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
@@ -911,7 +904,7 @@
|
|
context managers, and will complain about the underlying generator failing
|
|
to yield if an attempt is made to use them a second time::
|
|
|
|
- >>> from contextlib import contextmanager
|
|
+ >>> from contextlib2 import contextmanager
|
|
>>> @contextmanager
|
|
... def singleuse():
|
|
... print("Before")
|
|
@@ -946,7 +939,7 @@
|
|
:func:`suppress`, :func:`redirect_stdout`, and :func:`chdir`. Here's a very
|
|
simple example of reentrant use::
|
|
|
|
- >>> from contextlib import redirect_stdout
|
|
+ >>> from contextlib2 import redirect_stdout
|
|
>>> from io import StringIO
|
|
>>> stream = StringIO()
|
|
>>> write_to_stream = redirect_stdout(stream)
|
|
@@ -992,7 +985,7 @@
|
|
when leaving any with statement, regardless of where those callbacks
|
|
were added::
|
|
|
|
- >>> from contextlib import ExitStack
|
|
+ >>> from contextlib2 import ExitStack
|
|
>>> stack = ExitStack()
|
|
>>> with stack:
|
|
... stack.callback(print, "Callback: from first context")
|
|
@@ -1026,7 +1019,7 @@
|
|
Using separate :class:`ExitStack` instances instead of reusing a single
|
|
instance avoids that problem::
|
|
|
|
- >>> from contextlib import ExitStack
|
|
+ >>> from contextlib2 import ExitStack
|
|
>>> with ExitStack() as outer_stack:
|
|
... outer_stack.callback(print, "Callback: from outer context")
|
|
... with ExitStack() as inner_stack:
|