| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  | import linecache | 
					
						
							| 
									
										
										
										
											2022-03-17 03:03:09 +02:00
										 |  |  | import reprlib | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  | import traceback | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from . import base_futures | 
					
						
							|  |  |  | from . import coroutines | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _task_repr_info(task): | 
					
						
							|  |  |  |     info = base_futures._future_repr_info(task) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-15 15:42:04 -08:00
										 |  |  |     if task.cancelling() and not task.done(): | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |         # replace status | 
					
						
							|  |  |  |         info[0] = 'cancelling' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-09 00:06:47 +03:00
										 |  |  |     info.insert(1, 'name=%r' % task.get_name()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |     if task._fut_waiter is not None: | 
					
						
							| 
									
										
										
										
											2023-05-01 14:10:13 -07:00
										 |  |  |         info.insert(2, f'wait_for={task._fut_waiter!r}') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if task._coro: | 
					
						
							|  |  |  |         coro = coroutines._format_coroutine(task._coro) | 
					
						
							|  |  |  |         info.insert(2, f'coro=<{coro}>') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |     return info | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-17 03:03:09 +02:00
										 |  |  | @reprlib.recursive_repr() | 
					
						
							|  |  |  | def _task_repr(task): | 
					
						
							|  |  |  |     info = ' '.join(_task_repr_info(task)) | 
					
						
							|  |  |  |     return f'<{task.__class__.__name__} {info}>' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  | def _task_get_stack(task, limit): | 
					
						
							|  |  |  |     frames = [] | 
					
						
							| 
									
										
										
										
											2020-03-02 04:45:54 -08:00
										 |  |  |     if hasattr(task._coro, 'cr_frame'): | 
					
						
							|  |  |  |         # case 1: 'async def' coroutines | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |         f = task._coro.cr_frame | 
					
						
							| 
									
										
										
										
											2020-03-02 04:45:54 -08:00
										 |  |  |     elif hasattr(task._coro, 'gi_frame'): | 
					
						
							|  |  |  |         # case 2: legacy coroutines | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |         f = task._coro.gi_frame | 
					
						
							| 
									
										
										
										
											2020-03-02 04:45:54 -08:00
										 |  |  |     elif hasattr(task._coro, 'ag_frame'): | 
					
						
							|  |  |  |         # case 3: async generators | 
					
						
							|  |  |  |         f = task._coro.ag_frame | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         # case 4: unknown objects | 
					
						
							|  |  |  |         f = None | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |     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)) | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |     exc = task._exception | 
					
						
							|  |  |  |     if not extracted_list: | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |         print(f'No stack for {task!r}', file=file) | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |     elif exc is not None: | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |         print(f'Traceback for {task!r} (most recent call last):', file=file) | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |         print(f'Stack for {task!r} (most recent call last):', file=file) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |     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='') |