diff --git a/IPython/core/debugger.py b/IPython/core/debugger.py index a056dda..e25faca 100644 --- a/IPython/core/debugger.py +++ b/IPython/core/debugger.py @@ -34,15 +34,8 @@ import sys from IPython import get_ipython from IPython.utils import PyColorize, ulinecache from IPython.utils import coloransi, py3compat -from IPython.core.completer import IPCompleter from IPython.core.excolors import exception_colors from IPython.testing.skipdoctest import skip_doctest -from IPython.terminal.ptutils import IPythonPTCompleter - -from prompt_toolkit.token import Token -from prompt_toolkit.shortcuts import create_prompt_application -from prompt_toolkit.interface import CommandLineInterface -from prompt_toolkit.enums import EditingMode prompt = 'ipdb> ' @@ -251,80 +244,6 @@ class Pdb(OldPdb, object): # Set the prompt - the default prompt is '(Pdb)' self.prompt = prompt - self._ptcomp = None - self.pt_init() - - def pt_init(self): - self.use_prompt_toolkit = hasattr(self.shell, 'pt_cli') - - if not self.use_prompt_toolkit: - return - - def get_prompt_tokens(cli): - return [(Token.Prompt, self.prompt)] - - if self._ptcomp is None: - compl = IPCompleter(shell=self.shell, - namespace={}, - global_namespace={}, - use_readline=False, - parent=self.shell, - ) - self._ptcomp = IPythonPTCompleter(compl) - - self._pt_app = create_prompt_application( - editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()), - history=self.shell.debugger_history, - completer= self._ptcomp, - enable_history_search=True, - mouse_support=self.shell.mouse_support, - get_prompt_tokens=get_prompt_tokens - ) - self.pt_cli = CommandLineInterface(self._pt_app, eventloop=self.shell._eventloop) - - - - 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_prompt_toolkit: - return OldPdb.cmdloop(self, intro) - - if not self.use_rawinput: - raise ValueError('Sorry ipdb does not support raw_input=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: - line = self.pt_cli.run(reset_current_buffer=True).text - except EOFError: - line = 'EOF' - line = self.precmd(line) - stop = self.onecmd(line) - stop = self.postcmd(stop, line) - self.postloop() - except Exception: - raise - - def set_colors(self, scheme): """Shorthand access to the color table scheme selector method.""" diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index c6e913a..3bcc3e0 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -42,6 +42,7 @@ from IPython.core.autocall import ExitAutocall from IPython.core.builtin_trap import BuiltinTrap from IPython.core.events import EventManager, available_events from IPython.core.compilerop import CachingCompiler, check_linecache_ipython +from IPython.core.debugger import Pdb from IPython.core.display_trap import DisplayTrap from IPython.core.displayhook import DisplayHook from IPython.core.displaypub import DisplayPublisher @@ -1584,6 +1585,8 @@ class InteractiveShell(SingletonConfigurable): # Things related to exception handling and tracebacks (not debugging) #------------------------------------------------------------------------- + debugger_cls = Pdb + def init_traceback_handlers(self, custom_exceptions): # Syntax error handler. self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor') @@ -1594,7 +1597,8 @@ class InteractiveShell(SingletonConfigurable): self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain', color_scheme='NoColor', tb_offset = 1, - check_cache=check_linecache_ipython) + check_cache=check_linecache_ipython, + debugger_cls=self.debugger_cls) # The instance will store a pointer to the system-wide exception hook, # so that runtime code (such as magics) can access it. This is because diff --git a/IPython/core/ultratb.py b/IPython/core/ultratb.py index 0d8bb98..38ba74e 100644 --- a/IPython/core/ultratb.py +++ b/IPython/core/ultratb.py @@ -809,7 +809,7 @@ class VerboseTB(TBTools): def __init__(self, color_scheme='Linux', call_pdb=False, ostream=None, tb_offset=0, long_header=False, include_vars=True, - check_cache=None): + check_cache=None, debugger_cls = None): """Specify traceback offset, headers and color scheme. Define how many frames to drop from the tracebacks. Calling it with @@ -830,6 +830,8 @@ class VerboseTB(TBTools): check_cache = linecache.checkcache self.check_cache = check_cache + self.debugger_cls = debugger_cls or debugger.Pdb + def format_records(self, records, last_unique, recursion_repeat): """Format the stack frames of the traceback""" frames = [] @@ -1217,7 +1219,7 @@ class VerboseTB(TBTools): if force or self.call_pdb: if self.pdb is None: - self.pdb = debugger.Pdb( + self.pdb = self.debugger_cls( self.color_scheme_table.active_scheme_name) # the system displayhook may have changed, restore the original # for pdb @@ -1278,7 +1280,7 @@ class FormattedTB(VerboseTB, ListTB): def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False, ostream=None, tb_offset=0, long_header=False, include_vars=False, - check_cache=None): + check_cache=None, debugger_cls=None): # NEVER change the order of this list. Put new modes at the end: self.valid_modes = ['Plain', 'Context', 'Verbose'] @@ -1287,7 +1289,7 @@ class FormattedTB(VerboseTB, ListTB): VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb, ostream=ostream, tb_offset=tb_offset, long_header=long_header, include_vars=include_vars, - check_cache=check_cache) + check_cache=check_cache, debugger_cls=debugger_cls) # Different types of tracebacks are joined with different separators to # form a single string. They are taken from this dict diff --git a/IPython/terminal/debugger.py b/IPython/terminal/debugger.py new file mode 100644 index 0000000..315c956 --- /dev/null +++ b/IPython/terminal/debugger.py @@ -0,0 +1,73 @@ +from IPython.core.debugger import Pdb + +from IPython.core.completer import IPCompleter +from .ptutils import IPythonPTCompleter + +from prompt_toolkit.token import Token +from prompt_toolkit.shortcuts import create_prompt_application +from prompt_toolkit.interface import CommandLineInterface +from prompt_toolkit.enums import EditingMode + +class TerminalPdb(Pdb): + def __init__(self, *args, **kwargs): + Pdb.__init__(self, *args, **kwargs) + self._ptcomp = None + self.pt_init() + + def pt_init(self): + def get_prompt_tokens(cli): + return [(Token.Prompt, self.prompt)] + + if self._ptcomp is None: + compl = IPCompleter(shell=self.shell, + namespace={}, + global_namespace={}, + use_readline=False, + parent=self.shell, + ) + self._ptcomp = IPythonPTCompleter(compl) + + self._pt_app = create_prompt_application( + editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()), + history=self.shell.debugger_history, + completer= self._ptcomp, + enable_history_search=True, + mouse_support=self.shell.mouse_support, + get_prompt_tokens=get_prompt_tokens + ) + self.pt_cli = CommandLineInterface(self._pt_app, eventloop=self.shell._eventloop) + + 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: + line = self.pt_cli.run(reset_current_buffer=True).text + except EOFError: + line = 'EOF' + line = self.precmd(line) + stop = self.onecmd(line) + stop = self.postcmd(stop, line) + self.postloop() + except Exception: + raise diff --git a/IPython/terminal/ptshell.py b/IPython/terminal/ptshell.py index a3865df..b229284 100644 --- a/IPython/terminal/ptshell.py +++ b/IPython/terminal/ptshell.py @@ -26,6 +26,7 @@ from prompt_toolkit.styles import PygmentsStyle, DynamicStyle from pygments.styles import get_style_by_name, get_all_styles from pygments.token import Token +from .debugger import TerminalPdb from .pt_inputhooks import get_inputhook_func from .interactiveshell import get_default_editor, TerminalMagics from .ptutils import IPythonPTCompleter, IPythonPTLexer @@ -43,6 +44,7 @@ class TerminalInteractiveShell(InteractiveShell): pt_cli = None debugger_history = None + debugger_cls = TerminalPdb autoedit_syntax = Bool(False, help="auto editing of files with syntax errors.",