Skip to content

Commit

Permalink
Fix issue where working dir becomes wrong on subst drive on Windows. F…
Browse files Browse the repository at this point in the history
…ixes #5965
  • Loading branch information
fabioz committed Jan 21, 2020
1 parent a52f791 commit 330c45f
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 2 deletions.
1 change: 1 addition & 0 deletions changelog/5965.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
No longer resolve symlinks so that the current directory remains correct even with drives mapped with subst on Windows.
4 changes: 2 additions & 2 deletions src/_pytest/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def get_config(args=None, plugins=None):
config = Config(
pluginmanager,
invocation_params=Config.InvocationParams(
args=args or (), plugins=plugins, dir=Path().resolve()
args=args or (), plugins=plugins, dir=Path().absolute()
),
)

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

if invocation_params is None:
invocation_params = self.InvocationParams(
args=(), plugins=None, dir=Path().resolve()
args=(), plugins=None, dir=Path().absolute()
)

self.option = argparse.Namespace()
Expand Down
95 changes: 95 additions & 0 deletions testing/test_windows_subst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import os.path
import subprocess
import sys
from string import ascii_lowercase

from py._path.local import LocalPath

import pytest
from _pytest import pytester
from _pytest.fixtures import FixtureRequest


class _SubstTmpdirFactory:
"""
A temp dir factory which may do a subst on Windows drives.
"""

def __init__(self, tmpdir, tmpdir_factory, subst):
self.tmpdir = tmpdir
self.tmpdir_factory = tmpdir_factory
self.subst = subst
self.subst_drives = {}

def _subst_path(self, filename):

if self.subst:
for c in ascii_lowercase[7:]: # Create a subst drive from H-Z.
c += ":"
if not os.path.exists(c):
drive = c
break
else:
raise AssertionError("Unable to find suitable drive letter for subst.")

directory = os.path.dirname(filename)
basename = os.path.basename(filename)

args = ["subst", drive, directory]
subprocess.check_call(args)
assert os.path.exists(drive)
self.subst_drives[drive] = directory

filename = LocalPath(os.path.join(drive, basename))

return filename

def mktemp(self, name, numbered):
filename = self.tmpdir_factory.mktemp(name, numbered=numbered)
filename = self._subst_path(filename)
return filename

def unsubst(self):
for drive in self.subst_drives:
args = ["subst", "/D", drive]
subprocess.check_call(args)


@pytest.fixture(params=[{"subst": True}, {"subst": False}])
def _subst_tmpdir_factory(request: FixtureRequest, tmpdir, tmpdir_factory):
if sys.platform != "win32":
pytest.skip("Windows only test.")
factory = _SubstTmpdirFactory(tmpdir, tmpdir_factory, **request.param)
yield factory
factory.unsubst()


@pytest.fixture
def _custom_testdir(
request: FixtureRequest, _subst_tmpdir_factory
) -> "pytester.Testdir":
return pytester.Testdir(request, _subst_tmpdir_factory)


def test_windows_subst_resolve(_custom_testdir, _subst_tmpdir_factory) -> None:
"""
Check that when we have a subst on Windows the errors reported are not
in the subst target.
See: https://github.com/pytest-dev/pytest/issues/5965
"""
testdir = _custom_testdir
testdir.makepyfile(
"""
import pytest
def test_foo():
raise AssertionError()
"""
)
result = testdir.runpytest()

# i.e.: Make sure that the error is reported as a relative path, not as an
# absolute (resolved) path.
# See: https://github.com/pytest-dev/pytest/issues/5965
for _drive, directory in _subst_tmpdir_factory.subst_drives.items():
for line in result.stdout.lines:
assert directory.lower() not in line.lower()

0 comments on commit 330c45f

Please sign in to comment.