• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import linecache
2import traceback
3
4from . import base_futures
5from . import coroutines
6
7
8def _task_repr_info(task):
9    info = base_futures._future_repr_info(task)
10
11    if task._must_cancel:
12        # replace status
13        info[0] = 'cancelling'
14
15    coro = coroutines._format_coroutine(task._coro)
16    info.insert(1, f'coro=<{coro}>')
17
18    if task._fut_waiter is not None:
19        info.insert(2, f'wait_for={task._fut_waiter!r}')
20    return info
21
22
23def _task_get_stack(task, limit):
24    frames = []
25    try:
26        # 'async def' coroutines
27        f = task._coro.cr_frame
28    except AttributeError:
29        f = task._coro.gi_frame
30    if f is not None:
31        while f is not None:
32            if limit is not None:
33                if limit <= 0:
34                    break
35                limit -= 1
36            frames.append(f)
37            f = f.f_back
38        frames.reverse()
39    elif task._exception is not None:
40        tb = task._exception.__traceback__
41        while tb is not None:
42            if limit is not None:
43                if limit <= 0:
44                    break
45                limit -= 1
46            frames.append(tb.tb_frame)
47            tb = tb.tb_next
48    return frames
49
50
51def _task_print_stack(task, limit, file):
52    extracted_list = []
53    checked = set()
54    for f in task.get_stack(limit=limit):
55        lineno = f.f_lineno
56        co = f.f_code
57        filename = co.co_filename
58        name = co.co_name
59        if filename not in checked:
60            checked.add(filename)
61            linecache.checkcache(filename)
62        line = linecache.getline(filename, lineno, f.f_globals)
63        extracted_list.append((filename, lineno, name, line))
64
65    exc = task._exception
66    if not extracted_list:
67        print(f'No stack for {task!r}', file=file)
68    elif exc is not None:
69        print(f'Traceback for {task!r} (most recent call last):', file=file)
70    else:
71        print(f'Stack for {task!r} (most recent call last):', file=file)
72
73    traceback.print_list(extracted_list, file=file)
74    if exc is not None:
75        for line in traceback.format_exception_only(exc.__class__, exc):
76            print(line, file=file, end='')
77