Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Lib/asyncio/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,14 +153,16 @@ def interrupt(self) -> None:
"ps", help="Display a table of all pending tasks in a process"
)
ps.add_argument("pid", type=int, help="Process ID to inspect")
formats = [fmt.value for fmt in asyncio.tools.TaskTableOutputFormat]
ps.add_argument("--format", choices=formats, default="table")
pstree = subparsers.add_parser(
"pstree", help="Display a tree of all pending tasks in a process"
)
pstree.add_argument("pid", type=int, help="Process ID to inspect")
args = parser.parse_args()
match args.command:
case "ps":
asyncio.tools.display_awaited_by_tasks_table(args.pid)
asyncio.tools.display_awaited_by_tasks_table(args.pid, args.format)
sys.exit(0)
case "pstree":
asyncio.tools.display_awaited_by_tasks_tree(args.pid)
Expand Down
30 changes: 28 additions & 2 deletions Lib/asyncio/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from enum import Enum
import sys
from _remote_debugging import RemoteUnwinder
import csv


class NodeType(Enum):
Expand Down Expand Up @@ -204,20 +205,45 @@ def _get_awaited_by_tasks(pid: int) -> list:
sys.exit(1)


def display_awaited_by_tasks_table(pid: int) -> None:
class TaskTableOutputFormat(Enum):
table = "table"
csv = "csv"
bsv = "bsv"


_header = ('tid', 'task id', 'task name', 'coroutine chain', 'awaiter name', 'awaiter id')


def display_awaited_by_tasks_table(pid: int, format_: TaskTableOutputFormat = TaskTableOutputFormat.table) -> None:
"""Build and print a table of all pending tasks under `pid`."""

tasks = _get_awaited_by_tasks(pid)
table = build_task_table(tasks)
if format_ != TaskTableOutputFormat.table:
_display_awaited_by_tasks_csv(table, format_)
return
# Print the table in a simple tabular format
print(
f"{'tid':<10} {'task id':<20} {'task name':<20} {'coroutine chain':<50} {'awaiter name':<20} {'awaiter id':<15}"
f"{_header[0]:<10} {_header[1]:<20} {_header[2]:<20} {_header[3]:<50} {_header[4]:<20} {_header[5]:<15}"
)
print("-" * 135)
for row in table:
print(f"{row[0]:<10} {row[1]:<20} {row[2]:<20} {row[3]:<50} {row[4]:<20} {row[5]:<15}")


def _display_awaited_by_tasks_csv(table, format_: TaskTableOutputFormat) -> None:
match format_:
case TaskTableOutputFormat.csv:
delimiter = ','
case TaskTableOutputFormat.bsv:
delimiter = '🍌'
case _:
raise ValueError(f"Unknown output format: {format_}")
csv_writer = csv.writer(sys.stdout, delimiter=delimiter)
csv_writer.writerow(_header)
csv_writer.writerows(table)


def display_awaited_by_tasks_tree(pid: int) -> None:
"""Build and print a tree of all pending tasks under `pid`."""

Expand Down
Loading