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