diff options
author | Tim Peters <tim.peters@gmail.com> | 2004-07-18 06:16:08 +0000 |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2004-07-18 06:16:08 +0000 |
commit | 182b5aca27d376b08a2904bed42b751496f932f3 (patch) | |
tree | df13115820dbc879c0fe2eae488c9f8c0215a7da /Mac/Tools/IDE/PyDebugger.py | |
parent | e6ddc8b20b493fef2e7cffb2e1351fe1d238857e (diff) | |
download | cpython-git-182b5aca27d376b08a2904bed42b751496f932f3.tar.gz |
Whitespace normalization, via reindent.py.
Diffstat (limited to 'Mac/Tools/IDE/PyDebugger.py')
-rw-r--r-- | Mac/Tools/IDE/PyDebugger.py | 1692 |
1 files changed, 846 insertions, 846 deletions
diff --git a/Mac/Tools/IDE/PyDebugger.py b/Mac/Tools/IDE/PyDebugger.py index 51ba753b46..5ee92d5020 100644 --- a/Mac/Tools/IDE/PyDebugger.py +++ b/Mac/Tools/IDE/PyDebugger.py @@ -13,882 +13,882 @@ import MacOS _filenames = {} SIMPLE_TYPES = ( - types.NoneType, - types.IntType, - types.LongType, - types.FloatType, - types.ComplexType, - types.StringType + types.NoneType, + types.IntType, + types.LongType, + types.FloatType, + types.ComplexType, + types.StringType ) class Debugger(bdb.Bdb): - - def __init__(self, title = 'Debugger'): - bdb.Bdb.__init__(self) - self.closed = 1 - self.title = title - self.breaksviewer = None - self.reset() - self.tracing = 0 - self.tracingmonitortime = Evt.TickCount() - self.editors = {} - - prefs = W.getapplication().getprefs() - if prefs.debugger: - for file, breaks in prefs.debugger.breaks.items(): - for b in breaks: - self.set_break(file, b) - self.bounds, self.horpanes, self.verpanes = prefs.debugger.windowsettings - self.tracemagic = prefs.debugger.tracemagic - else: - self.breaks = {} - self.horpanes = (0.4, 0.6) - self.verpanes = (0.3, 0.35, 0.35) - self.bounds = (600, 400) - self.tracemagic = 0 - self.laststacksel = None - - def canonic(self, filename): - # override: the provided canonic() method breaks our - # file-less Untitled windows - return filename - - def reset(self): - self.currentframe = None - self.file = None - self.laststack = None - self.reason = 'Not running' - self.continuewithoutdebugger = 0 - bdb.Bdb.reset(self) - self.forget() - - def start(self, bottomframe = None, running = 0): - W.getapplication().DebuggerQuit = bdb.BdbQuit - from Carbon import Menu - Menu.HiliteMenu(0) - if self.closed: - self.setupwidgets(self.title) - self.closed = 0 - if not self.w.parent.debugger_quitting: - self.w.select() - raise W.AlertError, 'There is another debugger session busy.' - self.reset() - self.botframe = bottomframe - if running: - self.set_continue() - self.reason = 'Running\xc9' - self.setstate('running') - else: - self.set_step() - self.reason = 'stopped' - self.setstate('stopped') - sys.settrace(self.trace_dispatch) - - def stop(self): - self.set_quit() - if self.w.parent: - self.exit_mainloop() - self.resetwidgets() - - def set_continue_without_debugger(self): - sys.settrace(None) - self.set_quit() - self.clear_tracefuncs() - self.continuewithoutdebugger = 1 - if hasattr(self, "w") and self.w.parent: - self.exit_mainloop() - self.resetwidgets() - - def clear_tracefuncs(self): - try: - raise 'spam' - except: - pass - frame = sys.exc_traceback.tb_frame - while frame is not None: - del frame.f_trace - frame = frame.f_back - - def postmortem(self, exc_type, exc_value, traceback): - if self.closed: - self.setupwidgets(self.title) - self.closed = 0 - if not self.w.parent.debugger_quitting: - raise W.AlertError, 'There is another debugger session busy.' - self.reset() - if traceback: - self.botframe = traceback.tb_frame - while traceback.tb_next <> None: - traceback = traceback.tb_next - frame = traceback.tb_frame - else: - self.botframe = None - frame = None - self.w.panes.bottom.buttons.killbutton.enable(1) - self.reason = '(dead) ' + self.formatexception(exc_type, exc_value) - self.w.select() - self.setup(frame, traceback) - self.setstate('dead') - self.showstack(self.curindex) - self.showframe(self.curindex) - - def setupwidgets(self, title): - self.w = w = W.Window(self.bounds, title, minsize = (500, 300)) - - w.panes = W.HorizontalPanes((8, 4, -8, -8), self.horpanes) - - w.panes.browserpanes = browserpanes = W.VerticalPanes(None, self.verpanes) - - browserpanes.stacklist = W.Group(None) - browserpanes.stacklist.title = W.TextBox((4, 0, 0, 12), 'Stack') - browserpanes.stacklist.stack = W.List((0, 16, 0, 0), callback = self.do_stack, flags = Lists.lOnlyOne) - - browserpanes.locals = W.Group(None) - browserpanes.locals.title = W.TextBox((4, 0, 0, 12), 'Local variables') - browserpanes.locals.browser = PyBrowser.BrowserWidget((0, 16, 0, 0)) - - browserpanes.globals = W.Group(None) - browserpanes.globals.title = W.TextBox((4, 0, 0, 12), 'Global variables') - browserpanes.globals.browser = PyBrowser.BrowserWidget((0, 16, 0, 0)) - - w.panes.bottom = bottom = W.Group(None) - bottom.src = src = W.Group((0, 64, 0, 0)) - source = SourceViewer((1, 1, -15, -15), readonly = 1, debugger = self) - src.optionsmenu = W.PopupMenu((-16, 0, 16, 16), []) - src.optionsmenu.bind('<click>', self.makeoptionsmenu) - - src._barx = W.Scrollbar((0, -16, -15, 16), source.hscroll, max = 32767) - src._bary = W.Scrollbar((-16, 15, 16, -15), source.vscroll, max = 32767) - src.source = source - src.frame = W.Frame((0, 0, -15, -15)) - - bottom.tracingmonitor = TracingMonitor((0, 23, 6, 6)) - bottom.state = W.TextBox((12, 24, 0, 16), self.reason) - - bottom.srctitle = W.TextBox((12, 44, 0, 16)) - bottom.buttons = buttons = W.Group((12, 0, 0, 20)) - - buttons.runbutton = W.Button((0, 0, 50, 16), "Run", self.do_run) - buttons.stopbutton = W.Button((58, 0, 50, 16), "Stop", self.do_stop) - buttons.killbutton = W.Button((116, 0, 50, 16), "Kill", self.do_kill) - buttons.line = W.VerticalLine((173, 0, 0, 0)) - buttons.stepbutton = W.Button((181, 0, 60, 16), "Step", self.do_step) - buttons.stepinbutton = W.Button((249, 0, 60, 16), "Step in", self.do_stepin) - buttons.stepoutbutton = W.Button((317, 0, 60, 16), "Step out", self.do_stepout) - - w.bind('cmdr', buttons.runbutton.push) - w.bind('cmd.', buttons.stopbutton.push) - w.bind('cmdk', buttons.killbutton.push) - w.bind('cmds', buttons.stepbutton.push) - w.bind('cmdt', buttons.stepinbutton.push) - w.bind('cmdu', buttons.stepoutbutton.push) - - w.bind('<close>', self.close) - - w.open() - w.xxx___select(w.panes.bottom.src.source) - - def makeoptionsmenu(self): - options = [('Clear breakpoints', self.w.panes.bottom.src.source.clearbreakpoints), - ('Clear all breakpoints', self.clear_all_breaks), - ('Edit breakpoints\xc9', self.edit_breaks), '-', - (self.tracemagic and - 'Disable __magic__ tracing' or 'Enable __magic__ tracing', self.togglemagic)] - self.w.panes.bottom.src.optionsmenu.set(options) - - def edit_breaks(self): - if self.breaksviewer: - self.breaksviewer.select() - else: - self.breaksviewer = BreakpointsViewer(self) - - def togglemagic(self): - self.tracemagic = not self.tracemagic - - def setstate(self, state): - self.w.panes.bottom.tracingmonitor.reset() - self.w.panes.bottom.state.set(self.reason) - buttons = self.w.panes.bottom.buttons - if state == 'stopped': - buttons.runbutton.enable(1) - buttons.stopbutton.enable(0) - buttons.killbutton.enable(1) - buttons.stepbutton.enable(1) - buttons.stepinbutton.enable(1) - buttons.stepoutbutton.enable(1) - elif state == 'running': - buttons.runbutton.enable(0) - buttons.stopbutton.enable(1) - buttons.killbutton.enable(1) - buttons.stepbutton.enable(0) - buttons.stepinbutton.enable(0) - buttons.stepoutbutton.enable(0) - elif state == 'idle': - buttons.runbutton.enable(0) - buttons.stopbutton.enable(0) - buttons.killbutton.enable(0) - buttons.stepbutton.enable(0) - buttons.stepinbutton.enable(0) - buttons.stepoutbutton.enable(0) - elif state == 'dead': - buttons.runbutton.enable(0) - buttons.stopbutton.enable(0) - buttons.killbutton.enable(1) - buttons.stepbutton.enable(0) - buttons.stepinbutton.enable(0) - buttons.stepoutbutton.enable(0) - else: - print 'unknown state:', state - - def resetwidgets(self): - self.reason = '' - self.w.panes.bottom.srctitle.set('') - self.w.panes.bottom.src.source.set('') - self.w.panes.browserpanes.stacklist.stack.set([]) - self.w.panes.browserpanes.locals.browser.set({}) - self.w.panes.browserpanes.globals.browser.set({}) - self.setstate('idle') - - # W callbacks - - def close(self): - self.set_quit() - self.exit_mainloop() - self.closed = 1 - - self.unregister_editor(self.w.panes.bottom.src.source, - self.w.panes.bottom.src.source.file) - self.horpanes = self.w.panes.getpanesizes() - self.verpanes = self.w.panes.browserpanes.getpanesizes() - self.bounds = self.w.getbounds() - prefs = W.getapplication().getprefs() - prefs.debugger.breaks = self.breaks - prefs.debugger.windowsettings = self.bounds, self.horpanes, self.verpanes - prefs.debugger.tracemagic = self.tracemagic - prefs.save() - - # stack list callback - - def do_stack(self, isdbl): - sel = self.w.panes.browserpanes.stacklist.stack.getselection() - if isdbl: - if sel: - frame, lineno = self.stack[sel[0] + 1] - filename = frame.f_code.co_filename - editor = self.w._parentwindow.parent.openscript(filename, lineno) - if self.breaks.has_key(filename): - editor.showbreakpoints(1) - else: - if sel and sel <> self.laststacksel: - self.showframe(sel[0] + 1) - self.laststacksel = sel - - def geteditor(self, filename): - if filename[:1] == '<' and filename[-1:] == '>': - editor = W.getapplication().getscript(filename[1:-1]) - else: - editor = W.getapplication().getscript(filename) - return editor - - # button callbacks - - def do_run(self): - self.running() - self.set_continue() - self.exit_mainloop() - - def do_stop(self): - self.set_step() - - def do_kill(self): - self.set_quit() - self.exit_mainloop() - self.resetwidgets() - - def do_step(self): - self.running() - self.set_next(self.curframe) - self.exit_mainloop() - - def do_stepin(self): - self.running() - self.set_step() - self.exit_mainloop() - - def do_stepout(self): - self.running() - self.set_return(self.curframe) - self.exit_mainloop() - - def running(self): - W.SetCursor('watch') - self.reason = 'Running\xc9' - self.setstate('running') - #self.w.panes.bottom.src.source.set('') - #self.w.panes.browserpanes.stacklist.stack.set([]) - #self.w.panes.browserpanes.locals.browser.set({}) - #self.w.panes.browserpanes.globals.browser.set({}) - - def exit_mainloop(self): - self.w.parent.debugger_quitting = 1 - - # - - def showframe(self, stackindex): - (frame, lineno) = self.stack[stackindex] - W.SetCursor('watch') - filename = frame.f_code.co_filename - if filename <> self.file: - editor = self.geteditor(filename) - if editor: - self.w.panes.bottom.src.source.set(editor.get(), filename) - else: - try: - f = open(filename, 'rU') - data = f.read() - f.close() - except IOError: - if filename[-3:] == '.py': - import imp - modname = os.path.basename(filename)[:-3] - try: - f, filename, (suff, mode, dummy) = imp.find_module(modname) - except ImportError: - self.w.panes.bottom.src.source.set("can't find file") - else: - if f: - f.close() - if f and suff == '.py': - f = open(filename, 'rU') - data = f.read() - f.close() - self.w.panes.bottom.src.source.set(data, filename) - else: - self.w.panes.bottom.src.source.set("can't find file") - else: - self.w.panes.bottom.src.source.set("can't find file") - else: - data = data.replace('\n', '\r') - self.w.panes.bottom.src.source.set(data, filename) - self.file = filename - self.w.panes.bottom.srctitle.set('Source: ' + filename + ((lineno > 0) and (' (line %d)' % lineno) or ' ')) - self.goto_line(lineno) - self.lineno = lineno - self.showvars((frame, lineno)) - - def showvars(self, (frame, lineno)): - if frame.f_locals is not frame.f_globals: - locals = frame.f_locals - else: - locals = {'Same as Globals':''} - filteredlocals = {} - for key, value in locals.items(): - # empty key is magic for Python 1.4; '.' is magic for 1.5... - if not key or key[0] <> '.': - filteredlocals[key] = value - self.w.panes.browserpanes.locals.browser.set(filteredlocals) - self.w.panes.browserpanes.globals.browser.set(frame.f_globals) - - def showstack(self, stackindex): - stack = [] - for frame, lineno in self.stack[1:]: - filename = frame.f_code.co_filename - try: - filename = _filenames[filename] - except KeyError: - if filename[:1] + filename[-1:] <> '<>': - filename = os.path.basename(filename) - _filenames[frame.f_code.co_filename] = filename - funcname = frame.f_code.co_name - if funcname == '?': - funcname = '<toplevel>' - stack.append(filename + ': ' + funcname) - if stack <> self.laststack: - self.w.panes.browserpanes.stacklist.stack.set(stack) - self.laststack = stack - sel = [stackindex - 1] - self.w.panes.browserpanes.stacklist.stack.setselection(sel) - self.laststacksel = sel - - def goto_line(self, lineno): - if lineno > 0: - self.w.panes.bottom.src.source.selectline(lineno - 1) - else: - self.w.panes.bottom.src.source.setselection(0, 0) - - # bdb entry points - -# def user_call(self, frame, argument_list): -# self.reason = 'Calling' -# self.interaction(frame, None) - - def user_line(self, frame): - # This function is called when we stop or break at this line - self.reason = 'Stopped' - self.interaction(frame, None) - - def user_return(self, frame, return_value): - # This function is called when a return trap is set here - fname = frame.f_code.co_name - if fname <> '?': - self.reason = 'Returning from %s()' % frame.f_code.co_name - frame.f_locals['__return__'] = return_value - elif frame.f_back is self.botframe: - self.reason = 'Done' - else: - self.reason = 'Returning' - self.interaction(frame, None, 1) - - def user_exception(self, frame, (exc_type, exc_value, exc_traceback)): - # This function is called when we stop or break at this line - self.reason = self.formatexception(exc_type, exc_value) - self.interaction(frame, exc_traceback) - - def formatexception(self, exc_type, exc_value): - if exc_type == SyntaxError: - try: - value, (filename, lineno, charno, line) = exc_value - except: - pass - else: - return str(exc_type) + ': ' + str(value) - if type(exc_type) == types.ClassType: - nice = exc_type.__name__ - else: - nice = str(exc_type) - value = str(exc_value) - if exc_value and value: - nice = nice + ": " + value - return nice - - def forget(self): - self.stack = [] - self.curindex = 0 - self.curframe = None - - def setup(self, f, t, isreturning = 0): - self.forget() - self.stack, self.curindex = self.get_stack(f, t) - self.curframe = self.stack[self.curindex - isreturning][0] - - def interaction(self, frame, traceback, isreturning = 0): - saveport = Qd.GetPort() - self.w.select() - try: - self.setup(frame, traceback, isreturning) - self.setstate('stopped') - stackindex = self.curindex - if isreturning: - if frame.f_back is not self.botframe: - stackindex = stackindex - 1 - self.showstack(stackindex) - self.showframe(stackindex) - self.w.parent.debugger_mainloop() - self.forget() - finally: - Qd.SetPort(saveport) - - # bdb customization - - def trace_dispatch(self, frame, event, arg, TickCount = Evt.TickCount): - if TickCount() - self.tracingmonitortime > 15: - self.tracingmonitortime = TickCount() - self.w.panes.bottom.tracingmonitor.toggle() - try: - try: - if hasattr(MacOS, 'EnableAppswitch'): - MacOS.EnableAppswitch(0) - if self.quitting: - # returning None is not enough, a former BdbQuit exception - # might have been eaten by the print statement - raise bdb.BdbQuit - if event == 'line': - return self.dispatch_line(frame) - if event == 'call': - return self.dispatch_call(frame, arg) - if event == 'return': - return self.dispatch_return(frame, arg) - if event == 'exception': - return self.dispatch_exception(frame, arg) - print 'bdb.Bdb.dispatch: unknown debugging event:', repr(event) - return self.trace_dispatch - finally: - if hasattr(MacOS, 'EnableAppswitch'): - MacOS.EnableAppswitch(-1) - except KeyboardInterrupt: - self.set_step() - return self.trace_dispatch - except bdb.BdbQuit: - if self.continuewithoutdebugger: - self.clear_tracefuncs() - return - else: - raise bdb.BdbQuit - except: - print 'XXX Exception during debugger interaction.', \ - self.formatexception(sys.exc_type, sys.exc_value) - import traceback - traceback.print_exc() - return self.trace_dispatch - - def dispatch_call(self, frame, arg): - if not self.tracemagic and \ - frame.f_code.co_name[:2] == '__' == frame.f_code.co_name[-2:] and \ - frame.f_code.co_name <> '__init__': - return - if self.botframe is None: - # First call of dispatch since reset() - self.botframe = frame.f_back # xxx !!! added f_back - return self.trace_dispatch - if not (self.stop_here(frame) or self.break_anywhere(frame)): - # No need to trace this function - return # None - self.user_call(frame, arg) - if self.quitting: - raise bdb.BdbQuit - return self.trace_dispatch - - def set_continue(self): - # Don't stop except at breakpoints or when finished - self.stopframe = self.botframe - self.returnframe = None - self.quitting = 0 - # unlike in bdb/pdb, there's a chance that breakpoints change - # *while* a program (this program ;-) is running. It's actually quite likely. - # So we don't delete frame.f_trace until the bottom frame if there are no breakpoints. - - def set_break(self, filename, lineno): - if not self.breaks.has_key(filename): - self.breaks[filename] = [] - list = self.breaks[filename] - if lineno in list: - return 'There is already a breakpoint there!' - list.append(lineno) - list.sort() # I want to keep them neatly sorted; easier for drawing - if hasattr(bdb, "Breakpoint"): - # 1.5.2b1 specific - bp = bdb.Breakpoint(filename, lineno, 0, None) - self.update_breaks(filename) - - def clear_break(self, filename, lineno): - bdb.Bdb.clear_break(self, filename, lineno) - self.update_breaks(filename) - - def clear_all_file_breaks(self, filename): - bdb.Bdb.clear_all_file_breaks(self, filename) - self.update_breaks(filename) - - def clear_all_breaks(self): - bdb.Bdb.clear_all_breaks(self) - for editors in self.editors.values(): - for editor in editors: - editor.drawbreakpoints() - - # special - - def toggle_break(self, filename, lineno): - if self.get_break(filename, lineno): - self.clear_break(filename, lineno) - else: - self.set_break(filename, lineno) - - def clear_breaks_above(self, filename, above): - if not self.breaks.has_key(filename): - return 'There are no breakpoints in that file!' - for lineno in self.breaks[filename][:]: - if lineno > above: - self.breaks[filename].remove(lineno) - if not self.breaks[filename]: - del self.breaks[filename] - - # editor stuff - - def update_breaks(self, filename): - if self.breaksviewer: - self.breaksviewer.update() - if self.editors.has_key(filename): - for editor in self.editors[filename]: - if editor._debugger: # XXX - editor.drawbreakpoints() - else: - print 'xxx dead editor!' - - def update_allbreaks(self): - if self.breaksviewer: - self.breaksviewer.update() - for filename in self.breaks.keys(): - if self.editors.has_key(filename): - for editor in self.editors[filename]: - if editor._debugger: # XXX - editor.drawbreakpoints() - else: - print 'xxx dead editor!' - - def register_editor(self, editor, filename): - if not filename: - return - if not self.editors.has_key(filename): - self.editors[filename] = [editor] - elif editor not in self.editors[filename]: - self.editors[filename].append(editor) - - def unregister_editor(self, editor, filename): - if not filename: - return - try: - self.editors[filename].remove(editor) - if not self.editors[filename]: - del self.editors[filename] - # if this was an untitled window, clear the breaks. - if filename[:1] == '<' and filename[-1:] == '>' and \ - self.breaks.has_key(filename): - self.clear_all_file_breaks(filename) - except (KeyError, ValueError): - pass - + + def __init__(self, title = 'Debugger'): + bdb.Bdb.__init__(self) + self.closed = 1 + self.title = title + self.breaksviewer = None + self.reset() + self.tracing = 0 + self.tracingmonitortime = Evt.TickCount() + self.editors = {} + + prefs = W.getapplication().getprefs() + if prefs.debugger: + for file, breaks in prefs.debugger.breaks.items(): + for b in breaks: + self.set_break(file, b) + self.bounds, self.horpanes, self.verpanes = prefs.debugger.windowsettings + self.tracemagic = prefs.debugger.tracemagic + else: + self.breaks = {} + self.horpanes = (0.4, 0.6) + self.verpanes = (0.3, 0.35, 0.35) + self.bounds = (600, 400) + self.tracemagic = 0 + self.laststacksel = None + + def canonic(self, filename): + # override: the provided canonic() method breaks our + # file-less Untitled windows + return filename + + def reset(self): + self.currentframe = None + self.file = None + self.laststack = None + self.reason = 'Not running' + self.continuewithoutdebugger = 0 + bdb.Bdb.reset(self) + self.forget() + + def start(self, bottomframe = None, running = 0): + W.getapplication().DebuggerQuit = bdb.BdbQuit + from Carbon import Menu + Menu.HiliteMenu(0) + if self.closed: + self.setupwidgets(self.title) + self.closed = 0 + if not self.w.parent.debugger_quitting: + self.w.select() + raise W.AlertError, 'There is another debugger session busy.' + self.reset() + self.botframe = bottomframe + if running: + self.set_continue() + self.reason = 'Running\xc9' + self.setstate('running') + else: + self.set_step() + self.reason = 'stopped' + self.setstate('stopped') + sys.settrace(self.trace_dispatch) + + def stop(self): + self.set_quit() + if self.w.parent: + self.exit_mainloop() + self.resetwidgets() + + def set_continue_without_debugger(self): + sys.settrace(None) + self.set_quit() + self.clear_tracefuncs() + self.continuewithoutdebugger = 1 + if hasattr(self, "w") and self.w.parent: + self.exit_mainloop() + self.resetwidgets() + + def clear_tracefuncs(self): + try: + raise 'spam' + except: + pass + frame = sys.exc_traceback.tb_frame + while frame is not None: + del frame.f_trace + frame = frame.f_back + + def postmortem(self, exc_type, exc_value, traceback): + if self.closed: + self.setupwidgets(self.title) + self.closed = 0 + if not self.w.parent.debugger_quitting: + raise W.AlertError, 'There is another debugger session busy.' + self.reset() + if traceback: + self.botframe = traceback.tb_frame + while traceback.tb_next <> None: + traceback = traceback.tb_next + frame = traceback.tb_frame + else: + self.botframe = None + frame = None + self.w.panes.bottom.buttons.killbutton.enable(1) + self.reason = '(dead) ' + self.formatexception(exc_type, exc_value) + self.w.select() + self.setup(frame, traceback) + self.setstate('dead') + self.showstack(self.curindex) + self.showframe(self.curindex) + + def setupwidgets(self, title): + self.w = w = W.Window(self.bounds, title, minsize = (500, 300)) + + w.panes = W.HorizontalPanes((8, 4, -8, -8), self.horpanes) + + w.panes.browserpanes = browserpanes = W.VerticalPanes(None, self.verpanes) + + browserpanes.stacklist = W.Group(None) + browserpanes.stacklist.title = W.TextBox((4, 0, 0, 12), 'Stack') + browserpanes.stacklist.stack = W.List((0, 16, 0, 0), callback = self.do_stack, flags = Lists.lOnlyOne) + + browserpanes.locals = W.Group(None) + browserpanes.locals.title = W.TextBox((4, 0, 0, 12), 'Local variables') + browserpanes.locals.browser = PyBrowser.BrowserWidget((0, 16, 0, 0)) + + browserpanes.globals = W.Group(None) + browserpanes.globals.title = W.TextBox((4, 0, 0, 12), 'Global variables') + browserpanes.globals.browser = PyBrowser.BrowserWidget((0, 16, 0, 0)) + + w.panes.bottom = bottom = W.Group(None) + bottom.src = src = W.Group((0, 64, 0, 0)) + source = SourceViewer((1, 1, -15, -15), readonly = 1, debugger = self) + src.optionsmenu = W.PopupMenu((-16, 0, 16, 16), []) + src.optionsmenu.bind('<click>', self.makeoptionsmenu) + + src._barx = W.Scrollbar((0, -16, -15, 16), source.hscroll, max = 32767) + src._bary = W.Scrollbar((-16, 15, 16, -15), source.vscroll, max = 32767) + src.source = source + src.frame = W.Frame((0, 0, -15, -15)) + + bottom.tracingmonitor = TracingMonitor((0, 23, 6, 6)) + bottom.state = W.TextBox((12, 24, 0, 16), self.reason) + + bottom.srctitle = W.TextBox((12, 44, 0, 16)) + bottom.buttons = buttons = W.Group((12, 0, 0, 20)) + + buttons.runbutton = W.Button((0, 0, 50, 16), "Run", self.do_run) + buttons.stopbutton = W.Button((58, 0, 50, 16), "Stop", self.do_stop) + buttons.killbutton = W.Button((116, 0, 50, 16), "Kill", self.do_kill) + buttons.line = W.VerticalLine((173, 0, 0, 0)) + buttons.stepbutton = W.Button((181, 0, 60, 16), "Step", self.do_step) + buttons.stepinbutton = W.Button((249, 0, 60, 16), "Step in", self.do_stepin) + buttons.stepoutbutton = W.Button((317, 0, 60, 16), "Step out", self.do_stepout) + + w.bind('cmdr', buttons.runbutton.push) + w.bind('cmd.', buttons.stopbutton.push) + w.bind('cmdk', buttons.killbutton.push) + w.bind('cmds', buttons.stepbutton.push) + w.bind('cmdt', buttons.stepinbutton.push) + w.bind('cmdu', buttons.stepoutbutton.push) + + w.bind('<close>', self.close) + + w.open() + w.xxx___select(w.panes.bottom.src.source) + + def makeoptionsmenu(self): + options = [('Clear breakpoints', self.w.panes.bottom.src.source.clearbreakpoints), + ('Clear all breakpoints', self.clear_all_breaks), + ('Edit breakpoints\xc9', self.edit_breaks), '-', + (self.tracemagic and + 'Disable __magic__ tracing' or 'Enable __magic__ tracing', self.togglemagic)] + self.w.panes.bottom.src.optionsmenu.set(options) + + def edit_breaks(self): + if self.breaksviewer: + self.breaksviewer.select() + else: + self.breaksviewer = BreakpointsViewer(self) + + def togglemagic(self): + self.tracemagic = not self.tracemagic + + def setstate(self, state): + self.w.panes.bottom.tracingmonitor.reset() + self.w.panes.bottom.state.set(self.reason) + buttons = self.w.panes.bottom.buttons + if state == 'stopped': + buttons.runbutton.enable(1) + buttons.stopbutton.enable(0) + buttons.killbutton.enable(1) + buttons.stepbutton.enable(1) + buttons.stepinbutton.enable(1) + buttons.stepoutbutton.enable(1) + elif state == 'running': + buttons.runbutton.enable(0) + buttons.stopbutton.enable(1) + buttons.killbutton.enable(1) + buttons.stepbutton.enable(0) + buttons.stepinbutton.enable(0) + buttons.stepoutbutton.enable(0) + elif state == 'idle': + buttons.runbutton.enable(0) + buttons.stopbutton.enable(0) + buttons.killbutton.enable(0) + buttons.stepbutton.enable(0) + buttons.stepinbutton.enable(0) + buttons.stepoutbutton.enable(0) + elif state == 'dead': + buttons.runbutton.enable(0) + buttons.stopbutton.enable(0) + buttons.killbutton.enable(1) + buttons.stepbutton.enable(0) + buttons.stepinbutton.enable(0) + buttons.stepoutbutton.enable(0) + else: + print 'unknown state:', state + + def resetwidgets(self): + self.reason = '' + self.w.panes.bottom.srctitle.set('') + self.w.panes.bottom.src.source.set('') + self.w.panes.browserpanes.stacklist.stack.set([]) + self.w.panes.browserpanes.locals.browser.set({}) + self.w.panes.browserpanes.globals.browser.set({}) + self.setstate('idle') + + # W callbacks + + def close(self): + self.set_quit() + self.exit_mainloop() + self.closed = 1 + + self.unregister_editor(self.w.panes.bottom.src.source, + self.w.panes.bottom.src.source.file) + self.horpanes = self.w.panes.getpanesizes() + self.verpanes = self.w.panes.browserpanes.getpanesizes() + self.bounds = self.w.getbounds() + prefs = W.getapplication().getprefs() + prefs.debugger.breaks = self.breaks + prefs.debugger.windowsettings = self.bounds, self.horpanes, self.verpanes + prefs.debugger.tracemagic = self.tracemagic + prefs.save() + + # stack list callback + + def do_stack(self, isdbl): + sel = self.w.panes.browserpanes.stacklist.stack.getselection() + if isdbl: + if sel: + frame, lineno = self.stack[sel[0] + 1] + filename = frame.f_code.co_filename + editor = self.w._parentwindow.parent.openscript(filename, lineno) + if self.breaks.has_key(filename): + editor.showbreakpoints(1) + else: + if sel and sel <> self.laststacksel: + self.showframe(sel[0] + 1) + self.laststacksel = sel + + def geteditor(self, filename): + if filename[:1] == '<' and filename[-1:] == '>': + editor = W.getapplication().getscript(filename[1:-1]) + else: + editor = W.getapplication().getscript(filename) + return editor + + # button callbacks + + def do_run(self): + self.running() + self.set_continue() + self.exit_mainloop() + + def do_stop(self): + self.set_step() + + def do_kill(self): + self.set_quit() + self.exit_mainloop() + self.resetwidgets() + + def do_step(self): + self.running() + self.set_next(self.curframe) + self.exit_mainloop() + + def do_stepin(self): + self.running() + self.set_step() + self.exit_mainloop() + + def do_stepout(self): + self.running() + self.set_return(self.curframe) + self.exit_mainloop() + + def running(self): + W.SetCursor('watch') + self.reason = 'Running\xc9' + self.setstate('running') + #self.w.panes.bottom.src.source.set('') + #self.w.panes.browserpanes.stacklist.stack.set([]) + #self.w.panes.browserpanes.locals.browser.set({}) + #self.w.panes.browserpanes.globals.browser.set({}) + + def exit_mainloop(self): + self.w.parent.debugger_quitting = 1 + + # + + def showframe(self, stackindex): + (frame, lineno) = self.stack[stackindex] + W.SetCursor('watch') + filename = frame.f_code.co_filename + if filename <> self.file: + editor = self.geteditor(filename) + if editor: + self.w.panes.bottom.src.source.set(editor.get(), filename) + else: + try: + f = open(filename, 'rU') + data = f.read() + f.close() + except IOError: + if filename[-3:] == '.py': + import imp + modname = os.path.basename(filename)[:-3] + try: + f, filename, (suff, mode, dummy) = imp.find_module(modname) + except ImportError: + self.w.panes.bottom.src.source.set("can't find file") + else: + if f: + f.close() + if f and suff == '.py': + f = open(filename, 'rU') + data = f.read() + f.close() + self.w.panes.bottom.src.source.set(data, filename) + else: + self.w.panes.bottom.src.source.set("can't find file") + else: + self.w.panes.bottom.src.source.set("can't find file") + else: + data = data.replace('\n', '\r') + self.w.panes.bottom.src.source.set(data, filename) + self.file = filename + self.w.panes.bottom.srctitle.set('Source: ' + filename + ((lineno > 0) and (' (line %d)' % lineno) or ' ')) + self.goto_line(lineno) + self.lineno = lineno + self.showvars((frame, lineno)) + + def showvars(self, (frame, lineno)): + if frame.f_locals is not frame.f_globals: + locals = frame.f_locals + else: + locals = {'Same as Globals':''} + filteredlocals = {} + for key, value in locals.items(): + # empty key is magic for Python 1.4; '.' is magic for 1.5... + if not key or key[0] <> '.': + filteredlocals[key] = value + self.w.panes.browserpanes.locals.browser.set(filteredlocals) + self.w.panes.browserpanes.globals.browser.set(frame.f_globals) + + def showstack(self, stackindex): + stack = [] + for frame, lineno in self.stack[1:]: + filename = frame.f_code.co_filename + try: + filename = _filenames[filename] + except KeyError: + if filename[:1] + filename[-1:] <> '<>': + filename = os.path.basename(filename) + _filenames[frame.f_code.co_filename] = filename + funcname = frame.f_code.co_name + if funcname == '?': + funcname = '<toplevel>' + stack.append(filename + ': ' + funcname) + if stack <> self.laststack: + self.w.panes.browserpanes.stacklist.stack.set(stack) + self.laststack = stack + sel = [stackindex - 1] + self.w.panes.browserpanes.stacklist.stack.setselection(sel) + self.laststacksel = sel + + def goto_line(self, lineno): + if lineno > 0: + self.w.panes.bottom.src.source.selectline(lineno - 1) + else: + self.w.panes.bottom.src.source.setselection(0, 0) + + # bdb entry points + +# def user_call(self, frame, argument_list): +# self.reason = 'Calling' +# self.interaction(frame, None) + + def user_line(self, frame): + # This function is called when we stop or break at this line + self.reason = 'Stopped' + self.interaction(frame, None) + + def user_return(self, frame, return_value): + # This function is called when a return trap is set here + fname = frame.f_code.co_name + if fname <> '?': + self.reason = 'Returning from %s()' % frame.f_code.co_name + frame.f_locals['__return__'] = return_value + elif frame.f_back is self.botframe: + self.reason = 'Done' + else: + self.reason = 'Returning' + self.interaction(frame, None, 1) + + def user_exception(self, frame, (exc_type, exc_value, exc_traceback)): + # This function is called when we stop or break at this line + self.reason = self.formatexception(exc_type, exc_value) + self.interaction(frame, exc_traceback) + + def formatexception(self, exc_type, exc_value): + if exc_type == SyntaxError: + try: + value, (filename, lineno, charno, line) = exc_value + except: + pass + else: + return str(exc_type) + ': ' + str(value) + if type(exc_type) == types.ClassType: + nice = exc_type.__name__ + else: + nice = str(exc_type) + value = str(exc_value) + if exc_value and value: + nice = nice + ": " + value + return nice + + def forget(self): + self.stack = [] + self.curindex = 0 + self.curframe = None + + def setup(self, f, t, isreturning = 0): + self.forget() + self.stack, self.curindex = self.get_stack(f, t) + self.curframe = self.stack[self.curindex - isreturning][0] + + def interaction(self, frame, traceback, isreturning = 0): + saveport = Qd.GetPort() + self.w.select() + try: + self.setup(frame, traceback, isreturning) + self.setstate('stopped') + stackindex = self.curindex + if isreturning: + if frame.f_back is not self.botframe: + stackindex = stackindex - 1 + self.showstack(stackindex) + self.showframe(stackindex) + self.w.parent.debugger_mainloop() + self.forget() + finally: + Qd.SetPort(saveport) + + # bdb customization + + def trace_dispatch(self, frame, event, arg, TickCount = Evt.TickCount): + if TickCount() - self.tracingmonitortime > 15: + self.tracingmonitortime = TickCount() + self.w.panes.bottom.tracingmonitor.toggle() + try: + try: + if hasattr(MacOS, 'EnableAppswitch'): + MacOS.EnableAppswitch(0) + if self.quitting: + # returning None is not enough, a former BdbQuit exception + # might have been eaten by the print statement + raise bdb.BdbQuit + if event == 'line': + return self.dispatch_line(frame) + if event == 'call': + return self.dispatch_call(frame, arg) + if event == 'return': + return self.dispatch_return(frame, arg) + if event == 'exception': + return self.dispatch_exception(frame, arg) + print 'bdb.Bdb.dispatch: unknown debugging event:', repr(event) + return self.trace_dispatch + finally: + if hasattr(MacOS, 'EnableAppswitch'): + MacOS.EnableAppswitch(-1) + except KeyboardInterrupt: + self.set_step() + return self.trace_dispatch + except bdb.BdbQuit: + if self.continuewithoutdebugger: + self.clear_tracefuncs() + return + else: + raise bdb.BdbQuit + except: + print 'XXX Exception during debugger interaction.', \ + self.formatexception(sys.exc_type, sys.exc_value) + import traceback + traceback.print_exc() + return self.trace_dispatch + + def dispatch_call(self, frame, arg): + if not self.tracemagic and \ + frame.f_code.co_name[:2] == '__' == frame.f_code.co_name[-2:] and \ + frame.f_code.co_name <> '__init__': + return + if self.botframe is None: + # First call of dispatch since reset() + self.botframe = frame.f_back # xxx !!! added f_back + return self.trace_dispatch + if not (self.stop_here(frame) or self.break_anywhere(frame)): + # No need to trace this function + return # None + self.user_call(frame, arg) + if self.quitting: + raise bdb.BdbQuit + return self.trace_dispatch + + def set_continue(self): + # Don't stop except at breakpoints or when finished + self.stopframe = self.botframe + self.returnframe = None + self.quitting = 0 + # unlike in bdb/pdb, there's a chance that breakpoints change + # *while* a program (this program ;-) is running. It's actually quite likely. + # So we don't delete frame.f_trace until the bottom frame if there are no breakpoints. + + def set_break(self, filename, lineno): + if not self.breaks.has_key(filename): + self.breaks[filename] = [] + list = self.breaks[filename] + if lineno in list: + return 'There is already a breakpoint there!' + list.append(lineno) + list.sort() # I want to keep them neatly sorted; easier for drawing + if hasattr(bdb, "Breakpoint"): + # 1.5.2b1 specific + bp = bdb.Breakpoint(filename, lineno, 0, None) + self.update_breaks(filename) + + def clear_break(self, filename, lineno): + bdb.Bdb.clear_break(self, filename, lineno) + self.update_breaks(filename) + + def clear_all_file_breaks(self, filename): + bdb.Bdb.clear_all_file_breaks(self, filename) + self.update_breaks(filename) + + def clear_all_breaks(self): + bdb.Bdb.clear_all_breaks(self) + for editors in self.editors.values(): + for editor in editors: + editor.drawbreakpoints() + + # special + + def toggle_break(self, filename, lineno): + if self.get_break(filename, lineno): + self.clear_break(filename, lineno) + else: + self.set_break(filename, lineno) + + def clear_breaks_above(self, filename, above): + if not self.breaks.has_key(filename): + return 'There are no breakpoints in that file!' + for lineno in self.breaks[filename][:]: + if lineno > above: + self.breaks[filename].remove(lineno) + if not self.breaks[filename]: + del self.breaks[filename] + + # editor stuff + + def update_breaks(self, filename): + if self.breaksviewer: + self.breaksviewer.update() + if self.editors.has_key(filename): + for editor in self.editors[filename]: + if editor._debugger: # XXX + editor.drawbreakpoints() + else: + print 'xxx dead editor!' + + def update_allbreaks(self): + if self.breaksviewer: + self.breaksviewer.update() + for filename in self.breaks.keys(): + if self.editors.has_key(filename): + for editor in self.editors[filename]: + if editor._debugger: # XXX + editor.drawbreakpoints() + else: + print 'xxx dead editor!' + + def register_editor(self, editor, filename): + if not filename: + return + if not self.editors.has_key(filename): + self.editors[filename] = [editor] + elif editor not in self.editors[filename]: + self.editors[filename].append(editor) + + def unregister_editor(self, editor, filename): + if not filename: + return + try: + self.editors[filename].remove(editor) + if not self.editors[filename]: + del self.editors[filename] + # if this was an untitled window, clear the breaks. + if filename[:1] == '<' and filename[-1:] == '>' and \ + self.breaks.has_key(filename): + self.clear_all_file_breaks(filename) + except (KeyError, ValueError): + pass + class SourceViewer(W.PyEditor): - - def __init__(self, *args, **kwargs): - apply(W.PyEditor.__init__, (self,) + args, kwargs) - self.bind('<click>', self.clickintercept) - - def clickintercept(self, point, modifiers): - if self._parentwindow._currentwidget <> self and not self.pt_in_breaks(point): - self._parentwindow.xxx___select(self) - return 1 - - def _getviewrect(self): - l, t, r, b = self._bounds - if self._debugger: - return (l + 12, t + 2, r - 1, b - 2) - else: - return (l + 5, t + 2, r - 1, b - 2) - - def select(self, onoff, isclick = 0): - if W.SelectableWidget.select(self, onoff): - return - self.SetPort() - #if onoff: - # self.ted.WEActivate() - #else: - # self.ted.WEDeactivate() - self.drawselframe(onoff) - - def drawselframe(self, onoff): - pass + + def __init__(self, *args, **kwargs): + apply(W.PyEditor.__init__, (self,) + args, kwargs) + self.bind('<click>', self.clickintercept) + + def clickintercept(self, point, modifiers): + if self._parentwindow._currentwidget <> self and not self.pt_in_breaks(point): + self._parentwindow.xxx___select(self) + return 1 + + def _getviewrect(self): + l, t, r, b = self._bounds + if self._debugger: + return (l + 12, t + 2, r - 1, b - 2) + else: + return (l + 5, t + 2, r - 1, b - 2) + + def select(self, onoff, isclick = 0): + if W.SelectableWidget.select(self, onoff): + return + self.SetPort() + #if onoff: + # self.ted.WEActivate() + #else: + # self.ted.WEDeactivate() + self.drawselframe(onoff) + + def drawselframe(self, onoff): + pass class BreakpointsViewer: - - def __init__(self, debugger): - self.debugger = debugger - self.w = W.Window((300, 250), 'Breakpoints', minsize = (200, 200)) - self.w.panes = W.HorizontalPanes((8, 8, -8, -32), (0.3, 0.7)) - self.w.panes.files = W.List(None, callback = self.filehit) #, flags = Lists.lOnlyOne) - self.w.panes.gr = W.Group(None) - self.w.panes.gr.breaks = W.List((0, 0, -130, 0), callback = self.linehit) #, flags = Lists.lOnlyOne) - self.w.panes.gr.openbutton = W.Button((-80, 4, 0, 16), 'View\xc9', self.openbuttonhit) - self.w.panes.gr.deletebutton = W.Button((-80, 28, 0, 16), 'Delete', self.deletebuttonhit) - - self.w.bind('<close>', self.close) - self.w.bind('backspace', self.w.panes.gr.deletebutton.push) - - self.setup() - self.w.open() - self.w.panes.gr.openbutton.enable(0) - self.w.panes.gr.deletebutton.enable(0) - self.curfile = None - - def deletebuttonhit(self): - if self.w._currentwidget == self.w.panes.files: - self.del_filename() - else: - self.del_number() - self.checkbuttons() - - def del_number(self): - if self.curfile is None: - return - sel = self.w.panes.gr.breaks.getselectedobjects() - for lineno in sel: - self.debugger.clear_break(self.curfile, lineno) - - def del_filename(self): - sel = self.w.panes.files.getselectedobjects() - for filename in sel: - self.debugger.clear_all_file_breaks(filename) - self.debugger.update_allbreaks() - - def setup(self): - files = self.debugger.breaks.keys() - files.sort() - self.w.panes.files.set(files) - - def close(self): - self.debugger.breaksviewer = None - self.debugger = None - - def update(self): - sel = self.w.panes.files.getselectedobjects() - self.setup() - self.w.panes.files.setselectedobjects(sel) - sel = self.w.panes.files.getselection() - if len(sel) == 0 and self.curfile: - self.w.panes.files.setselectedobjects([self.curfile]) - self.filehit(0) - - def select(self): - self.w.select() - - def selectfile(self, file): - self.w.panes.files.setselectedobjects([file]) - self.filehit(0) - - def openbuttonhit(self): - self.filehit(1) - - def filehit(self, isdbl): - sel = self.w.panes.files.getselectedobjects() - if isdbl: - for filename in sel: - lineno = None - if filename == self.curfile: - linesel = self.w.panes.gr.breaks.getselectedobjects() - if linesel: - lineno = linesel[-1] - elif self.w.panes.gr.breaks: - lineno = self.w.panes.gr.breaks[0] - editor = self.w._parentwindow.parent.openscript(filename, lineno) - editor.showbreakpoints(1) - return - if len(sel) == 1: - file = sel[0] - filebreaks = self.debugger.breaks[file][:] - if self.curfile == file: - linesel = self.w.panes.gr.breaks.getselectedobjects() - self.w.panes.gr.breaks.set(filebreaks) - if self.curfile == file: - self.w.panes.gr.breaks.setselectedobjects(linesel) - self.curfile = file - else: - if len(sel) <> 0: - self.curfile = None - self.w.panes.gr.breaks.set([]) - self.checkbuttons() - - def linehit(self, isdbl): - if isdbl: - files = self.w.panes.files.getselectedobjects() - if len(files) <> 1: - return - filename = files[0] - linenos = self.w.panes.gr.breaks.getselectedobjects() - if not linenos: - return - lineno = linenos[-1] - editor = self.w._parentwindow.parent.openscript(filename, lineno) - editor.showbreakpoints(1) - self.checkbuttons() - - def checkbuttons(self): - if self.w.panes.files.getselection(): - self.w.panes.gr.openbutton.enable(1) - self.w._parentwindow.setdefaultbutton(self.w.panes.gr.openbutton) - if self.w._currentwidget == self.w.panes.files: - if self.w.panes.files.getselection(): - self.w.panes.gr.deletebutton.enable(1) - else: - self.w.panes.gr.deletebutton.enable(0) - else: - if self.w.panes.gr.breaks.getselection(): - self.w.panes.gr.deletebutton.enable(1) - else: - self.w.panes.gr.deletebutton.enable(0) - else: - self.w.panes.gr.openbutton.enable(0) - self.w.panes.gr.deletebutton.enable(0) + + def __init__(self, debugger): + self.debugger = debugger + self.w = W.Window((300, 250), 'Breakpoints', minsize = (200, 200)) + self.w.panes = W.HorizontalPanes((8, 8, -8, -32), (0.3, 0.7)) + self.w.panes.files = W.List(None, callback = self.filehit) #, flags = Lists.lOnlyOne) + self.w.panes.gr = W.Group(None) + self.w.panes.gr.breaks = W.List((0, 0, -130, 0), callback = self.linehit) #, flags = Lists.lOnlyOne) + self.w.panes.gr.openbutton = W.Button((-80, 4, 0, 16), 'View\xc9', self.openbuttonhit) + self.w.panes.gr.deletebutton = W.Button((-80, 28, 0, 16), 'Delete', self.deletebuttonhit) + + self.w.bind('<close>', self.close) + self.w.bind('backspace', self.w.panes.gr.deletebutton.push) + + self.setup() + self.w.open() + self.w.panes.gr.openbutton.enable(0) + self.w.panes.gr.deletebutton.enable(0) + self.curfile = None + + def deletebuttonhit(self): + if self.w._currentwidget == self.w.panes.files: + self.del_filename() + else: + self.del_number() + self.checkbuttons() + + def del_number(self): + if self.curfile is None: + return + sel = self.w.panes.gr.breaks.getselectedobjects() + for lineno in sel: + self.debugger.clear_break(self.curfile, lineno) + + def del_filename(self): + sel = self.w.panes.files.getselectedobjects() + for filename in sel: + self.debugger.clear_all_file_breaks(filename) + self.debugger.update_allbreaks() + + def setup(self): + files = self.debugger.breaks.keys() + files.sort() + self.w.panes.files.set(files) + + def close(self): + self.debugger.breaksviewer = None + self.debugger = None + + def update(self): + sel = self.w.panes.files.getselectedobjects() + self.setup() + self.w.panes.files.setselectedobjects(sel) + sel = self.w.panes.files.getselection() + if len(sel) == 0 and self.curfile: + self.w.panes.files.setselectedobjects([self.curfile]) + self.filehit(0) + + def select(self): + self.w.select() + + def selectfile(self, file): + self.w.panes.files.setselectedobjects([file]) + self.filehit(0) + + def openbuttonhit(self): + self.filehit(1) + + def filehit(self, isdbl): + sel = self.w.panes.files.getselectedobjects() + if isdbl: + for filename in sel: + lineno = None + if filename == self.curfile: + linesel = self.w.panes.gr.breaks.getselectedobjects() + if linesel: + lineno = linesel[-1] + elif self.w.panes.gr.breaks: + lineno = self.w.panes.gr.breaks[0] + editor = self.w._parentwindow.parent.openscript(filename, lineno) + editor.showbreakpoints(1) + return + if len(sel) == 1: + file = sel[0] + filebreaks = self.debugger.breaks[file][:] + if self.curfile == file: + linesel = self.w.panes.gr.breaks.getselectedobjects() + self.w.panes.gr.breaks.set(filebreaks) + if self.curfile == file: + self.w.panes.gr.breaks.setselectedobjects(linesel) + self.curfile = file + else: + if len(sel) <> 0: + self.curfile = None + self.w.panes.gr.breaks.set([]) + self.checkbuttons() + + def linehit(self, isdbl): + if isdbl: + files = self.w.panes.files.getselectedobjects() + if len(files) <> 1: + return + filename = files[0] + linenos = self.w.panes.gr.breaks.getselectedobjects() + if not linenos: + return + lineno = linenos[-1] + editor = self.w._parentwindow.parent.openscript(filename, lineno) + editor.showbreakpoints(1) + self.checkbuttons() + + def checkbuttons(self): + if self.w.panes.files.getselection(): + self.w.panes.gr.openbutton.enable(1) + self.w._parentwindow.setdefaultbutton(self.w.panes.gr.openbutton) + if self.w._currentwidget == self.w.panes.files: + if self.w.panes.files.getselection(): + self.w.panes.gr.deletebutton.enable(1) + else: + self.w.panes.gr.deletebutton.enable(0) + else: + if self.w.panes.gr.breaks.getselection(): + self.w.panes.gr.deletebutton.enable(1) + else: + self.w.panes.gr.deletebutton.enable(0) + else: + self.w.panes.gr.openbutton.enable(0) + self.w.panes.gr.deletebutton.enable(0) class TracingMonitor(W.Widget): - - def __init__(self, *args, **kwargs): - apply(W.Widget.__init__, (self,) + args, kwargs) - self.state = 0 - - def toggle(self): - if hasattr(self, "_parentwindow") and self._parentwindow is not None: - self.state = self.state % 2 + 1 - port = Qd.GetPort() - self.SetPort() - self.draw() - Qd.SetPort(port) - - def reset(self): - if self._parentwindow: - self.state = 0 - port = Qd.GetPort() - self.SetPort() - self.draw() - Qd.SetPort(port) - - def draw(self, visRgn = None): - if self.state == 2: - Qd.PaintOval(self._bounds) - else: - Qd.EraseOval(self._bounds) + + def __init__(self, *args, **kwargs): + apply(W.Widget.__init__, (self,) + args, kwargs) + self.state = 0 + + def toggle(self): + if hasattr(self, "_parentwindow") and self._parentwindow is not None: + self.state = self.state % 2 + 1 + port = Qd.GetPort() + self.SetPort() + self.draw() + Qd.SetPort(port) + + def reset(self): + if self._parentwindow: + self.state = 0 + port = Qd.GetPort() + self.SetPort() + self.draw() + Qd.SetPort(port) + + def draw(self, visRgn = None): + if self.state == 2: + Qd.PaintOval(self._bounds) + else: + Qd.EraseOval(self._bounds) # convenience funcs def postmortem(exc_type, exc_value, tb): - d = getdebugger() - d.postmortem(exc_type, exc_value, tb) + d = getdebugger() + d.postmortem(exc_type, exc_value, tb) def start(bottomframe = None): - d = getdebugger() - d.start(bottomframe) + d = getdebugger() + d.start(bottomframe) def startfromhere(): - d = getdebugger() - try: - raise 'spam' - except: - frame = sys.exc_traceback.tb_frame.f_back - d.start(frame) + d = getdebugger() + try: + raise 'spam' + except: + frame = sys.exc_traceback.tb_frame.f_back + d.start(frame) def startfrombottom(): - d = getdebugger() - d.start(_getbottomframe(), 1) + d = getdebugger() + d.start(_getbottomframe(), 1) def stop(): - d = getdebugger() - d.stop() + d = getdebugger() + d.stop() def cont(): - sys.settrace(None) - d = getdebugger() - d.set_continue_without_debugger() + sys.settrace(None) + d = getdebugger() + d.set_continue_without_debugger() def _getbottomframe(): - try: - raise 'spam' - except: - pass - frame = sys.exc_traceback.tb_frame - while 1: - if frame.f_code.co_name == 'mainloop' or frame.f_back is None: - break - frame = frame.f_back - return frame + try: + raise 'spam' + except: + pass + frame = sys.exc_traceback.tb_frame + while 1: + if frame.f_code.co_name == 'mainloop' or frame.f_back is None: + break + frame = frame.f_back + return frame _debugger = None def getdebugger(): - if not __debug__: - raise W.AlertError, "Can't debug in \"Optimize bytecode\" mode.\r(see \"Default startup options\" in EditPythonPreferences)" - global _debugger - if _debugger is None: - _debugger = Debugger() - return _debugger + if not __debug__: + raise W.AlertError, "Can't debug in \"Optimize bytecode\" mode.\r(see \"Default startup options\" in EditPythonPreferences)" + global _debugger + if _debugger is None: + _debugger = Debugger() + return _debugger |