Browse Source
bpo-32311: Implement asyncio.create_task() shortcut (#4848)
bpo-32311: Implement asyncio.create_task() shortcut (#4848)
* Implement functionality * Add documentationpull/4766/merge
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 201 additions and 95 deletions
-
25Doc/library/asyncio-task.rst
-
4Lib/asyncio/base_futures.py
-
2Lib/asyncio/constants.py
-
10Lib/asyncio/coroutines.py
-
83Lib/asyncio/events.py
-
75Lib/asyncio/format_helpers.py
-
4Lib/asyncio/futures.py
-
23Lib/asyncio/tasks.py
-
37Lib/test/test_asyncio/test_tasks.py
-
3Lib/test/test_asyncio/utils.py
-
1Misc/NEWS.d/next/Library/2017-12-14-17-28-54.bpo-32311.DL5Ytn.rst
-
29Modules/_asynciomodule.c
@ -0,0 +1,75 @@ |
|||
import functools |
|||
import inspect |
|||
import reprlib |
|||
import traceback |
|||
|
|||
from . import constants |
|||
|
|||
|
|||
def _get_function_source(func): |
|||
func = inspect.unwrap(func) |
|||
if inspect.isfunction(func): |
|||
code = func.__code__ |
|||
return (code.co_filename, code.co_firstlineno) |
|||
if isinstance(func, functools.partial): |
|||
return _get_function_source(func.func) |
|||
if isinstance(func, functools.partialmethod): |
|||
return _get_function_source(func.func) |
|||
return None |
|||
|
|||
|
|||
def _format_callback_source(func, args): |
|||
func_repr = _format_callback(func, args, None) |
|||
source = _get_function_source(func) |
|||
if source: |
|||
func_repr += f' at {source[0]}:{source[1]}' |
|||
return func_repr |
|||
|
|||
|
|||
def _format_args_and_kwargs(args, kwargs): |
|||
"""Format function arguments and keyword arguments. |
|||
|
|||
Special case for a single parameter: ('hello',) is formatted as ('hello'). |
|||
""" |
|||
# use reprlib to limit the length of the output |
|||
items = [] |
|||
if args: |
|||
items.extend(reprlib.repr(arg) for arg in args) |
|||
if kwargs: |
|||
items.extend(f'{k}={reprlib.repr(v)}' for k, v in kwargs.items()) |
|||
return '({})'.format(', '.join(items)) |
|||
|
|||
|
|||
def _format_callback(func, args, kwargs, suffix=''): |
|||
if isinstance(func, functools.partial): |
|||
suffix = _format_args_and_kwargs(args, kwargs) + suffix |
|||
return _format_callback(func.func, func.args, func.keywords, suffix) |
|||
|
|||
if hasattr(func, '__qualname__'): |
|||
func_repr = getattr(func, '__qualname__') |
|||
elif hasattr(func, '__name__'): |
|||
func_repr = getattr(func, '__name__') |
|||
else: |
|||
func_repr = repr(func) |
|||
|
|||
func_repr += _format_args_and_kwargs(args, kwargs) |
|||
if suffix: |
|||
func_repr += suffix |
|||
return func_repr |
|||
|
|||
|
|||
def extract_stack(f=None, limit=None): |
|||
"""Replacement for traceback.extract_stack() that only does the |
|||
necessary work for asyncio debug mode. |
|||
""" |
|||
if f is None: |
|||
f = sys._getframe().f_back |
|||
if limit is None: |
|||
# Limit the amount of work to a reasonable amount, as extract_stack() |
|||
# can be called for each coroutine and future in debug mode. |
|||
limit = constants.DEBUG_STACK_DEPTH |
|||
stack = traceback.StackSummary.extract(traceback.walk_stack(f), |
|||
limit=limit, |
|||
lookup_lines=False) |
|||
stack.reverse() |
|||
return stack |
|||
@ -0,0 +1 @@ |
|||
Implement asyncio.create_task(coro) shortcut |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue