Skip to content

Commit 330c45f

Browse files
committed
Fix issue where working dir becomes wrong on subst drive on Windows. Fixes #5965
1 parent a52f791 commit 330c45f

File tree

3 files changed

+98
-2
lines changed

3 files changed

+98
-2
lines changed

changelog/5965.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
No longer resolve symlinks so that the current directory remains correct even with drives mapped with subst on Windows.

src/_pytest/config/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def get_config(args=None, plugins=None):
177177
config = Config(
178178
pluginmanager,
179179
invocation_params=Config.InvocationParams(
180-
args=args or (), plugins=plugins, dir=Path().resolve()
180+
args=args or (), plugins=plugins, dir=Path().absolute()
181181
),
182182
)
183183

@@ -736,7 +736,7 @@ def __init__(self, pluginmanager, *, invocation_params=None):
736736

737737
if invocation_params is None:
738738
invocation_params = self.InvocationParams(
739-
args=(), plugins=None, dir=Path().resolve()
739+
args=(), plugins=None, dir=Path().absolute()
740740
)
741741

742742
self.option = argparse.Namespace()

testing/test_windows_subst.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import os.path
2+
import subprocess
3+
import sys
4+
from string import ascii_lowercase
5+
6+
from py._path.local import LocalPath
7+
8+
import pytest
9+
from _pytest import pytester
10+
from _pytest.fixtures import FixtureRequest
11+
12+
13+
class _SubstTmpdirFactory:
14+
"""
15+
A temp dir factory which may do a subst on Windows drives.
16+
"""
17+
18+
def __init__(self, tmpdir, tmpdir_factory, subst):
19+
self.tmpdir = tmpdir
20+
self.tmpdir_factory = tmpdir_factory
21+
self.subst = subst
22+
self.subst_drives = {}
23+
24+
def _subst_path(self, filename):
25+
26+
if self.subst:
27+
for c in ascii_lowercase[7:]: # Create a subst drive from H-Z.
28+
c += ":"
29+
if not os.path.exists(c):
30+
drive = c
31+
break
32+
else:
33+
raise AssertionError("Unable to find suitable drive letter for subst.")
34+
35+
directory = os.path.dirname(filename)
36+
basename = os.path.basename(filename)
37+
38+
args = ["subst", drive, directory]
39+
subprocess.check_call(args)
40+
assert os.path.exists(drive)
41+
self.subst_drives[drive] = directory
42+
43+
filename = LocalPath(os.path.join(drive, basename))
44+
45+
return filename
46+
47+
def mktemp(self, name, numbered):
48+
filename = self.tmpdir_factory.mktemp(name, numbered=numbered)
49+
filename = self._subst_path(filename)
50+
return filename
51+
52+
def unsubst(self):
53+
for drive in self.subst_drives:
54+
args = ["subst", "/D", drive]
55+
subprocess.check_call(args)
56+
57+
58+
@pytest.fixture(params=[{"subst": True}, {"subst": False}])
59+
def _subst_tmpdir_factory(request: FixtureRequest, tmpdir, tmpdir_factory):
60+
if sys.platform != "win32":
61+
pytest.skip("Windows only test.")
62+
factory = _SubstTmpdirFactory(tmpdir, tmpdir_factory, **request.param)
63+
yield factory
64+
factory.unsubst()
65+
66+
67+
@pytest.fixture
68+
def _custom_testdir(
69+
request: FixtureRequest, _subst_tmpdir_factory
70+
) -> "pytester.Testdir":
71+
return pytester.Testdir(request, _subst_tmpdir_factory)
72+
73+
74+
def test_windows_subst_resolve(_custom_testdir, _subst_tmpdir_factory) -> None:
75+
"""
76+
Check that when we have a subst on Windows the errors reported are not
77+
in the subst target.
78+
See: https://github.com/pytest-dev/pytest/issues/5965
79+
"""
80+
testdir = _custom_testdir
81+
testdir.makepyfile(
82+
"""
83+
import pytest
84+
def test_foo():
85+
raise AssertionError()
86+
"""
87+
)
88+
result = testdir.runpytest()
89+
90+
# i.e.: Make sure that the error is reported as a relative path, not as an
91+
# absolute (resolved) path.
92+
# See: https://github.com/pytest-dev/pytest/issues/5965
93+
for _drive, directory in _subst_tmpdir_factory.subst_drives.items():
94+
for line in result.stdout.lines:
95+
assert directory.lower() not in line.lower()

0 commit comments

Comments
 (0)