xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/asyncio/base_tasks.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Workerimport linecache
2*cda5da8dSAndroid Build Coastguard Workerimport reprlib
3*cda5da8dSAndroid Build Coastguard Workerimport traceback
4*cda5da8dSAndroid Build Coastguard Worker
5*cda5da8dSAndroid Build Coastguard Workerfrom . import base_futures
6*cda5da8dSAndroid Build Coastguard Workerfrom . import coroutines
7*cda5da8dSAndroid Build Coastguard Worker
8*cda5da8dSAndroid Build Coastguard Worker
9*cda5da8dSAndroid Build Coastguard Workerdef _task_repr_info(task):
10*cda5da8dSAndroid Build Coastguard Worker    info = base_futures._future_repr_info(task)
11*cda5da8dSAndroid Build Coastguard Worker
12*cda5da8dSAndroid Build Coastguard Worker    if task.cancelling() and not task.done():
13*cda5da8dSAndroid Build Coastguard Worker        # replace status
14*cda5da8dSAndroid Build Coastguard Worker        info[0] = 'cancelling'
15*cda5da8dSAndroid Build Coastguard Worker
16*cda5da8dSAndroid Build Coastguard Worker    info.insert(1, 'name=%r' % task.get_name())
17*cda5da8dSAndroid Build Coastguard Worker
18*cda5da8dSAndroid Build Coastguard Worker    coro = coroutines._format_coroutine(task._coro)
19*cda5da8dSAndroid Build Coastguard Worker    info.insert(2, f'coro=<{coro}>')
20*cda5da8dSAndroid Build Coastguard Worker
21*cda5da8dSAndroid Build Coastguard Worker    if task._fut_waiter is not None:
22*cda5da8dSAndroid Build Coastguard Worker        info.insert(3, f'wait_for={task._fut_waiter!r}')
23*cda5da8dSAndroid Build Coastguard Worker    return info
24*cda5da8dSAndroid Build Coastguard Worker
25*cda5da8dSAndroid Build Coastguard Worker
26*cda5da8dSAndroid Build Coastguard Worker@reprlib.recursive_repr()
27*cda5da8dSAndroid Build Coastguard Workerdef _task_repr(task):
28*cda5da8dSAndroid Build Coastguard Worker    info = ' '.join(_task_repr_info(task))
29*cda5da8dSAndroid Build Coastguard Worker    return f'<{task.__class__.__name__} {info}>'
30*cda5da8dSAndroid Build Coastguard Worker
31*cda5da8dSAndroid Build Coastguard Worker
32*cda5da8dSAndroid Build Coastguard Workerdef _task_get_stack(task, limit):
33*cda5da8dSAndroid Build Coastguard Worker    frames = []
34*cda5da8dSAndroid Build Coastguard Worker    if hasattr(task._coro, 'cr_frame'):
35*cda5da8dSAndroid Build Coastguard Worker        # case 1: 'async def' coroutines
36*cda5da8dSAndroid Build Coastguard Worker        f = task._coro.cr_frame
37*cda5da8dSAndroid Build Coastguard Worker    elif hasattr(task._coro, 'gi_frame'):
38*cda5da8dSAndroid Build Coastguard Worker        # case 2: legacy coroutines
39*cda5da8dSAndroid Build Coastguard Worker        f = task._coro.gi_frame
40*cda5da8dSAndroid Build Coastguard Worker    elif hasattr(task._coro, 'ag_frame'):
41*cda5da8dSAndroid Build Coastguard Worker        # case 3: async generators
42*cda5da8dSAndroid Build Coastguard Worker        f = task._coro.ag_frame
43*cda5da8dSAndroid Build Coastguard Worker    else:
44*cda5da8dSAndroid Build Coastguard Worker        # case 4: unknown objects
45*cda5da8dSAndroid Build Coastguard Worker        f = None
46*cda5da8dSAndroid Build Coastguard Worker    if f is not None:
47*cda5da8dSAndroid Build Coastguard Worker        while f is not None:
48*cda5da8dSAndroid Build Coastguard Worker            if limit is not None:
49*cda5da8dSAndroid Build Coastguard Worker                if limit <= 0:
50*cda5da8dSAndroid Build Coastguard Worker                    break
51*cda5da8dSAndroid Build Coastguard Worker                limit -= 1
52*cda5da8dSAndroid Build Coastguard Worker            frames.append(f)
53*cda5da8dSAndroid Build Coastguard Worker            f = f.f_back
54*cda5da8dSAndroid Build Coastguard Worker        frames.reverse()
55*cda5da8dSAndroid Build Coastguard Worker    elif task._exception is not None:
56*cda5da8dSAndroid Build Coastguard Worker        tb = task._exception.__traceback__
57*cda5da8dSAndroid Build Coastguard Worker        while tb is not None:
58*cda5da8dSAndroid Build Coastguard Worker            if limit is not None:
59*cda5da8dSAndroid Build Coastguard Worker                if limit <= 0:
60*cda5da8dSAndroid Build Coastguard Worker                    break
61*cda5da8dSAndroid Build Coastguard Worker                limit -= 1
62*cda5da8dSAndroid Build Coastguard Worker            frames.append(tb.tb_frame)
63*cda5da8dSAndroid Build Coastguard Worker            tb = tb.tb_next
64*cda5da8dSAndroid Build Coastguard Worker    return frames
65*cda5da8dSAndroid Build Coastguard Worker
66*cda5da8dSAndroid Build Coastguard Worker
67*cda5da8dSAndroid Build Coastguard Workerdef _task_print_stack(task, limit, file):
68*cda5da8dSAndroid Build Coastguard Worker    extracted_list = []
69*cda5da8dSAndroid Build Coastguard Worker    checked = set()
70*cda5da8dSAndroid Build Coastguard Worker    for f in task.get_stack(limit=limit):
71*cda5da8dSAndroid Build Coastguard Worker        lineno = f.f_lineno
72*cda5da8dSAndroid Build Coastguard Worker        co = f.f_code
73*cda5da8dSAndroid Build Coastguard Worker        filename = co.co_filename
74*cda5da8dSAndroid Build Coastguard Worker        name = co.co_name
75*cda5da8dSAndroid Build Coastguard Worker        if filename not in checked:
76*cda5da8dSAndroid Build Coastguard Worker            checked.add(filename)
77*cda5da8dSAndroid Build Coastguard Worker            linecache.checkcache(filename)
78*cda5da8dSAndroid Build Coastguard Worker        line = linecache.getline(filename, lineno, f.f_globals)
79*cda5da8dSAndroid Build Coastguard Worker        extracted_list.append((filename, lineno, name, line))
80*cda5da8dSAndroid Build Coastguard Worker
81*cda5da8dSAndroid Build Coastguard Worker    exc = task._exception
82*cda5da8dSAndroid Build Coastguard Worker    if not extracted_list:
83*cda5da8dSAndroid Build Coastguard Worker        print(f'No stack for {task!r}', file=file)
84*cda5da8dSAndroid Build Coastguard Worker    elif exc is not None:
85*cda5da8dSAndroid Build Coastguard Worker        print(f'Traceback for {task!r} (most recent call last):', file=file)
86*cda5da8dSAndroid Build Coastguard Worker    else:
87*cda5da8dSAndroid Build Coastguard Worker        print(f'Stack for {task!r} (most recent call last):', file=file)
88*cda5da8dSAndroid Build Coastguard Worker
89*cda5da8dSAndroid Build Coastguard Worker    traceback.print_list(extracted_list, file=file)
90*cda5da8dSAndroid Build Coastguard Worker    if exc is not None:
91*cda5da8dSAndroid Build Coastguard Worker        for line in traceback.format_exception_only(exc.__class__, exc):
92*cda5da8dSAndroid Build Coastguard Worker            print(line, file=file, end='')
93