Ejemplo n.º 1
0
 def complete(self, text, state):
     if state == 0:
         mydict = self.curframe.f_globals.copy()
         mydict.update(self.curframe.f_locals)
         self.mycompleter = Completer(mydict)
     return self.mycompleter.complete(text, state)
Ejemplo n.º 2
0
class Pdb(pdb.Pdb, ConfigurableClass):

    DefaultConfig = DefaultConfig
    config_filename = '.pdbrc.py'

    def __init__(self, *args, **kwds):
        Config = kwds.pop('Config', None)
        pdb.Pdb.__init__(self, *args, **kwds)
        self.config = self.get_config(Config)
        self.config.setup(self)
        self.prompt = self.config.prompt
        self.completekey = self.config.completekey

        self.mycompleter = None
        self.watching = {} # frame --> (name --> last seen value)
        self.sticky = False
        self.sticky_ranges = {} # frame --> (start, end)
        self.tb_lineno = {} # frame --> lineno where the exception raised

    def interaction(self, frame, traceback):
        self.setup(frame, traceback)
        self.print_stack_entry(self.stack[self.curindex])
        self.cmdloop()
        self.forget()

    def setup(self, frame, tb):
        pdb.Pdb.setup(self, frame, tb)
        while tb:
            lineno = lasti2lineno(tb.tb_frame.f_code, tb.tb_lasti)
            self.tb_lineno[tb.tb_frame] = lineno
            tb = tb.tb_next

    def get_stack(self, f, t):
        # Modified from bdb.py to be able to walk the stack beyond generators,
        # which does not work in the normal pdb :-(
        stack, i = pdb.Pdb.get_stack(self, f, t)
        if f is None:
            i = max(0, len(stack) - 1)
        return stack, i

    def forget(self):
        pdb.Pdb.forget(self)
        self.raise_lineno = {}

    def complete(self, text, state):
        if state == 0:
            mydict = self.curframe.f_globals.copy()
            mydict.update(self.curframe.f_locals)
            self.mycompleter = Completer(mydict)
        return self.mycompleter.complete(text, state)

    def _init_pygments(self): 
        try:
            from pygments.lexers import PythonLexer
            from pygments.formatters import TerminalFormatter
        except ImportError:
            return False

        if hasattr(self, '_fmt'):
            return True
        
        self._fmt = TerminalFormatter(bg=self.config.bg,
                                      colorscheme=self.config.colorscheme)
        self._lexer = PythonLexer()
        return True

    def format_source(self, src):
        if not self._init_pygments():
            return src
        from pygments import highlight, lex
        return highlight(src, self._lexer, self._fmt)

    def format_line(self, lineno, marker, line):
        lineno = '%4d' % lineno
        if self.config.highlight:
            lineno = setcolor(lineno, self.config.line_number_color)
        line = '%s  %2s %s' % (lineno, marker, line)
        if self.config.highlight and marker == '->':
            line = setbgcolor(line, self.config.current_line_color)
        return line

    def parseline(self, line):
        cmd, arg, newline = pdb.Pdb.parseline(self, line)
        # don't execute short disruptive commands if a variable with
        # the name exits in the current contex; this prevents pdb to
        # quit if you type e.g. 'r[0]' by mystake.
        if cmd in ['c', 'r', 'q'] and (cmd in self.curframe.f_globals or
                                       cmd in self.curframe.f_locals):
            line = '!' + line
            return pdb.Pdb.parseline(self, line)
        return cmd, arg, newline

    def do_longlist(self, arg):
        """
        {longlist|ll}
        List source code for the current function.
        
        Differently that list, the whole function is displayed; the
        current line is marked with '->'.  In case of post-mortem
        debugging, the line which effectively raised the exception is
        marked with '>>'.

        If the 'highlight' config option is set and pygments is
        installed, the source code is colorized.
        """
        self.lastcmd = 'longlist'
        self._printlonglist()

    def _printlonglist(self, linerange=None):
        try:
            lines, lineno = getsourcelines(self.curframe)
        except IOError, e:
            print '** Error: %s **' % e
            return
        if linerange:
            start, end = linerange
            start = max(start, lineno)
            end = min(end, lineno+len(lines))
            lines = lines[start-lineno:end-lineno]
            lineno = start
        self._print_lines(lines, lineno)