import cmd, inspect, pprint, sys
from pyrepl.unix_console import UnixConsole
from pyrepl.python_reader import ReaderConsole

def source (obj):
    try:
        try:
            return inspect.getsource(obj)
        except TypeError:
            return inspect.getsource(obj.__class__)
    except (IOError, AttributeError):
        return None

def format (obj):
    if hasattr(obj, '__dict__'):
        items = vars(obj).items()
    else:
        items = [(key, getattr(obj, key)) for key in dir(obj)]
    items.sort()
    lines = ['object: %r ' % obj]
    lines.append('from %s' % inspect.getmodule(obj))
    lines.extend(["  %s=%s" % (k, pprint.pformat(v))
                  for k, v in items])
    return '\n'.join(lines)

def idb ():
    frame = idb.frame
    global source, format_instance, inspect, sys, pprint
    source = source
    format_instance = format_instance
    inspect = inspect
    pformat = pprint.pformat
    pprint = pprint.pprint
    sys = sys
    
    def print_frame(self, index=None, pre=6, post=2):
        if index is None:
            index = self.get_frame_index()
        frame = self.idb.stack[index]
        filename, lineno, f, text, offset = inspect.getframeinfo(frame)
        if filename is None:
            return
        if f != '?':
            in_note = 'in %s()' % f
        else:
            in_note = 'top-level'
        print "\nframe %s: %s, line %s in %s" % (
            index, in_note, lineno, filename)
        source = self.idb.source(frame)
        if text:
            frameline = text[0][:-1]
            sourcelines = source.splitlines()
            if frameline in sourcelines:
                framelineindex = sourcelines.index(frameline)
                if pre is not None and framelineindex > pre:
                    sourcelines = sourcelines[framelineindex - pre:]
                    framelineindex = sourcelines.index(frameline)
                if post is not None:
                    sourcelines = sourcelines[:framelineindex + post + 1]
            else:
                sourcelines = [ line[:-1] for line in text ]
            for line in sourcelines:
                if line == frameline:
                    space = '>:'
                else:
                    space = ' :'
            print space + line
        if self.idb.exception and frame is self.idb.traceback.tb_frame:
            print "*** %s: %r" % (self.idb.exception.__class__.__name__,
                              str(self.idb.exception))
        if ((self.idb.exception and frame is self.idb.traceback.tb_frame) or
            len(pprint.pformat(frame.f_locals)) < 200):
            print "locals: ",
            pprint.pprint(frame.f_locals)
    ReaderConsole(UnixConsole(1, None), locals=locals()).interact()




