Merge pull request #7708 from nicoddemus/repr-line-7707
Fix handle of exceptions in ReprEntry with tb=line
This commit is contained in:
commit
0d0b798663
|
@ -0,0 +1 @@
|
||||||
|
Fix internal error when handling some exceptions that contain multiple lines or the style uses multiple lines (``--tb=line`` for example).
|
|
@ -1049,25 +1049,21 @@ class ReprEntry(TerminalRepr):
|
||||||
# such as "> assert 0"
|
# such as "> assert 0"
|
||||||
fail_marker = "{} ".format(FormattedExcinfo.fail_marker)
|
fail_marker = "{} ".format(FormattedExcinfo.fail_marker)
|
||||||
indent_size = len(fail_marker)
|
indent_size = len(fail_marker)
|
||||||
indents = []
|
indents = [] # type: List[str]
|
||||||
source_lines = []
|
source_lines = [] # type: List[str]
|
||||||
failure_lines = []
|
failure_lines = [] # type: List[str]
|
||||||
seeing_failures = False
|
for index, line in enumerate(self.lines):
|
||||||
for line in self.lines:
|
is_failure_line = line.startswith(fail_marker)
|
||||||
is_source_line = not line.startswith(fail_marker)
|
if is_failure_line:
|
||||||
if is_source_line:
|
# from this point on all lines are considered part of the failure
|
||||||
assert not seeing_failures, (
|
failure_lines.extend(self.lines[index:])
|
||||||
"Unexpected failure lines between source lines:\n"
|
break
|
||||||
+ "\n".join(self.lines)
|
else:
|
||||||
)
|
|
||||||
if self.style == "value":
|
if self.style == "value":
|
||||||
source_lines.append(line)
|
source_lines.append(line)
|
||||||
else:
|
else:
|
||||||
indents.append(line[:indent_size])
|
indents.append(line[:indent_size])
|
||||||
source_lines.append(line[indent_size:])
|
source_lines.append(line[indent_size:])
|
||||||
else:
|
|
||||||
seeing_failures = True
|
|
||||||
failure_lines.append(line)
|
|
||||||
|
|
||||||
tw._write_source(source_lines, indents)
|
tw._write_source(source_lines, indents)
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ import os
|
||||||
import queue
|
import queue
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from typing import Any
|
||||||
|
from typing import Dict
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
|
@ -1045,28 +1047,34 @@ raise ValueError()
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"reproptions",
|
"reproptions",
|
||||||
[
|
[
|
||||||
{
|
pytest.param(
|
||||||
"style": style,
|
{
|
||||||
"showlocals": showlocals,
|
"style": style,
|
||||||
"funcargs": funcargs,
|
"showlocals": showlocals,
|
||||||
"tbfilter": tbfilter,
|
"funcargs": funcargs,
|
||||||
}
|
"tbfilter": tbfilter,
|
||||||
for style in ("long", "short", "no")
|
},
|
||||||
|
id="style={},showlocals={},funcargs={},tbfilter={}".format(
|
||||||
|
style, showlocals, funcargs, tbfilter
|
||||||
|
),
|
||||||
|
)
|
||||||
|
for style in ["long", "short", "line", "no", "native", "value", "auto"]
|
||||||
for showlocals in (True, False)
|
for showlocals in (True, False)
|
||||||
for tbfilter in (True, False)
|
for tbfilter in (True, False)
|
||||||
for funcargs in (True, False)
|
for funcargs in (True, False)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_format_excinfo(self, importasmod, reproptions):
|
def test_format_excinfo(self, reproptions: Dict[str, Any]) -> None:
|
||||||
mod = importasmod(
|
def bar():
|
||||||
"""
|
assert False, "some error"
|
||||||
def g(x):
|
|
||||||
raise ValueError(x)
|
def foo():
|
||||||
def f():
|
bar()
|
||||||
g(3)
|
|
||||||
"""
|
# using inline functions as opposed to importasmod so we get source code lines
|
||||||
)
|
# in the tracebacks (otherwise getinspect doesn't find the source code).
|
||||||
excinfo = pytest.raises(ValueError, mod.f)
|
with pytest.raises(AssertionError) as excinfo:
|
||||||
|
foo()
|
||||||
file = io.StringIO()
|
file = io.StringIO()
|
||||||
tw = TerminalWriter(file=file)
|
tw = TerminalWriter(file=file)
|
||||||
repr = excinfo.getrepr(**reproptions)
|
repr = excinfo.getrepr(**reproptions)
|
||||||
|
|
Loading…
Reference in New Issue