Skip to content

Commit 4c53909

Browse files
committed
Highlight the path of file location in error report
So that it's more obvious when we need to copy the file path.
1 parent ffb583a commit 4c53909

File tree

4 files changed

+73
-39
lines changed

4 files changed

+73
-39
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,4 @@ Trevor Bekolay
101101
Wouter van Ackooy
102102
Bernard Pratz
103103
Javier Romero
104+
Xuecong Liao

CHANGELOG.rst

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
2.9.3.dev
22
=========
33

4+
* Highlight path of the file location in the error report.
5+
46
**Bug Fixes**
57

68
* Add an 'E' to the first line of error messages from FixtureLookupErrorRepr.

_pytest/_code/code.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,8 @@ def toterminal(self, tw):
723723
i = msg.find("\n")
724724
if i != -1:
725725
msg = msg[:i]
726-
tw.line("%s:%s: %s" %(self.path, self.lineno, msg))
726+
tw.write(self.path, bold=True, red=True)
727+
tw.line(":%s: %s" % (self.lineno, msg))
727728

728729
class ReprLocals(TerminalRepr):
729730
def __init__(self, lines):

testing/code/test_excinfo.py

+68-38
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,23 @@
2121
pytest_version_info = tuple(map(int, pytest.__version__.split(".")[:3]))
2222

2323
class TWMock:
24+
WRITE = object()
25+
2426
def __init__(self):
2527
self.lines = []
28+
self.is_writing = False
2629
def sep(self, sep, line=None):
2730
self.lines.append((sep, line))
31+
def write(self, msg, **kw):
32+
self.lines.append((TWMock.WRITE, msg))
2833
def line(self, line, **kw):
2934
self.lines.append(line)
3035
def markup(self, text, **kw):
3136
return text
37+
def get_write_msg(self, idx):
38+
flag, msg = self.lines[idx]
39+
assert flag == TWMock.WRITE
40+
return msg
3241

3342
fullwidth = 80
3443

@@ -755,14 +764,18 @@ def f():
755764
assert tw.lines[0] == " def f():"
756765
assert tw.lines[1] == "> g(3)"
757766
assert tw.lines[2] == ""
758-
assert tw.lines[3].endswith("mod.py:5: ")
759-
assert tw.lines[4] == ("_ ", None)
760-
assert tw.lines[5] == ""
761-
assert tw.lines[6] == " def g(x):"
762-
assert tw.lines[7] == "> raise ValueError(x)"
763-
assert tw.lines[8] == "E ValueError: 3"
764-
assert tw.lines[9] == ""
765-
assert tw.lines[10].endswith("mod.py:3: ValueError")
767+
line = tw.get_write_msg(3)
768+
assert line.endswith("mod.py")
769+
assert tw.lines[4] == (":5: ")
770+
assert tw.lines[5] == ("_ ", None)
771+
assert tw.lines[6] == ""
772+
assert tw.lines[7] == " def g(x):"
773+
assert tw.lines[8] == "> raise ValueError(x)"
774+
assert tw.lines[9] == "E ValueError: 3"
775+
assert tw.lines[10] == ""
776+
line = tw.get_write_msg(11)
777+
assert line.endswith("mod.py")
778+
assert tw.lines[12] == ":3: ValueError"
766779

