aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'py/_code/code.py')
-rw-r--r--py/_code/code.py73
1 files changed, 43 insertions, 30 deletions
diff --git a/py/_code/code.py b/py/_code/code.py
index aa60da8017..f14c562a29 100644
--- a/py/_code/code.py
+++ b/py/_code/code.py
@@ -133,12 +133,17 @@ class Frame(object):
class TracebackEntry(object):
""" a single entry in a traceback """
+ _repr_style = None
exprinfo = None
def __init__(self, rawentry):
self._rawentry = rawentry
self.lineno = rawentry.tb_lineno - 1
+ def set_repr_style(self, mode):
+ assert mode in ("short", "long")
+ self._repr_style = mode
+
@property
def frame(self):
return py.code.Frame(self._rawentry.tb_frame)
@@ -465,22 +470,22 @@ class FormattedExcinfo(object):
def get_source(self, source, line_index=-1, excinfo=None, short=False):
""" return formatted and marked up source lines. """
lines = []
- if source is None:
+ if source is None or line_index >= len(source.lines):
source = py.code.Source("???")
line_index = 0
if line_index < 0:
line_index += len(source)
- for i in range(len(source)):
- if i == line_index:
- prefix = self.flow_marker + " "
- else:
- if short:
- continue
- prefix = " "
- line = prefix + source[i]
- lines.append(line)
+ space_prefix = " "
+ if short:
+ lines.append(space_prefix + source.lines[line_index].strip())
+ else:
+ for line in source.lines[:line_index]:
+ lines.append(space_prefix + line)
+ lines.append(self.flow_marker + " " + source.lines[line_index])
+ for line in source.lines[line_index+1:]:
+ lines.append(space_prefix + line)
if excinfo is not None:
- indent = self._getindent(source)
+ indent = 4 if short else self._getindent(source)
lines.extend(self.get_exconly(excinfo, indent=indent, markall=True))
return lines
@@ -520,7 +525,6 @@ class FormattedExcinfo(object):
return ReprLocals(lines)
def repr_traceback_entry(self, entry, excinfo=None):
- # excinfo is not None if this is the last tb entry
source = self._getentrysource(entry)
if source is None:
source = py.code.Source("???")
@@ -530,11 +534,12 @@ class FormattedExcinfo(object):
line_index = entry.lineno - max(entry.getfirstlinesource(), 0)
lines = []
- if self.style in ("short", "long"):
- short = self.style == "short"
- reprargs = None
- if not short:
- reprargs = self.repr_args(entry)
+ style = entry._repr_style
+ if style is None:
+ style = self.style
+ if style in ("short", "long"):
+ short = style == "short"
+ reprargs = self.repr_args(entry) if not short else None
s = self.get_source(source, line_index, excinfo, short=short)
lines.extend(s)
if short:
@@ -546,10 +551,10 @@ class FormattedExcinfo(object):
localsrepr = None
if not short:
localsrepr = self.repr_locals(entry.locals)
- return ReprEntry(lines, reprargs, localsrepr, filelocrepr, short)
+ return ReprEntry(lines, reprargs, localsrepr, filelocrepr, style)
if excinfo:
lines.extend(self.get_exconly(excinfo, indent=4))
- return ReprEntry(lines, None, None, None, False)
+ return ReprEntry(lines, None, None, None, style)
def _makepath(self, path):
if not self.abspath:
@@ -567,7 +572,8 @@ class FormattedExcinfo(object):
traceback = traceback.filter()
recursionindex = None
if excinfo.errisinstance(RuntimeError):
- recursionindex = traceback.recursionindex()
+ if "maximum recursion depth exceeded" in str(excinfo.value):
+ recursionindex = traceback.recursionindex()
last = traceback[-1]
entries = []
extraline = None
@@ -628,14 +634,18 @@ class ReprTraceback(TerminalRepr):
self.style = style
def toterminal(self, tw):
- sepok = False
- for entry in self.reprentries:
- if self.style == "long":
- if sepok:
- tw.sep(self.entrysep)
+ # the entries might have different styles
+ last_style = None
+ for i, entry in enumerate(self.reprentries):
+ if entry.style == "long":
tw.line("")
- sepok = True
entry.toterminal(tw)
+ if i < len(self.reprentries) - 1:
+ next_entry = self.reprentries[i+1]
+ if entry.style == "long" or \
+ entry.style == "short" and next_entry.style == "long":
+ tw.sep(self.entrysep)
+
if self.extraline:
tw.line(self.extraline)
@@ -646,6 +656,8 @@ class ReprTracebackNative(ReprTraceback):
self.extraline = None
class ReprEntryNative(TerminalRepr):
+ style = "native"
+
def __init__(self, tblines):
self.lines = tblines
@@ -655,15 +667,15 @@ class ReprEntryNative(TerminalRepr):
class ReprEntry(TerminalRepr):
localssep = "_ "
- def __init__(self, lines, reprfuncargs, reprlocals, filelocrepr, short):
+ def __init__(self, lines, reprfuncargs, reprlocals, filelocrepr, style):
self.lines = lines
self.reprfuncargs = reprfuncargs
self.reprlocals = reprlocals
self.reprfileloc = filelocrepr
- self.short = short
+ self.style = style
def toterminal(self, tw):
- if self.short:
+ if self.style == "short":
self.reprfileloc.toterminal(tw)
for line in self.lines:
red = line.startswith("E ")
@@ -680,7 +692,8 @@ class ReprEntry(TerminalRepr):
tw.line("")
self.reprlocals.toterminal(tw)
if self.reprfileloc:
- tw.line("")
+ if self.lines:
+ tw.line("")
self.reprfileloc.toterminal(tw)
def __str__(self):