From c83aafe4d3ebbc5a82c4ae9a061f5a44e7251208 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jim=20Br=C3=A4nnlund?= Date: Fri, 3 Mar 2023 20:57:06 +0100 Subject: [PATCH] changes based on PR comments --- doc/en/how-to/tmp_path.rst | 2 +- doc/en/reference/reference.rst | 2 +- src/_pytest/pathlib.py | 9 ++++++--- src/_pytest/pytester.py | 7 +++---- src/_pytest/tmpdir.py | 15 +++++++-------- testing/test_tmpdir.py | 2 +- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/doc/en/how-to/tmp_path.rst b/doc/en/how-to/tmp_path.rst index a58c1eb97..0a5f9ac9f 100644 --- a/doc/en/how-to/tmp_path.rst +++ b/doc/en/how-to/tmp_path.rst @@ -163,7 +163,7 @@ File permissions Any file or directory created by the above fixtures are by default created with private permissions (file mask 700). -You can override the file mask by setting the :envvar:`PYTEST_TMPDIR_FILE_MODE` environment variable as an octal string, the default being `0o700`. +You can override the file mask by setting the :envvar:`PYTEST_TMPDIR_FILE_MODE` environment variable as an octal string, the default being `700`. This is for example useful in cases where created files or directories have to be shared by docker containers etc. diff --git a/doc/en/reference/reference.rst b/doc/en/reference/reference.rst index 41ff4acbe..0c6e51747 100644 --- a/doc/en/reference/reference.rst +++ b/doc/en/reference/reference.rst @@ -1092,7 +1092,7 @@ Sets the :envvar:`PYTEST_THEME` to be either *dark* or *light*. .. envvar:: PYTEST_TMPDIR_FILE_MODE -Sets the file mode of any temporary files or directories. Defaults to `0o700`. See :fixture:`tmp_path` :fixture:`tmp_path_factory`. +Sets the file mode of any temporary files or directories. Defaults to `700`. See :fixture:`tmp_path` :fixture:`tmp_path_factory`. .. envvar:: PY_COLORS diff --git a/src/_pytest/pathlib.py b/src/_pytest/pathlib.py index 065ddebc4..bc9a4d1c3 100644 --- a/src/_pytest/pathlib.py +++ b/src/_pytest/pathlib.py @@ -51,8 +51,6 @@ _IGNORED_WINERRORS = ( 1921, # ERROR_CANT_RESOLVE_FILENAME - fix for broken symlink pointing to itself ) -TMPDIR_FILE_MODE = int(os.getenv("PYTEST_TMPDIR_FILE_MODE", "0o700"), 8) - def _ignore_error(exception): return ( @@ -208,8 +206,9 @@ def _force_symlink( pass -def make_numbered_dir(root: Path, prefix: str, mode: int = TMPDIR_FILE_MODE) -> Path: +def make_numbered_dir(root: Path, prefix: str, mode: Union[int, None] = None) -> Path: """Create a directory with an increased number as suffix for the given prefix.""" + mode = mode or tmpdir_file_mode() for i in range(10): # try up to 10 times to create the folder max_existing = max(map(parse_num, find_suffixes(root, prefix)), default=-1) @@ -748,3 +747,7 @@ def copytree(source: Path, target: Path) -> None: shutil.copyfile(x, newx) elif x.is_dir(): newx.mkdir(exist_ok=True) + + +def tmpdir_file_mode() -> int: + return int(os.getenv("PYTEST_TMPDIR_FILE_MODE", "700"), 8) diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index a9f15d4eb..b6960251d 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -62,6 +62,7 @@ from _pytest.outcomes import skip from _pytest.pathlib import bestrelpath from _pytest.pathlib import copytree from _pytest.pathlib import make_numbered_dir +from _pytest.pathlib import tmpdir_file_mode from _pytest.reports import CollectReport from _pytest.reports import TestReport from _pytest.tmpdir import TempPathFactory @@ -82,8 +83,6 @@ IGNORE_PAM = [ # filenames added when obtaining details about the current user "/var/lib/sss/mc/passwd" ] -TMPDIR_FILE_MODE = int(os.getenv("PYTEST_TMPDIR_FILE_MODE", "0o700"), 8) - def pytest_addoption(parser: Parser) -> None: parser.addoption( @@ -1505,7 +1504,7 @@ class Pytester: """ __tracebackhide__ = True p = make_numbered_dir( - root=self.path, prefix="runpytest-", mode=TMPDIR_FILE_MODE + root=self.path, prefix="runpytest-", mode=tmpdir_file_mode() ) args = ("--basetemp=%s" % p,) + args plugins = [x for x in self.plugins if isinstance(x, str)] @@ -1525,7 +1524,7 @@ class Pytester: The pexpect child is returned. """ basetemp = self.path / "temp-pexpect" - basetemp.mkdir(mode=TMPDIR_FILE_MODE) + basetemp.mkdir(mode=tmpdir_file_mode()) invoke = " ".join(map(str, self._getpytestargs())) cmd = f"{invoke} --basetemp={basetemp} {string}" return self.spawn(cmd, expect_timeout=expect_timeout) diff --git a/src/_pytest/tmpdir.py b/src/_pytest/tmpdir.py index 0a50200ee..959549ddf 100644 --- a/src/_pytest/tmpdir.py +++ b/src/_pytest/tmpdir.py @@ -30,6 +30,7 @@ from .pathlib import make_numbered_dir from .pathlib import make_numbered_dir_with_cleanup from .pathlib import rm_rf from .pathlib import cleanup_dead_symlink +from .pathlib import tmpdir_file_mode from _pytest.compat import final from _pytest.config import Config from _pytest.config import ExitCode @@ -41,8 +42,6 @@ from _pytest.monkeypatch import MonkeyPatch tmppath_result_key = StashKey[Dict[str, bool]]() -TMPDIR_FILE_MODE = int(os.getenv("PYTEST_TMPDIR_FILE_MODE", "0o700"), 8) - @final @dataclasses.dataclass @@ -138,10 +137,10 @@ class TempPathFactory: basename = self._ensure_relative_to_basetemp(basename) if not numbered: p = self.getbasetemp().joinpath(basename) - p.mkdir(mode=TMPDIR_FILE_MODE) + p.mkdir(mode=tmpdir_file_mode()) else: p = make_numbered_dir( - root=self.getbasetemp(), prefix=basename, mode=TMPDIR_FILE_MODE + root=self.getbasetemp(), prefix=basename, mode=tmpdir_file_mode() ) self._trace("mktemp", p) return p @@ -159,7 +158,7 @@ class TempPathFactory: basetemp = self._given_basetemp if basetemp.exists(): rm_rf(basetemp) - basetemp.mkdir(mode=TMPDIR_FILE_MODE) + basetemp.mkdir(mode=tmpdir_file_mode()) basetemp = basetemp.resolve() else: from_env = os.environ.get("PYTEST_DEBUG_TEMPROOT") @@ -169,11 +168,11 @@ class TempPathFactory: # make_numbered_dir() call rootdir = temproot.joinpath(f"pytest-of-{user}") try: - rootdir.mkdir(mode=TMPDIR_FILE_MODE, exist_ok=True) + rootdir.mkdir(mode=tmpdir_file_mode(), exist_ok=True) except OSError: # getuser() likely returned illegal characters for the platform, use unknown back off mechanism rootdir = temproot.joinpath("pytest-of-unknown") - rootdir.mkdir(mode=TMPDIR_FILE_MODE, exist_ok=True) + rootdir.mkdir(mode=tmpdir_file_mode(), exist_ok=True) # Because we use exist_ok=True with a predictable name, make sure # we are the owners, to prevent any funny business (on unix, where # temproot is usually shared). @@ -201,7 +200,7 @@ class TempPathFactory: root=rootdir, keep=keep, lock_timeout=LOCK_TIMEOUT, - mode=TMPDIR_FILE_MODE, + mode=tmpdir_file_mode(), ) assert basetemp is not None, basetemp self._basetemp = basetemp diff --git a/testing/test_tmpdir.py b/testing/test_tmpdir.py index 8b34985ec..bcede3613 100644 --- a/testing/test_tmpdir.py +++ b/testing/test_tmpdir.py @@ -631,7 +631,7 @@ def test_tmp_path_factory_user_specified_permissions( """Verify that pytest creates directories under /tmp with user specified permissions.""" # Use the test's tmp_path as the system temproot (/tmp). monkeypatch.setenv("PYTEST_DEBUG_TEMPROOT", str(tmp_path)) - monkeypatch.setenv("PYTEST_TMPDIR_FILE_MODE", "0o777") + monkeypatch.setenv("PYTEST_TMPDIR_FILE_MODE", "777") tmp_factory = TempPathFactory(None, 3, "all", lambda *args: None, _ispytest=True) basetemp = tmp_factory.getbasetemp()