[svn r46772] add a custom pdb.Pdb subclass that has the ability to properly list the lines

generated by py.code.Source. Very useful in PyPy debugging.

--HG--
branch : trunk
This commit is contained in:
cfbolz 2007-09-20 17:26:09 +02:00
parent 77163a5bf7
commit d61ed8c014
4 changed files with 80 additions and 8 deletions

72
py/test/custompdb.py Normal file
View File

@ -0,0 +1,72 @@
import pdb, sys, linecache
class Pdb(pdb.Pdb):
def do_list(self, arg):
self.lastcmd = 'list'
last = None
if arg:
try:
x = eval(arg, {}, {})
if type(x) == type(()):
first, last = x
first = int(first)
last = int(last)
if last < first:
# Assume it's a count
last = first + last
else:
first = max(1, int(x) - 5)
except:
print '*** Error in argument:', repr(arg)
return
elif self.lineno is None:
first = max(1, self.curframe.f_lineno - 5)
else:
first = self.lineno + 1
if last is None:
last = first + 10
filename = self.curframe.f_code.co_filename
breaklist = self.get_file_breaks(filename)
try:
for lineno in range(first, last+1):
# start difference from normal do_line
line = self._getline(filename, lineno)
# end difference from normal do_line
if not line:
print '[EOF]'
break
else:
s = repr(lineno).rjust(3)
if len(s) < 4: s = s + ' '
if lineno in breaklist: s = s + 'B'
else: s = s + ' '
if lineno == self.curframe.f_lineno:
s = s + '->'
print s + '\t' + line,
self.lineno = lineno
except KeyboardInterrupt:
pass
do_l = do_list
def _getline(self, filename, lineno):
if hasattr(filename, "__source__"):
try:
return filename.__source__.lines[lineno - 1] + "\n"
except IndexError:
return None
return linecache.getline(filename, lineno)
def post_mortem(t):
# again, a copy of the version in pdb.py
t = outcome.excinfo._excinfo[2]
p = Pdb()
p.reset()
while t.tb_next is not None:
t = t.tb_next
p.interaction(t.tb_frame, t)
def set_trace():
# again, a copy of the version in pdb.py
Pdb().set_trace(sys._getframe().f_back)

View File

@ -7,6 +7,7 @@ from py.__.test.outcome import SerializableOutcome, ReprOutcome
from py.__.test.rsession.box import Box
from py.__.test import repevent
from py.__.test.outcome import Skipped, Failed
import py.__.test.custompdb
class RunExecutor(object):
""" Same as in executor, but just running run
@ -55,8 +56,7 @@ class RunExecutor(object):
self.reporter(repevent.ImmediateFailure(self.item,
ReprOutcome(outcome.make_repr
(self.config.option.tbstyle))))
import pdb
pdb.post_mortem(excinfo._excinfo[2])
py.__.test.custompdb.post_mortem(excinfo._excinfo[2])
# XXX hmm, we probably will not like to continue from that
# point
raise SystemExit()

View File

@ -6,6 +6,7 @@ import py
from py.__.test.rsession.rsession import LSession
from py.__.test import repevent
from py.__.test.rsession.local import box_runner, plain_runner, apigen_runner
import py.__.test.custompdb
def setup_module(mod):
mod.tmp = py.test.ensuretemp("lsession_module")
@ -78,14 +79,13 @@ class TestLSession(object):
def test_1():
assert 0
"""))
import pdb
l = []
def some_fun(*args):
l.append(args)
try:
post_mortem = pdb.post_mortem
pdb.post_mortem = some_fun
post_mortem = py.__.test.custompdb.post_mortem
py.__.test.custompdb.post_mortem = some_fun
args = [str(tmpdir.join(subdir)), '--pdb']
config = py.test.config._reparse(args)
lsession = LSession(config)
@ -101,7 +101,7 @@ class TestLSession(object):
assert len(failure_events) == 1
assert len(l) == 1
finally:
pdb.post_mortem = post_mortem
py.__.test.custompdb.post_mortem = post_mortem
def test_minus_x(self):
if not hasattr(py.std.os, 'fork'):

View File

@ -4,6 +4,7 @@ from time import time as now
from py.__.test.terminal.out import getout
from py.__.test.representation import Presenter
from py.__.test.outcome import Skipped, Passed, Failed
import py.__.test.custompdb
def getrelpath(source, dest):
base = source.common(dest)
@ -97,9 +98,8 @@ class TerminalSession(Session):
if isinstance(outcome, Failed):
print "dispatching to ppdb", colitem
self.repr_failure(colitem, outcome)
import pdb
self.out.write('\n%s\n' % (outcome.excinfo.exconly(),))
pdb.post_mortem(outcome.excinfo._excinfo[2])
py.__.test.custompdb.post_mortem(excinfo._excinfo[2])
if isinstance(colitem, py.test.collect.Module):
resultstring = self.repr_progress_module_result(colitem, outcome)
if resultstring: