Skip to content

Commit 589176e

Browse files
authored
Merge pull request #7285 from nicoddemus/backport-7220
[5.4] Merge pull request #7220 from nicoddemus/issue-6428
2 parents 3734a27 + e1a21e4 commit 589176e

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

changelog/6428.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Paths appearing in error messages are now correct in case the current working directory has
2+
changed since the start of the session.

src/_pytest/nodes.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from _pytest.mark.structures import MarkDecorator
3030
from _pytest.mark.structures import NodeKeywords
3131
from _pytest.outcomes import fail
32+
from _pytest.pathlib import Path
3233
from _pytest.store import Store
3334

3435
if TYPE_CHECKING:
@@ -348,9 +349,14 @@ def _repr_failure_py(
348349
else:
349350
truncate_locals = True
350351

352+
# excinfo.getrepr() formats paths relative to the CWD if `abspath` is False.
353+
# It is possible for a fixture/test to change the CWD while this code runs, which
354+
# would then result in the user seeing confusing paths in the failure message.
355+
# To fix this, if the CWD changed, always display the full absolute path.
356+
# It will be better to just always display paths relative to invocation_dir, but
357+
# this requires a lot of plumbing (#6428).
351358
try:
352-
os.getcwd()
353-
abspath = False
359+
abspath = Path(os.getcwd()) != Path(self.config.invocation_dir)
354360
except OSError:
355361
abspath = True
356362

testing/test_nodes.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,30 @@ class FakeSession:
5858

5959
outside = py.path.local("/outside")
6060
assert nodes._check_initialpaths_for_relpath(FakeSession, outside) is None
61+
62+
63+
def test_failure_with_changed_cwd(testdir):
64+
"""
65+
Test failure lines should use absolute paths if cwd has changed since
66+
invocation, so the path is correct (#6428).
67+
"""
68+
p = testdir.makepyfile(
69+
"""
70+
import os
71+
import pytest
72+
73+
@pytest.fixture
74+
def private_dir():
75+
out_dir = 'ddd'
76+
os.mkdir(out_dir)
77+
old_dir = os.getcwd()
78+
os.chdir(out_dir)
79+
yield out_dir
80+
os.chdir(old_dir)
81+
82+
def test_show_wrong_path(private_dir):
83+
assert False
84+
"""
85+
)
86+
result = testdir.runpytest()
87+
result.stdout.fnmatch_lines([str(p) + ":*: AssertionError", "*1 failed in *"])

0 commit comments

Comments
 (0)