|
1 | 1 | """Tools to analyze tasks running in asyncio programs."""
|
2 | 2 |
|
3 |
| -from collections import defaultdict, namedtuple |
| 3 | +from collections import defaultdict |
| 4 | +import csv |
4 | 5 | from itertools import count
|
5 |
| -from enum import Enum |
| 6 | +from enum import Enum, StrEnum, auto |
6 | 7 | import sys
|
7 | 8 | from _remote_debugging import RemoteUnwinder, FrameInfo
|
8 | 9 |
|
@@ -232,18 +233,51 @@ def _get_awaited_by_tasks(pid: int) -> list:
|
232 | 233 | sys.exit(1)
|
233 | 234 |
|
234 | 235 |
|
235 |
| -def display_awaited_by_tasks_table(pid: int) -> None: |
| 236 | +class TaskTableOutputFormat(StrEnum): |
| 237 | + table = auto() |
| 238 | + csv = auto() |
| 239 | + |
| 240 | + |
| 241 | +def display_awaited_by_tasks_table(pid, *, format=TaskTableOutputFormat.table): |
236 | 242 | """Build and print a table of all pending tasks under `pid`."""
|
237 | 243 |
|
238 | 244 | tasks = _get_awaited_by_tasks(pid)
|
239 | 245 | table = build_task_table(tasks)
|
240 |
| - # Print the table in a simple tabular format |
241 |
| - print( |
242 |
| - f"{'tid':<10} {'task id':<20} {'task name':<20} {'coroutine stack':<50} {'awaiter chain':<50} {'awaiter name':<15} {'awaiter id':<15}" |
243 |
| - ) |
244 |
| - print("-" * 180) |
| 246 | + format = TaskTableOutputFormat(format) |
| 247 | + if format == TaskTableOutputFormat.table: |
| 248 | + _display_awaited_by_tasks_table(table) |
| 249 | + else: |
| 250 | + _display_awaited_by_tasks_csv(table, format=format) |
| 251 | + |
| 252 | + |
| 253 | +_row_header = ('tid', 'task id', 'task name', 'coroutine stack', |
| 254 | + 'awaiter chain', 'awaiter name', 'awaiter id') |
| 255 | + |
| 256 | + |
| 257 | +def _display_awaited_by_tasks_table(table): |
| 258 | + """Print the table in a simple tabular format.""" |
| 259 | + print(_fmt_table_row(*_row_header)) |
| 260 | + print('-' * 180) |
245 | 261 | for row in table:
|
246 |
| - print(f"{row[0]:<10} {row[1]:<20} {row[2]:<20} {row[3]:<50} {row[4]:<50} {row[5]:<15} {row[6]:<15}") |
| 262 | + print(_fmt_table_row(*row)) |
| 263 | + |
| 264 | + |
| 265 | +def _fmt_table_row(tid, task_id, task_name, coro_stack, |
| 266 | + awaiter_chain, awaiter_name, awaiter_id): |
| 267 | + # Format a single row for the table format |
| 268 | + return (f'{tid:<10} {task_id:<20} {task_name:<20} {coro_stack:<50} ' |
| 269 | + f'{awaiter_chain:<50} {awaiter_name:<15} {awaiter_id:<15}') |
| 270 | + |
| 271 | + |
| 272 | +def _display_awaited_by_tasks_csv(table, *, format): |
| 273 | + """Print the table in CSV format""" |
| 274 | + if format == TaskTableOutputFormat.csv: |
| 275 | + delimiter = ',' |
| 276 | + else: |
| 277 | + raise ValueError(f"Unknown output format: {format}") |
| 278 | + csv_writer = csv.writer(sys.stdout, delimiter=delimiter) |
| 279 | + csv_writer.writerow(_row_header) |
| 280 | + csv_writer.writerows(table) |
247 | 281 |
|
248 | 282 |
|
249 | 283 | def display_awaited_by_tasks_tree(pid: int) -> None:
|
|
0 commit comments