Commit 2e5e14cb authored by Guido van Rossum's avatar Guido van Rossum

Ad primitive debugger interface (so far it will step and show you the

source, but it doesn't yet show the stack).
parent 6b4c2bb2
......@@ -109,6 +109,7 @@ emacs_bindings = [
("debug", "Go to line from traceback", None, "<<goto-traceback-line>>"),
("debug", "Open stack viewer", None, "<<open-stack-viewer>>"),
("debug", "Toggle debugger", None, "<<toggle-debugger>>"),
# Help menu
......
import os
import bdb
import traceback
from Tkinter import *
class Debugger(bdb.Bdb):
def __init__(self, pyshell):
bdb.Bdb.__init__(self)
self.pyshell = pyshell
self.make_gui()
def close(self):
self.top.destroy()
def user_line(self, frame):
self.interaction(frame)
def user_return(self, frame, rv):
# XXX show rv?
self.interaction(frame)
def user_exception(self, frame, info):
self.interaction(frame, info)
def make_gui(self):
pyshell = self.pyshell
self.flist = pyshell.flist
self.root = root = pyshell.root
self.top = top = Toplevel(root)
self.bframe = bframe = Frame(top)
self.bframe.pack()
self.buttons = bl = []
self.bcont = b = Button(bframe, text="Go", command=self.cont)
bl.append(b)
self.bstep = b = Button(bframe, text="Step into", command=self.step)
bl.append(b)
self.bnext = b = Button(bframe, text="Step over", command=self.next)
bl.append(b)
self.bret = b = Button(bframe, text="Step out", command=self.ret)
bl.append(b)
for b in bl:
b.configure(state="disabled")
b.pack(side="left")
self.status = Label(top)
self.status.pack()
def interaction(self, frame, info=None):
self.frame = frame
code = frame.f_code
file = code.co_filename
lineno = frame.f_lineno
message = "file=%s, name=%s, line=%s" % (file, code.co_name, lineno)
if info:
type, value, tb = info
m1 = "%s" % str(type)
## if value is not None:
## try:
## m1 = "%s: %s" % (m1, str(value))
## except:
## pass
message = "%s\n%s" % (message, m1)
self.status.configure(text=message)
if file[:1] + file[-1:] != "<>" and os.path.exists(file):
edit = self.flist.open(file)
if edit:
edit.gotoline(lineno)
for b in self.buttons:
b.configure(state="normal")
self.top.tkraise()
self.root.mainloop()
for b in self.buttons:
b.configure(state="disabled")
self.status.configure(text="")
self.frame = None
def cont(self):
self.set_continue()
self.root.quit()
def step(self):
self.set_step()
self.root.quit()
def next(self):
self.set_next(self.frame)
self.root.quit()
def ret(self):
self.set_return(self.frame)
self.root.quit()
......@@ -20,6 +20,7 @@ class PyShellEditorWindow(MultiEditorWindow):
def fixedwindowsmenu(self, wmenu):
wmenu.add_command(label="Python Shell", command=self.flist.open_shell)
wmenu.add_separator()
class PyShellFileList(FileList):
......@@ -138,12 +139,24 @@ class ModifiedInterpreter(InteractiveInterpreter):
if key[:1] + key[-1:] != "<>":
del c[key]
debugger = None
def setdebugger(self, debugger):
self.debugger = debugger
def getdebugger(self):
return self.debugger
def runcode(self, code):
# Override base class method
debugger = self.debugger
try:
self.tkconsole.beginexecuting()
try:
exec code in self.locals
if debugger:
debugger.run(code, self.locals)
else:
exec code in self.locals
except SystemExit:
if tkMessageBox.askyesno(
"Exit?",
......@@ -200,6 +213,7 @@ class PyShell(PyShellEditorWindow):
text.bind("<<end-of-file>>", self.eof_callback)
text.bind("<<goto-traceback-line>>", self.goto_traceback_line)
text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
text.bind("<<toggle-debugger>>", self.toggle_debugger)
sys.stdout = PseudoFile(self, "stdout")
sys.stderr = PseudoFile(self, "stderr")
......@@ -229,6 +243,28 @@ class PyShell(PyShellEditorWindow):
executing = 0
canceled = 0
endoffile = 0
def toggle_debugger(self, event=None):
if self.executing:
tkMessageBox.showerror("Don't debug now",
"You can only toggle the debugger when idle",
master=self.text)
return "break"
db = self.interp.getdebugger()
if db:
db.close()
self.resetoutput()
self.console.write("[DEBUG OFF]\n")
sys.ps1 = ">>> "
self.showprompt()
self.interp.setdebugger(None)
else:
import Debugger
self.interp.setdebugger(Debugger.Debugger(self))
sys.ps1 = "[DEBUG ON]>>> "
self.showprompt()
self.top.tkraise()
self.text.focus_set()
def beginexecuting(self):
# Helper for ModifiedInterpreter
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment