diff --git a/changelog/4425.bugfix.rst b/changelog/4425.bugfix.rst new file mode 100644 index 000000000..7c869cd4c --- /dev/null +++ b/changelog/4425.bugfix.rst @@ -0,0 +1 @@ +Ensure we resolve the absolute path when the given ``--basetemp`` is a relative path. diff --git a/src/_pytest/monkeypatch.py b/src/_pytest/monkeypatch.py index d536b7746..2c81de177 100644 --- a/src/_pytest/monkeypatch.py +++ b/src/_pytest/monkeypatch.py @@ -13,8 +13,9 @@ import six import pytest from _pytest.fixtures import fixture +from _pytest.pathlib import Path -RE_IMPORT_ERROR_NAME = re.compile("^No module named (.*)$") +RE_IMPORT_ERROR_NAME = re.compile(r"^No module named (.*)$") @fixture @@ -267,6 +268,9 @@ class MonkeyPatch(object): self._cwd = os.getcwd() if hasattr(path, "chdir"): path.chdir() + elif isinstance(path, Path): + # modern python uses the fspath protocol here LEGACY + os.chdir(str(path)) else: os.chdir(path) diff --git a/src/_pytest/tmpdir.py b/src/_pytest/tmpdir.py index 6287c1705..81430e4f0 100644 --- a/src/_pytest/tmpdir.py +++ b/src/_pytest/tmpdir.py @@ -26,7 +26,9 @@ class TempPathFactory(object): The base directory can be configured using the ``--basetemp`` option.""" - _given_basetemp = attr.ib() + _given_basetemp = attr.ib( + convert=attr.converters.optional(lambda p: Path(p).resolve()) + ) _trace = attr.ib() _basetemp = attr.ib(default=None) @@ -53,7 +55,7 @@ class TempPathFactory(object): """ return base temporary directory. """ if self._basetemp is None: if self._given_basetemp is not None: - basetemp = Path(self._given_basetemp) + basetemp = self._given_basetemp ensure_reset_dir(basetemp) else: from_env = os.environ.get("PYTEST_DEBUG_TEMPROOT") diff --git a/testing/test_tmpdir.py b/testing/test_tmpdir.py index 38b0672b7..fddece2cf 100644 --- a/testing/test_tmpdir.py +++ b/testing/test_tmpdir.py @@ -4,6 +4,7 @@ from __future__ import print_function import sys +import attr import six import pytest @@ -25,12 +26,29 @@ def test_ensuretemp(recwarn): assert d1.check(dir=1) +@attr.s +class FakeConfig(object): + basetemp = attr.ib() + trace = attr.ib(default=None) + + @property + def trace(self): + return self + + def get(self, key): + return lambda *k: None + + @property + def option(self): + return self + + class TestTempdirHandler(object): - def test_mktemp(self, testdir): + def test_mktemp(self, tmp_path): + from _pytest.tmpdir import TempdirFactory, TempPathFactory - config = testdir.parseconfig() - config.option.basetemp = testdir.mkdir("hello") + config = FakeConfig(tmp_path) t = TempdirFactory(TempPathFactory.from_config(config)) tmp = t.mktemp("world") assert tmp.relto(t.getbasetemp()) == "world0" @@ -40,6 +58,15 @@ class TestTempdirHandler(object): assert tmp2.relto(t.getbasetemp()).startswith("this") assert tmp2 != tmp + @pytest.mark.issue(4425) + def test_tmppath_relative_basetemp_absolute(self, tmp_path, monkeypatch): + from _pytest.tmpdir import TempPathFactory + + monkeypatch.chdir(tmp_path) + config = FakeConfig("hello") + t = TempPathFactory.from_config(config) + assert t.getbasetemp() == (tmp_path / "hello") + class TestConfigTmpdir(object): def test_getbasetemp_custom_removes_old(self, testdir):