debugger.py
117 lines
| 4.4 KiB
| text/x-python
|
PythonLexer
Thomas Kluyver
|
r23318 | import signal | ||
import sys | ||||
Thomas Kluyver
|
r22391 | from IPython.core.debugger import Pdb | ||
from IPython.core.completer import IPCompleter | ||||
from .ptutils import IPythonPTCompleter | ||||
Thomas Kluyver
|
r23371 | from .shortcuts import suspend_to_bg, cursor_in_leading_ws | ||
Thomas Kluyver
|
r22391 | |||
Thomas Kluyver
|
r23371 | from prompt_toolkit.enums import DEFAULT_BUFFER | ||
Jonathan Slenders
|
r24376 | from prompt_toolkit.filters import (Condition, has_focus, has_selection, | ||
vi_insert_mode, emacs_insert_mode) | ||||
from prompt_toolkit.key_binding import KeyBindings | ||||
Thomas Kluyver
|
r23371 | from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline | ||
Jonathan Slenders
|
r24376 | from pygments.token import Token | ||
from prompt_toolkit.shortcuts.prompt import PromptSession | ||||
Thomas Kluyver
|
r22391 | from prompt_toolkit.enums import EditingMode | ||
Jonathan Slenders
|
r24376 | from prompt_toolkit.formatted_text import PygmentsTokens | ||
tillahoffmann
|
r22874 | |||
Thomas Kluyver
|
r22391 | |||
class TerminalPdb(Pdb): | ||||
def __init__(self, *args, **kwargs): | ||||
Pdb.__init__(self, *args, **kwargs) | ||||
self._ptcomp = None | ||||
self.pt_init() | ||||
def pt_init(self): | ||||
Jonathan Slenders
|
r24376 | def get_prompt_tokens(): | ||
Thomas Kluyver
|
r22391 | return [(Token.Prompt, self.prompt)] | ||
if self._ptcomp is None: | ||||
compl = IPCompleter(shell=self.shell, | ||||
namespace={}, | ||||
global_namespace={}, | ||||
parent=self.shell, | ||||
) | ||||
Jonathan Slenders
|
r24376 | self._ptcomp = IPythonPTCompleter(compl) | ||
Thomas Kluyver
|
r22391 | |||
Jonathan Slenders
|
r24376 | kb = KeyBindings() | ||
supports_suspend = Condition(lambda: hasattr(signal, 'SIGTSTP')) | ||||
kb.add('c-z', filter=supports_suspend)(suspend_to_bg) | ||||
Thomas Kluyver
|
r23318 | |||
Thomas Kluyver
|
r23371 | if self.shell.display_completions == 'readlinelike': | ||
Jonathan Slenders
|
r24376 | kb.add('tab', filter=(has_focus(DEFAULT_BUFFER) | ||
& ~has_selection | ||||
& vi_insert_mode | emacs_insert_mode | ||||
& ~cursor_in_leading_ws | ||||
))(display_completions_like_readline) | ||||
self.pt_app = PromptSession( | ||||
message=(lambda: PygmentsTokens(get_prompt_tokens())), | ||||
Thomas Kluyver
|
r22391 | editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()), | ||
Jonathan Slenders
|
r24376 | key_bindings=kb, | ||
Thomas Kluyver
|
r22391 | history=self.shell.debugger_history, | ||
Jonathan Slenders
|
r24376 | completer=self._ptcomp, | ||
Thomas Kluyver
|
r22391 | enable_history_search=True, | ||
mouse_support=self.shell.mouse_support, | ||||
Jonathan Slenders
|
r24376 | complete_style=self.shell.pt_complete_style, | ||
style=self.shell.style, | ||||
inputhook=self.shell.inputhook, | ||||
Thomas Kluyver
|
r22391 | ) | ||
def cmdloop(self, intro=None): | ||||
"""Repeatedly issue a prompt, accept input, parse an initial prefix | ||||
off the received input, and dispatch to action methods, passing them | ||||
the remainder of the line as argument. | ||||
override the same methods from cmd.Cmd to provide prompt toolkit replacement. | ||||
""" | ||||
if not self.use_rawinput: | ||||
raise ValueError('Sorry ipdb does not support use_rawinput=False') | ||||
self.preloop() | ||||
try: | ||||
if intro is not None: | ||||
self.intro = intro | ||||
if self.intro: | ||||
self.stdout.write(str(self.intro)+"\n") | ||||
stop = None | ||||
while not stop: | ||||
if self.cmdqueue: | ||||
line = self.cmdqueue.pop(0) | ||||
else: | ||||
self._ptcomp.ipy_completer.namespace = self.curframe_locals | ||||
self._ptcomp.ipy_completer.global_namespace = self.curframe.f_globals | ||||
try: | ||||
Jonathan Slenders
|
r24376 | line = self.pt_app.prompt() # reset_current_buffer=True) | ||
Thomas Kluyver
|
r22391 | except EOFError: | ||
line = 'EOF' | ||||
line = self.precmd(line) | ||||
stop = self.onecmd(line) | ||||
stop = self.postcmd(stop, line) | ||||
self.postloop() | ||||
except Exception: | ||||
raise | ||||
Matthias Bussonnier
|
r22724 | |||
tillahoffmann
|
r22874 | |||
def set_trace(frame=None): | ||||
""" | ||||
Start debugging from `frame`. | ||||
If frame is not specified, debugging starts from caller's frame. | ||||
""" | ||||
TerminalPdb().set_trace(frame or sys._getframe().f_back) | ||||
Matthias Bussonnier
|
r22724 | |||
mbyt
|
r22858 | |||
if __name__ == '__main__': | ||||
import pdb | ||||
mbyt
|
r22879 | # IPython.core.debugger.Pdb.trace_dispatch shall not catch | ||
mbyt
|
r22901 | # bdb.BdbQuit. When started through __main__ and an exception | ||
mbyt
|
r22902 | # happened after hitting "c", this is needed in order to | ||
mbyt
|
r22879 | # be able to quit the debugging session (see #9950). | ||
old_trace_dispatch = pdb.Pdb.trace_dispatch | ||||
mbyt
|
r22858 | pdb.Pdb = TerminalPdb | ||
mbyt
|
r22879 | pdb.Pdb.trace_dispatch = old_trace_dispatch | ||
mbyt
|
r22858 | pdb.main() | ||