Source code for vsi.tools.vdb_ipdb

import IPython.core.debugger
import IPython.terminal.debugger
from functools import partial
import sys

import vsi.tools.vdb as vdb
from vsi.tools.vdb import set_attach, attach, pipe_server

[docs]class Vdb(IPython.terminal.debugger.TerminalPdb): ''' VSI Debugger, based off of IPython's 5.x or newer debugger ''' def __init__(self, skipInput=True, *args, **kwargs): self.__ignore_next_user_return = skipInput IPython.terminal.debugger.TerminalPdb.__init__(self, *args, **kwargs) self.prompt = 'vdb> ' #Modifications to skip initial user input
[docs] def user_return(self, frame, return_value): if self.__ignore_next_user_return: self.__ignore_next_user_return = False self.onecmd('c')#continue, effectively ignoring the first input else: IPython.terminal.debugger.TerminalPdb.interaction(self, frame, None)
#everything needed from set_trace, minus sys.settrace def _pre_settrace(self, frame=None): if frame is None: frame = sys._getframe().f_back f2 = frame self.reset() while f2: f2.f_trace = self.trace_dispatch self.botframe = f2 f2 = f2.f_back self.setup(frame, None) #Manually call sys.settrace to use out mods def _settrace(self): sys.settrace(self.trace_dispatch)
try: delattr(IPython.core.debugger.OldPdb, 'do_r') delattr(IPython.core.debugger.OldPdb, 'do_q') delattr(IPython.core.debugger.Pdb, 'do_q') #New quit in newer ipython except: pass #I HATE these! Too powerful and too easy to do by accident
[docs]class VdbPostMortemHook(vdb.PostMortemHook):
[docs] @staticmethod def set_post_mortem(interactive=False): sys.excepthook = partial(vdb.dbstop_exception_hook, post_mortem=post_mortem, interactive=interactive)
[docs]def dbclear_if_error(): VdbPostMortemHook.dbclear_if_error()
[docs]def dbstop_if_error(interactive=False): ''' Run this to auto start the vdb debugger on an exception. Arguments --------- interactive : :class:`bool`, optional Default False. dbstop if console is interactive. You are still able to print and run commands in the debugger, just listing code declared interactively will not work. Does not appear to work in ipython. Use %debug instead. This will not help in the multithread case in ipython... ipython does too much, just don't try that. Unless someone adds a way to override ipython's override. ''' VdbPostMortemHook.dbstop_if_error(interactive=interactive)
[docs]class DbStopIfError(vdb.DbStopIfErrorGeneric): ''' With statement for local dbstop situations ''' #This is all needed JUST for threading. It uses syshook instead of __exit__
[docs] def get_post_mortem_class(self): ''' Get post mortem class for Vdb ''' return VdbPostMortemHook
[docs] def get_post_mortem(self): return post_mortem
[docs]def runpdb(lines, debugger=None): ''' Executes a list of vdb command Arguments --------- lines : :obj:`str` or :obj:`list` or :obj:`tuple` Collection of strings to be executed as if you were already in the debugger. Useful for setting breakpoints programatically. Return ------ object Returns the debugger object, since this can only be executed on the debugger object, you can optionally pass it in as the second argument if you want to call runpdb multiple times. If you do not, a new debugger object is created, and all the "memory" of the last debugger is lost, such as breakpoints, etc... ''' try: lines + ' ' #Is str like lines = [lines] #make it a list except: pass if not debugger: debugger = Vdb() debugger._pre_settrace(frame=sys._getframe().f_back) for line in lines: debugger.onecmd(line) debugger._settrace() return debugger
[docs]def set_trace(frame=None, depth=None): ''' Helper function, like pdb.set_trace ''' frame = vdb.find_frame(frame, depth if depth is not None else 2 if frame is None else 0) Vdb().set_trace(frame)
[docs]def post_mortem(tb=None): ''' Helper function, like pdb.post_mortem ''' # handling the default if tb is None: # sys.exc_info() returns (type, value, traceback) if an exception is # being handled, otherwise it returns None tb = sys.exc_info()[2] if tb is None: raise ValueError("A valid traceback must be passed if no " "exception is being handled") debugger=Vdb() debugger.reset() debugger.interaction(None, tb)