Skip to content
Merged
Changes from 1 commit
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
42 changes: 42 additions & 0 deletions Lib/pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
import codeop
import pprint
import signal
import asyncio
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 614 has deferred import of asyncio.base_futures, so we could consider adding a lazy import of asyncio at line 606 to improve import time?

#109653
#118761

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

asyncio will be used as long as pdb is used. pdb is not an module that is often imported explicitly or implicitly, I don't think import time of pdb is specifically critical.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. I didn't realize that at the time

import inspect
import textwrap
import tokenize
Expand Down Expand Up @@ -361,6 +362,9 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None,
self._chained_exceptions = tuple()
self._chained_exception_index = 0

self._running_loop = None
self._current_task = None

def set_trace(self, frame=None):
Pdb._last_pdb_instance = self
if frame is None:
Expand Down Expand Up @@ -407,6 +411,8 @@ def setup(self, f, tb):
self.curframe_locals = self.curframe.f_locals
self.set_convenience_variable(self.curframe, '_frame', self.curframe)

self.set_convenience_variable(self.curframe, '_asynctask', self._current_task)

if self._chained_exceptions:
self.set_convenience_variable(
self.curframe,
Expand Down Expand Up @@ -596,6 +602,38 @@ def _hold_exceptions(self, exceptions):
self._chained_exceptions = tuple()
self._chained_exception_index = 0

def _get_asyncio_loop_and_task(self):
try:
loop = asyncio.get_event_loop()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can replace this with direct call to current_task and if it exists get loop from it, using get_event_loop can have unwanted consequences

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I will change this.

task = asyncio.current_task(loop)
except RuntimeError:
loop = task = None
return loop, task

def _asyncio_task_repr(self, task):
import asyncio.base_futures

if task.cancelling() and not task.done():
status = 'cancelling'
else:
info = asyncio.base_futures._future_repr_info(task)
status = info[0]

coro = task._coro

if coro is not None:
if hasattr(coro, '__qualname__') and coro.__qualname__:
coro_name = coro.__qualname__
elif hasattr(coro, '__name__') and coro.__name__:
coro_name = coro.__name__
else:
# Stop masking Cython bugs, expose them in a friendly way.
coro_name = f'<{type(coro).__name__} without __name__>'
else:
coro_name = 'unknown'

return f"{task.get_name()}: <{coro_name} {status}>"

def interaction(self, frame, tb_or_exc):
# Restore the previous signal handler at the Pdb prompt.
if Pdb._previous_sigint_handler:
Expand All @@ -606,6 +644,8 @@ def interaction(self, frame, tb_or_exc):
else:
Pdb._previous_sigint_handler = None

self._running_loop, self._current_task = self._get_asyncio_loop_and_task()

_chained_exceptions, tb = self._get_tb_and_exceptions(tb_or_exc)
if isinstance(tb_or_exc, BaseException):
assert tb is not None, "main exception must have a traceback"
Expand Down Expand Up @@ -995,6 +1035,8 @@ def completedefault(self, text, line, begidx, endidx):
# Pdb meta commands, only intended to be used internally by pdb

def _pdbcmd_print_frame_status(self, arg):
if self._current_task:
self.message(self._asyncio_task_repr(self._current_task))
self.print_stack_trace(0)
self._show_display()

Expand Down
Loading