[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:
parent
77163a5bf7
commit
d61ed8c014
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ from py.__.test.outcome import SerializableOutcome, ReprOutcome
|
||||||
from py.__.test.rsession.box import Box
|
from py.__.test.rsession.box import Box
|
||||||
from py.__.test import repevent
|
from py.__.test import repevent
|
||||||
from py.__.test.outcome import Skipped, Failed
|
from py.__.test.outcome import Skipped, Failed
|
||||||
|
import py.__.test.custompdb
|
||||||
|
|
||||||
class RunExecutor(object):
|
class RunExecutor(object):
|
||||||
""" Same as in executor, but just running run
|
""" Same as in executor, but just running run
|
||||||
|
@ -55,8 +56,7 @@ class RunExecutor(object):
|
||||||
self.reporter(repevent.ImmediateFailure(self.item,
|
self.reporter(repevent.ImmediateFailure(self.item,
|
||||||
ReprOutcome(outcome.make_repr
|
ReprOutcome(outcome.make_repr
|
||||||
(self.config.option.tbstyle))))
|
(self.config.option.tbstyle))))
|
||||||
import pdb
|
py.__.test.custompdb.post_mortem(excinfo._excinfo[2])
|
||||||
pdb.post_mortem(excinfo._excinfo[2])
|
|
||||||
# XXX hmm, we probably will not like to continue from that
|
# XXX hmm, we probably will not like to continue from that
|
||||||
# point
|
# point
|
||||||
raise SystemExit()
|
raise SystemExit()
|
||||||
|
|
|
@ -6,6 +6,7 @@ import py
|
||||||
from py.__.test.rsession.rsession import LSession
|
from py.__.test.rsession.rsession import LSession
|
||||||
from py.__.test import repevent
|
from py.__.test import repevent
|
||||||
from py.__.test.rsession.local import box_runner, plain_runner, apigen_runner
|
from py.__.test.rsession.local import box_runner, plain_runner, apigen_runner
|
||||||
|
import py.__.test.custompdb
|
||||||
|
|
||||||
def setup_module(mod):
|
def setup_module(mod):
|
||||||
mod.tmp = py.test.ensuretemp("lsession_module")
|
mod.tmp = py.test.ensuretemp("lsession_module")
|
||||||
|
@ -78,14 +79,13 @@ class TestLSession(object):
|
||||||
def test_1():
|
def test_1():
|
||||||
assert 0
|
assert 0
|
||||||
"""))
|
"""))
|
||||||
import pdb
|
|
||||||
l = []
|
l = []
|
||||||
def some_fun(*args):
|
def some_fun(*args):
|
||||||
l.append(args)
|
l.append(args)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
post_mortem = pdb.post_mortem
|
post_mortem = py.__.test.custompdb.post_mortem
|
||||||
pdb.post_mortem = some_fun
|
py.__.test.custompdb.post_mortem = some_fun
|
||||||
args = [str(tmpdir.join(subdir)), '--pdb']
|
args = [str(tmpdir.join(subdir)), '--pdb']
|
||||||
config = py.test.config._reparse(args)
|
config = py.test.config._reparse(args)
|
||||||
lsession = LSession(config)
|
lsession = LSession(config)
|
||||||
|
@ -101,7 +101,7 @@ class TestLSession(object):
|
||||||
assert len(failure_events) == 1
|
assert len(failure_events) == 1
|
||||||
assert len(l) == 1
|
assert len(l) == 1
|
||||||
finally:
|
finally:
|
||||||
pdb.post_mortem = post_mortem
|
py.__.test.custompdb.post_mortem = post_mortem
|
||||||
|
|
||||||
def test_minus_x(self):
|
def test_minus_x(self):
|
||||||
if not hasattr(py.std.os, 'fork'):
|
if not hasattr(py.std.os, 'fork'):
|
||||||
|
|
|
@ -4,6 +4,7 @@ from time import time as now
|
||||||
from py.__.test.terminal.out import getout
|
from py.__.test.terminal.out import getout
|
||||||
from py.__.test.representation import Presenter
|
from py.__.test.representation import Presenter
|
||||||
from py.__.test.outcome import Skipped, Passed, Failed
|
from py.__.test.outcome import Skipped, Passed, Failed
|
||||||
|
import py.__.test.custompdb
|
||||||
|
|
||||||
def getrelpath(source, dest):
|
def getrelpath(source, dest):
|
||||||
base = source.common(dest)
|
base = source.common(dest)
|
||||||
|
@ -97,9 +98,8 @@ class TerminalSession(Session):
|
||||||
if isinstance(outcome, Failed):
|
if isinstance(outcome, Failed):
|
||||||
print "dispatching to ppdb", colitem
|
print "dispatching to ppdb", colitem
|
||||||
self.repr_failure(colitem, outcome)
|
self.repr_failure(colitem, outcome)
|
||||||
import pdb
|
|
||||||
self.out.write('\n%s\n' % (outcome.excinfo.exconly(),))
|
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):
|
if isinstance(colitem, py.test.collect.Module):
|
||||||
resultstring = self.repr_progress_module_result(colitem, outcome)
|
resultstring = self.repr_progress_module_result(colitem, outcome)
|
||||||
if resultstring:
|
if resultstring:
|
||||||
|
|
Loading…
Reference in New Issue