bpo-40816 Add AsyncContextDecorator class (GH-20516)

Co-authored-by: Yury Selivanov <yury@edgedb.com>
diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst
index e42f5a9..ee2becb 100644
--- a/Doc/library/contextlib.rst
+++ b/Doc/library/contextlib.rst
@@ -126,6 +126,31 @@
 
    .. versionadded:: 3.7
 
+   Context managers defined with :func:`asynccontextmanager` can be used
+   either as decorators or with :keyword:`async with` statements::
+
+     import time
+
+     async def timeit():
+         now = time.monotonic()
+         try:
+             yield
+         finally:
+             print(f'it took {time.monotonic() - now}s to run')
+
+      @timeit()
+      async def main():
+          # ... async code ...
+
+   When used as a decorator, a new generator instance is implicitly created on
+   each function call. This allows the otherwise "one-shot" context managers
+   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)
 
@@ -384,6 +409,43 @@
    .. versionadded:: 3.2
 
 
+.. class:: AsyncContextManager
+
+   Similar as ContextManger only for async
+
+   Example of ``ContextDecorator``::
+
+      from asyncio import run
+      from contextlib import AsyncContextDecorator
+
+      class mycontext(AsyncContextDecorator):
+          async def __aenter__(self):
+              print('Starting')
+              return self
+
+          async def __aexit__(self, *exc):
+              print('Finishing')
+              return False
+
+      >>> @mycontext()
+      ... async def function():
+      ...     print('The bit in the middle')
+      ...
+      >>> run(function())
+      Starting
+      The bit in the middle
+      Finishing
+
+      >>> async def function():
+      ...    async with mycontext():
+      ...         print('The bit in the middle')
+      ...
+      >>> run(function())
+      Starting
+      The bit in the middle
+      Finishing
+
+
 .. class:: ExitStack()
 
    A context manager that is designed to make it easy to programmatically