diff options
author | Yury Selivanov <yury@magic.io> | 2016-10-28 16:52:37 (GMT) |
---|---|---|
committer | Yury Selivanov <yury@magic.io> | 2016-10-28 16:52:37 (GMT) |
commit | a0c1ba608eb89b4e10155f7652c50a3ac0b709af (patch) | |
tree | 90e811ae976793876c5c04de7d91cbb7f1518fd9 /Lib/asyncio/base_tasks.py | |
parent | bbcb79920b0e220c2e1b0e77db5aca2f3a2a52d4 (diff) | |
download | cpython-a0c1ba608eb89b4e10155f7652c50a3ac0b709af.zip cpython-a0c1ba608eb89b4e10155f7652c50a3ac0b709af.tar.gz cpython-a0c1ba608eb89b4e10155f7652c50a3ac0b709af.tar.bz2 |
Issue #28544: Implement asyncio.Task in C.
This implementation provides additional 10-20% speed boost for
asyncio programs.
The patch also fixes _asynciomodule.c to use Arguments Clinic, and
makes '_schedule_callbacks' an overridable method (as it was in 3.5).
Diffstat (limited to 'Lib/asyncio/base_tasks.py')
-rw-r--r-- | Lib/asyncio/base_tasks.py | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/Lib/asyncio/base_tasks.py b/Lib/asyncio/base_tasks.py new file mode 100644 index 0000000..5f34434 --- /dev/null +++ b/Lib/asyncio/base_tasks.py @@ -0,0 +1,76 @@ +import linecache +import traceback + +from . import base_futures +from . import coroutines + + +def _task_repr_info(task): + info = base_futures._future_repr_info(task) + + if task._must_cancel: + # replace status + info[0] = 'cancelling' + + coro = coroutines._format_coroutine(task._coro) + info.insert(1, 'coro=<%s>' % coro) + + if task._fut_waiter is not None: + info.insert(2, 'wait_for=%r' % task._fut_waiter) + return info + + +def _task_get_stack(task, limit): + frames = [] + try: + # 'async def' coroutines + f = task._coro.cr_frame + except AttributeError: + f = task._coro.gi_frame + if f is not None: + while f is not None: + if limit is not None: + if limit <= 0: + break + limit -= 1 + frames.append(f) + f = f.f_back + frames.reverse() + elif task._exception is not None: + tb = task._exception.__traceback__ + while tb is not None: + if limit is not None: + if limit <= 0: + break + limit -= 1 + frames.append(tb.tb_frame) + tb = tb.tb_next + return frames + + +def _task_print_stack(task, limit, file): + extracted_list = [] + checked = set() + for f in task.get_stack(limit=limit): + lineno = f.f_lineno + co = f.f_code + filename = co.co_filename + name = co.co_name + if filename not in checked: + checked.add(filename) + linecache.checkcache(filename) + line = linecache.getline(filename, lineno, f.f_globals) + extracted_list.append((filename, lineno, name, line)) + exc = task._exception + if not extracted_list: + print('No stack for %r' % task, file=file) + elif exc is not None: + print('Traceback for %r (most recent call last):' % task, + file=file) + else: + print('Stack for %r (most recent call last):' % task, + file=file) + traceback.print_list(extracted_list, file=file) + if exc is not None: + for line in traceback.format_exception_only(exc.__class__, exc): + print(line, file=file, end='') |