Merge pull request #7708 from nicoddemus/repr-line-7707

Fix handle of exceptions in ReprEntry with tb=line
This commit is contained in:
Bruno Oliveira 2020-09-04 12:06:11 -03:00 committed by GitHub
commit 0d0b798663
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 31 deletions

View File

@ -0,0 +1 @@
Fix internal error when handling some exceptions that contain multiple lines or the style uses multiple lines (``--tb=line`` for example).

View File

@ -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)

View File

@ -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)