Mercurial > dotfiles
changeset 222:a2ea4a78e02c
Drop pdb++ since it was breaking hg tests.
author | Augie Fackler <durin42@gmail.com> |
---|---|
date | Mon, 06 Sep 2010 14:06:14 -0500 |
parents | b9b118dba61a |
children | 739d96003993 |
files | unixSoft/lib/python/pdb.py unixSoft/lib/python/rlcompleter_ng.py |
diffstat | 2 files changed, 0 insertions(+), 663 deletions(-) [+] |
line wrap: on
line diff
deleted file mode 100644 --- a/unixSoft/lib/python/pdb.py +++ /dev/null @@ -1,413 +0,0 @@ -""" -Pdb++, a fancier version of pdb -=============================== - -This module extends the stdlib pdb in numerous ways, e.g. by providing -real completion of Python values instead of pdb's own commands, or by -adding few convenience commands like ``longlist``, ``interact`` or -``watch``. - -For a full explanation of each command, refer to the docstring or type -help <command> at the prompt. - -Installation ------------- - -This module is meant to replace stdlib's pdb.py from the outsite; -simply put it in a directory in your PYTHONPATH, and you can start -using it immediately. Since it's named pdb.py, every place which -imports pdb will now find the new module. - -Dependencies ------------- - -To work properly, this module needs `rlcompleter_ng`_ to be installed. - -To enable syntax highlighting, you must install `pygments`. - -.. _pygments: http://pygments.org/ -.. _`rlcompleter_ng`: http://codespeak.net/svn/user/antocuni/hack/rlcompleter_ng.py - -Configuration -------------- - -To customize the configuration of Pdb++, you need to put a file named -.pdbrc.py in your home directory. The file must contain a class named -``Config`` inheriting from ``DefaultConfig`` and overridding the -desired values. - -To know which options are available, look at the comment in the -source. - -You can find a sample configuration file, here: -http://codespeak.net/svn/user/antocuni/hack/pdbrc.py -""" - -__version__='0.1' -__author__ ='Antonio Cuni <anto.cuni@gmail.com>' -__url__='http://codespeak.net/svn/user/antocuni/hack/pdb.py' - -import sys -import os.path -import inspect -import code -import types -from rlcompleter_ng import Completer, ConfigurableClass, setcolor, colors - - -def import_from_stdlib(name): - import code # arbitrary module which stays in the same dir as pdb - stdlibdir, _ = os.path.split(code.__file__) - pyfile = os.path.join(stdlibdir, name + '.py') - result = types.ModuleType(name) - mydict = execfile(pyfile, result.__dict__) - return result - -pdb = import_from_stdlib('pdb') - - -class DefaultConfig: - prompt = '(Pdb++) ' - completekey = 'tab' - highlight = True - bg = 'dark' - colorscheme = None - - line_number_color = colors.turquoise - current_line_color = 44 # blue - -def getsourcelines(obj): - try: - return inspect.getsourcelines(obj) - except IOError: - pass - - if isinstance(obj, types.FrameType): - filename = obj.f_code.co_filename - if hasattr(filename, '__source__'): - first = max(1, obj.f_lineno - 5) - lines = [line + '\n' for line in filename.__source__.lines] - return lines, first - raise IOError('could not get source code') - -def setbgcolor(line, color): - # hack hack hack - # add a bgcolor attribute to all escape sequences found - import re - setbg = '\x1b[%dm' % color - regexbg = '\\1;%dm' % color - return setbg + re.sub('(\x1b\\[.*?)m', regexbg, line) + '\x1b[00m' - -CLEARSCREEN = '\033[2J\033[1;1H' - -def lasti2lineno(code, lasti): - import dis - linestarts = list(dis.findlinestarts(code)) - linestarts.reverse() - for i, lineno in linestarts: - if lasti >= i: - return lineno - assert False, 'Invalid instruction number: %s' % lasti - -class Undefined: - def __repr__(self): - return '<undefined>' -undefined = Undefined() - -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.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, orig_traceback=None): - self.setup(frame, traceback, orig_traceback) - self.print_stack_entry(self.stack[self.curindex]) - self.cmdloop() - self.forget() - - def setup(self, frame, tb, orig_tb=None): - pdb.Pdb.setup(self, frame, tb) - tb = orig_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 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) - - def _print_lines(self, lines, lineno, print_markers=True): - exc_lineno = self.tb_lineno.get(self.curframe, None) - lines = [line[:-1] for line in lines] # remove the trailing '\n' - if self.config.highlight: - maxlength = max(map(len, lines)) - lines = [line.ljust(maxlength) for line in lines] - src = self.format_source('\n'.join(lines)) - lines = src.splitlines() - for i, line in enumerate(lines): - marker = '' - if lineno == self.curframe.f_lineno and print_markers: - marker = '->' - elif lineno == exc_lineno and print_markers: - marker = '>>' - lines[i] = self.format_line(lineno, marker, line) - lineno += 1 - print '\n'.join(lines) - - do_ll = do_longlist - - def do_list(self, arg): - from StringIO import StringIO - oldstdout = sys.stdout - sys.stdout = StringIO() - pdb.Pdb.do_list(self, arg) - src = self.format_source(sys.stdout.getvalue()) - sys.stdout = oldstdout - print src, - - do_l = do_list - - def do_interact(self, arg): - """ - interact - - Start an interative interpreter whose global namespace - contains all the names found in the current scope. - """ - ns = self.curframe.f_globals.copy() - ns.update(self.curframe.f_locals) - code.interact("*interactive*", local=ns) - - def do_track(self, arg): - """ - track expression - - Display a graph showing which objects are referred by the - value of the expression. This command requires pypy to be in - the current PYTHONPATH. - """ - try: - from pypy.translator.tool.reftracker import track - except ImportError: - print '** cannot import pypy.translator.tool.reftracker **' - return - val = self._getval(arg) - track(val) - - def _get_watching(self): - return self.watching.setdefault(self.curframe, {}) - - def _getval_or_undefined(self, arg): - try: - return eval(arg, self.curframe.f_globals, - self.curframe.f_locals) - except NameError: - return undefined - - def do_watch(self, arg): - """ - watch expression - - Add expression to the watching list; expressions in this list - are evaluated at each step, and printed every time its value - changes. - - WARNING: since the expressions is evaluated multiple time, pay - attention not to put expressions with side-effects in the - watching list. - """ - try: - value = self._getval_or_undefined(arg) - except: - return - self._get_watching()[arg] = value - - def do_unwatch(self, arg): - """ - unwatch expression - - Remove expression from the watching list. - """ - try: - del self._get_watching()[arg] - except KeyError: - print '** not watching %s **' % arg - - def _print_if_sticky(self): - if self.sticky: - sys.stdout.write(CLEARSCREEN) - frame, lineno = self.stack[self.curindex] - filename = self.canonic(frame.f_code.co_filename) - s = '> %s(%r)' % (filename, lineno) - print s - print - sticky_range = self.sticky_ranges.get(self.curframe, None) - self._printlonglist(sticky_range) - - def do_sticky(self, arg): - """ - sticky [start end] - - Toggle sticky mode. When in sticky mode, it clear the screen - and longlist the current functions, making the source - appearing always in the same position. Useful to follow the - flow control of a function when doing step-by-step execution. - - If ``start`` and ``end`` are given, sticky mode is enabled and - only lines within that range (extremes included) will be - displayed. - """ - if arg: - try: - start, end = map(int, arg.split()) - except ValueError: - print '** Error when parsing argument: %s **' % arg - return - self.sticky = True - self.sticky_ranges[self.curframe] = start, end+1 - else: - self.sticky = not self.sticky - self.sticky_range = None - self._print_if_sticky() - - def preloop(self): - self._print_if_sticky() - watching = self._get_watching() - for expr, oldvalue in watching.iteritems(): - newvalue = self._getval_or_undefined(expr) - # check for identity first; this prevents custom __eq__ to - # be called at every loop, and also prevents instances - # whose fields are changed to be displayed - if newvalue is not oldvalue or newvalue != oldvalue: - watching[expr] = newvalue - print '%s: %r --> %r' % (expr, oldvalue, newvalue) - - def do_source(self, arg): - try: - obj = self._getval(arg) - except: - return - try: - lines, lineno = getsourcelines(obj) - except (IOError, TypeError), e: - print '** Error: %s **' % e - return - self._print_lines(lines, lineno, print_markers=False) - -# Simplified interface - -# copy some functions from pdb.py, but rebind the global dictionary -for name in 'run runeval runctx runcall set_trace pm'.split(): - func = getattr(pdb, name) - newfunc = types.FunctionType(func.func_code, globals(), func.func_name) - globals()[name] = newfunc -del name, func, newfunc - -def post_mortem(t, Pdb=Pdb): - p = Pdb() - p.reset() - orig_tb = t - while t.tb_next is not None: - t = t.tb_next - p.interaction(t.tb_frame, t, orig_tb) - -# pdb++ specific interface - -def xpm(Pdb=Pdb): - """ - To be used inside an except clause, enter a post-mortem pdb - related to the just catched exception. - """ - post_mortem(sys.exc_info()[2], Pdb)
deleted file mode 100644 --- a/unixSoft/lib/python/rlcompleter_ng.py +++ /dev/null @@ -1,250 +0,0 @@ -""" -rlcompleter_ng -============== - -This module represents an alternative to rlcompleter and rlcompleter2, -for those who don't like their default behaviour. - -There are two main differences between stdlib's rlcompleter and -rlcompleter_ng: - - - when doing something like a.b.c.<TAB>, rlcompleter prepends a.b.c - to all the completions it finds; rlcompleter_ng displays only the - attributes, making the screen less cluttered; - - - you can use the <TAB> key both to indent (when the current line is - blank) or to complete (when it's not blank); - - - more important, rlcompleter_ng prints the various attributes found - in different colors depending on their type. - -Unfortunately, the default version of libreadline don't support -colored completions, so you need to patch it to fully exploid -rlcompleter_ng capabilities. - -You can find the patch here: -http://codespeak.net/svn/user/antocuni/hack/readline-escape.patch - -Alternatively, you can download the Ubuntu Hardy i386 package from here (thanks -to Alexander Schremmer): -http://antosreadlineforhardy.alexanderweb.de/libreadline5_5.2-3build1pypy_i386.deb - -Installation ------------- - -Simply put the file rlcompleter_ng.py in a directory which is in your -PYTHONPATH. - -Configuration -------------- - -Since it requires a patched version of libreadline, coloured -completions are disabled by default. - -To customize the configuration of rlcompleter_ng, you need to put a -file named .rlcompleter_ngrc.py in your home directory. The file must -contain a class named ``Config`` inheriting from ``DefaultConfig`` and -overridding the desired values. - -You can find a sample configuration file, which enables colors, here: -http://codespeak.net/svn/user/antocuni/hack/rlcompleter_ngrc.py - -Usage ------ - -From the interactive prompt, import rlcompleter_ng and call setup(): - ->>> import rlcompleter_ng ->>> rlcompleter_ng.setup() - -Alternatively, you can put these lines in some file that it's -referenced by the PYTHONSTARTUP environment variable, so that -completions is always enabled. -""" - -__version__='0.1' -__author__ ='Antonio Cuni <anto.cuni@gmail.com>' -__url__='http://codespeak.net/svn/user/antocuni/hack/rlcompleter_ng.py' - - -import readline -import rlcompleter -import types -import os.path -from itertools import izip, count - -class colors: - black = '30' - darkred = '31' - darkgreen = '32' - brown = '33' - darkblue = '34' - purple = '35' - teal = '36' - lightgray = '37' - darkgray = '30;01' - red = '31;01' - green = '32;01' - yellow = '33;01' - blue = '34;01' - fuchsia = '35;01' - turquoise = '36;01' - white = '37;01' - - -class DefaultConfig: - - # WARNING: for this option to work properly, you need to patch readline with this: - # http://codespeak.net/svn/user/antocuni/hack/readline-escape.patch - use_colors = False - - color_by_type = { - types.BuiltinMethodType: colors.turquoise, - types.BuiltinMethodType: colors.turquoise, - types.MethodType: colors.turquoise, - type((42).__add__): colors.turquoise, - type(int.__add__): colors.turquoise, - type(str.replace): colors.turquoise, - - types.FunctionType: colors.blue, - types.BuiltinFunctionType: colors.blue, - - types.ClassType: colors.fuchsia, - type: colors.fuchsia, - - types.ModuleType: colors.teal, - types.NoneType: colors.lightgray, - str: colors.green, - unicode: colors.green, - int: colors.yellow, - float: colors.yellow, - complex: colors.yellow, - bool: colors.yellow, - } - - -def setcolor(s, color): - return '\x1b[%sm%s\x1b[00m' % (color, s) - - -class ConfigurableClass: - DefaultConfig = None - config_filename = None - - def get_config(self, Config): - if Config is not None: - return Config() - # try to load config from the ~/filename file - filename = '~/' + self.config_filename - rcfile = os.path.expanduser(filename) - if os.path.exists(rcfile): - mydict = {} - try: - execfile(rcfile, mydict) - return mydict['Config']() - except Exception, e: - print '** error when importing %s: %s **' % (s, e) - return self.DefaultConfig() - - -class Completer(rlcompleter.Completer, ConfigurableClass): - """ - When doing someting like a.b.<TAB>, display only the attributes of - b instead of the full a.b.attr string. - - Optionally, display the various completions in different colors - depending on the type. - """ - - DefaultConfig = DefaultConfig - config_filename = '.rlcompleter_ngrc.py' - - def __init__(self, namespace = None, Config=None): - rlcompleter.Completer.__init__(self, namespace) - self.config = self.get_config(Config) - if self.config.use_colors: - readline.parse_and_bind('set dont-escape-ctrl-chars on') - - def complete(self, text, state): - """ - stolen from: - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496812 - """ - if text == "": - return ['\t',None][state] - else: - return rlcompleter.Completer.complete(self,text,state) - - def global_matches(self, text): - import keyword - names = rlcompleter.Completer.global_matches(self, text) - prefix = commonprefix(names) - if prefix and prefix != text: - return [prefix] - - names.sort() - values = [] - for name in names: - if name in keyword.kwlist: - values.append(None) - else: - values.append(eval(name, self.namespace)) - matches = [self.color_for_obj(i, name, obj) - for i, name, obj - in izip(count(), names, values)] - return matches + [' '] - - def attr_matches(self, text): - import re - m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text) - if not m: - return - expr, attr = m.group(1, 3) - object = eval(expr, self.namespace) - names = [] - values = [] - n = len(attr) - for word in dir(object): - if word[:n] == attr and word != "__builtins__": - names.append(word) - values.append(getattr(object, word)) - - prefix = commonprefix(names) - if prefix and prefix != attr: - return ['%s.%s' % (expr, prefix)] # autocomplete prefix - - matches = [self.color_for_obj(i, name, value) - for i, name, value - in izip(count(), names, values)] - return matches + [' '] - - def color_for_obj(self, i, name, value): - if not self.config.use_colors: - return name - t = type(value) - color = self.config.color_by_type.get(t, '00') - # hack hack hack - # prepend a fake escape sequence, so that readline can sort the matches correctly - return '\x1b[%03d;00m' % i + setcolor(name, color) - - -# stolen from rlcompleter2 -def commonprefix(names, base = ''): - """ return the common prefix of all 'names' starting with 'base' - """ - def commonfunc(s1,s2): - while not s2.startswith(s1): - s1=s1[:-1] - return s1 - - if base: - names = filter(lambda x, base=base: x.startswith(base), names) - if not names: - return '' - return reduce(commonfunc,names) - - -def setup(): - completer = Completer() - readline.parse_and_bind('tab: complete') - readline.set_completer(completer.complete)