#7509: notebook -- make it possible to debug Python code in the notebook, e.g.,
something like pdb that works in the notebook
---------------------------+------------------------------------------------
Reporter: was | Owner: boothby
Type: enhancement | Status: new
Priority: major | Milestone: sage-4.3
Component: notebook | Keywords:
Work_issues: | Author:
Reviewer: | Merged:
---------------------------+------------------------------------------------
Comment(by was):
Paste the following code into any notebook cell (in any version of sage
ever) and you have a debugger.
{{{
class debug:
"""
If you get a traceback in the notebook, type ``d=debug()`` right
after the error to create a debugger object on that traceback.
Using the debugger you can move and down the call stack, and
evaluate arbitrary code anywhere in the call stack (typically
to inspect the value of variables).
- printing ``d`` shows the call stack and some context
- ``d.up(n)`` (or ``d.u(n)``) moves up `n` frames in
the call stack
- ``d.down(n)`` (or ``d.d(n)``) moves down `n` frames
in the call stack
- ``d.list(n)`` (or ``d.l(n)``) displays `n` lines of source
code context around the current position in the stack trace
- ``d("some code")`` executes the given code in the
context of the current position in the stack trace
Notes:
- Input is not preparsed.
- You can define and work with many debug objects at the same
time.
"""
def __init__(self):
import inspect, traceback
self.stack = inspect.getinnerframes(sys.last_traceback)
self.__curframe = len(self.stack) - 1
self.tb = traceback.format_tb(sys.last_traceback)
def curframe(self):
return self.stack[self.__curframe][0]
def frameno(self):
return self.__curframe
def __call__(self, line):
locals = self.curframe().f_locals
globals = self.curframe().f_globals
try:
code = compile(line + '\n', '<stdin>', 'single')
exec code in globals, locals
except:
t, v = sys.exc_info()[:2]
if type(t) == type(''):
exc_type_name = t
else: exc_type_name = t.__name__
print '***', exc_type_name + ':', v
def _highlight(self, line):
from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import HtmlFormatter
return highlight(line, PythonLexer(), HtmlFormatter())
def __repr__(self):
v = [' ' + str(i) + ': ' + ' '*(2*i) +
('\n'+' '*(2*i)).join(self.tb[i].splitlines())
for i in range(self.__curframe+1)]
if len(v) < len(self.stack):
v.append(' ............')
v.append(' ' + str(len(self.stack)-1) + ': (bottom frame)')
s = '<b>Traceback:</b>' + self._highlight('\n'.join(v)) +
self._list()
return '<html>%s</html>'%s
def up(self, n=1):
self.__curframe -= n
if self.__curframe < 0:
self.__curframe = 0
u = up
def down(self, n=1):
self.__curframe += n
if self.__curframe >= len(self.stack):
self.__curframe = len(self.stack)-1
d = down
def _list(self, n=3):
curframe = self.curframe()
filename = curframe.f_code.co_filename
lineno = curframe.f_lineno
import linecache
code = ''.join('--> ' if i ==lineno else ' ' +
linecache.getline(filename, i, curframe.f_globals) for
i in range(lineno-n, lineno+n+1))
i = filename.rfind('site-packages/sage')
if i != -1:
fname = filename[i+len('site-packages/sage')+1:].rstrip('/')
file = '<a href="/src/%s" target="_new">%s</a>'%(fname,fname)
else:
file = '<pre>%s</pre>'%filename
t = """<b>Frame:</b> %s\n<b>File: </b>%s<hr>%s<hr>"""%(
self.frameno(),
file,self._highlight(code).strip())
return t
def list(self, n=3):
html(self._list(n))
l = list
}}}
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/7509#comment:2>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sage-trac?hl=.