767780
def test_toterminal_long_missing_source(self, importasmod, tmpdir):
768781
mod = importasmod("""
@@ -781,13 +794,17 @@ def f():
781794
tw.lines.pop(0)
782795
assert tw.lines[0] == "> ???"
783796
assert tw.lines[1] == ""
784-
assert tw.lines[2].endswith("mod.py:5: ")
785-
assert tw.lines[3] == ("_ ", None)
786-
assert tw.lines[4] == ""
787-
assert tw.lines[5] == "> ???"
788-
assert tw.lines[6] == "E ValueError: 3"
789-
assert tw.lines[7] == ""
790-
assert tw.lines[8].endswith("mod.py:3: ValueError")
797+
line = tw.get_write_msg(2)
798+
assert line.endswith("mod.py")
799+
assert tw.lines[3] == ":5: "
800+
assert tw.lines[4] == ("_ ", None)
801+
assert tw.lines[5] == ""
802+
assert tw.lines[6] == "> ???"
803+
assert tw.lines[7] == "E ValueError: 3"
804+
assert tw.lines[8] == ""
805+
line = tw.get_write_msg(9)
806+
assert line.endswith("mod.py")
807+
assert tw.lines[10] == ":3: ValueError"
791808

792809
def test_toterminal_long_incomplete_source(self, importasmod, tmpdir):
793810
mod = importasmod("""
@@ -806,13 +823,17 @@ def f():
806823
tw.lines.pop(0)
807824
assert tw.lines[0] == "> ???"
808825
assert tw.lines[1] == ""
809-
assert tw.lines[2].endswith("mod.py:5: ")
810-
assert tw.lines[3] == ("_ ", None)
811-
assert tw.lines[4] == ""
812-
assert tw.lines[5] == "> ???"
813-
assert tw.lines[6] == "E ValueError: 3"
814-
assert tw.lines[7] == ""
815-
assert tw.lines[8].endswith("mod.py:3: ValueError")
826+
line = tw.get_write_msg(2)
827+
assert line.endswith("mod.py")
828+
assert tw.lines[3] == ":5: "
829+
assert tw.lines[4] == ("_ ", None)
830+
assert tw.lines[5] == ""
831+
assert tw.lines[6] == "> ???"
832+
assert tw.lines[7] == "E ValueError: 3"
833+
assert tw.lines[8] == ""
834+
line = tw.get_write_msg(9)
835+
assert line.endswith("mod.py")
836+
assert tw.lines[10] == ":3: ValueError"
816837

817838
def test_toterminal_long_filenames(self, importasmod):
818839
mod = importasmod("""
@@ -826,15 +847,18 @@ def f():
826847
try:
827848
repr = excinfo.getrepr(abspath=False)
828849
repr.toterminal(tw)
829-
line = tw.lines[-1]
830850
x = py.path.local().bestrelpath(path)
831851
if len(x) < len(str(path)):
832-
assert line == "mod.py:3: ValueError"
852+
msg = tw.get_write_msg(-2)
853+
assert msg == "mod.py"
854+
assert tw.lines[-1] == ":3: ValueError"
833855

834856
repr = excinfo.getrepr(abspath=True)
835857
repr.toterminal(tw)
858+
msg = tw.get_write_msg(-2)
859+
assert msg == path
836860
line = tw.lines[-1]
837-
assert line == "%s:3: ValueError" %(path,)
861+
assert line == ":3: ValueError"
838862
finally:
839863
old.chdir()
840864

@@ -896,19 +920,25 @@ def i():
896920
assert tw.lines[1] == " def f():"
897921
assert tw.lines[2] == "> g()"
898922
assert tw.lines[3] == ""
899-
assert tw.lines[4].endswith("mod.py:3: ")
900-
assert tw.lines[5] == ("_ ", None)
901-
assert tw.lines[6].endswith("in g")
902-
assert tw.lines[7] == " h()"
903-
assert tw.lines[8].endswith("in h")
904-
assert tw.lines[9] == " i()"
905-
assert tw.lines[10] == ("_ ", None)
906-
assert tw.lines[11] == ""
907-
assert tw.lines[12] == " def i():"
908-
assert tw.lines[13] == "> raise ValueError()"
909-
assert tw.lines[14] == "E ValueError"
910-
assert tw.lines[15] == ""
911-
assert tw.lines[16].endswith("mod.py:9: ValueError")
923+
msg = tw.get_write_msg(4)
924+
assert msg.endswith("mod.py")
925+
assert tw.lines[5] == ":3: "
926+
assert tw.lines[6] == ("_ ", None)
927+
tw.get_write_msg(7)
928+
assert tw.lines[8].endswith("in g")
929+
assert tw.lines[9] == " h()"
930+
tw.get_write_msg(10)
931+
assert tw.lines[11].endswith("in h")
932+
assert tw.lines[12] == " i()"
933+
assert tw.lines[13] == ("_ ", None)
934+
assert tw.lines[14] == ""
935+
assert tw.lines[15] == " def i():"
936+
assert tw.lines[16] == "> raise ValueError()"
937+
assert tw.lines[17] == "E ValueError"
938+
assert tw.lines[18] == ""
939+
msg = tw.get_write_msg(19)
940+
msg.endswith("mod.py")
941+
assert tw.lines[20] == ":9: ValueError"
912942

913943

914944
@pytest.mark.parametrize("style", ["short", "long"])

0 commit comments

Comments
 (0)