changes based on PR comments

This commit is contained in:
Jim Brännlund 2023-03-03 20:57:06 +01:00
parent 7237926323
commit c83aafe4d3
6 changed files with 19 additions and 18 deletions

View File

@ -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). 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. This is for example useful in cases where created files or directories have to be shared by docker containers etc.

View File

@ -1092,7 +1092,7 @@ Sets the :envvar:`PYTEST_THEME` to be either *dark* or *light*.
.. envvar:: PYTEST_TMPDIR_FILE_MODE .. 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 .. envvar:: PY_COLORS

View File

@ -51,8 +51,6 @@ _IGNORED_WINERRORS = (
1921, # ERROR_CANT_RESOLVE_FILENAME - fix for broken symlink pointing to itself 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): def _ignore_error(exception):
return ( return (
@ -208,8 +206,9 @@ def _force_symlink(
pass 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.""" """Create a directory with an increased number as suffix for the given prefix."""
mode = mode or tmpdir_file_mode()
for i in range(10): for i in range(10):
# try up to 10 times to create the folder # try up to 10 times to create the folder
max_existing = max(map(parse_num, find_suffixes(root, prefix)), default=-1) 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) shutil.copyfile(x, newx)
elif x.is_dir(): elif x.is_dir():
newx.mkdir(exist_ok=True) newx.mkdir(exist_ok=True)
def tmpdir_file_mode() -> int:
return int(os.getenv("PYTEST_TMPDIR_FILE_MODE", "700"), 8)

View File

@ -62,6 +62,7 @@ from _pytest.outcomes import skip
from _pytest.pathlib import bestrelpath from _pytest.pathlib import bestrelpath
from _pytest.pathlib import copytree from _pytest.pathlib import copytree
from _pytest.pathlib import make_numbered_dir from _pytest.pathlib import make_numbered_dir
from _pytest.pathlib import tmpdir_file_mode
from _pytest.reports import CollectReport from _pytest.reports import CollectReport
from _pytest.reports import TestReport from _pytest.reports import TestReport
from _pytest.tmpdir import TempPathFactory 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" "/var/lib/sss/mc/passwd"
] ]
TMPDIR_FILE_MODE = int(os.getenv("PYTEST_TMPDIR_FILE_MODE", "0o700"), 8)
def pytest_addoption(parser: Parser) -> None: def pytest_addoption(parser: Parser) -> None:
parser.addoption( parser.addoption(
@ -1505,7 +1504,7 @@ class Pytester:
""" """
__tracebackhide__ = True __tracebackhide__ = True
p = make_numbered_dir( 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 args = ("--basetemp=%s" % p,) + args
plugins = [x for x in self.plugins if isinstance(x, str)] plugins = [x for x in self.plugins if isinstance(x, str)]
@ -1525,7 +1524,7 @@ class Pytester:
The pexpect child is returned. The pexpect child is returned.
""" """
basetemp = self.path / "temp-pexpect" basetemp = self.path / "temp-pexpect"
basetemp.mkdir(mode=TMPDIR_FILE_MODE) basetemp.mkdir(mode=tmpdir_file_mode())
invoke = " ".join(map(str, self._getpytestargs())) invoke = " ".join(map(str, self._getpytestargs()))
cmd = f"{invoke} --basetemp={basetemp} {string}" cmd = f"{invoke} --basetemp={basetemp} {string}"
return self.spawn(cmd, expect_timeout=expect_timeout) return self.spawn(cmd, expect_timeout=expect_timeout)

View File

@ -30,6 +30,7 @@ from .pathlib import make_numbered_dir
from .pathlib import make_numbered_dir_with_cleanup from .pathlib import make_numbered_dir_with_cleanup
from .pathlib import rm_rf from .pathlib import rm_rf
from .pathlib import cleanup_dead_symlink from .pathlib import cleanup_dead_symlink
from .pathlib import tmpdir_file_mode
from _pytest.compat import final from _pytest.compat import final
from _pytest.config import Config from _pytest.config import Config
from _pytest.config import ExitCode from _pytest.config import ExitCode
@ -41,8 +42,6 @@ from _pytest.monkeypatch import MonkeyPatch
tmppath_result_key = StashKey[Dict[str, bool]]() tmppath_result_key = StashKey[Dict[str, bool]]()
TMPDIR_FILE_MODE = int(os.getenv("PYTEST_TMPDIR_FILE_MODE", "0o700"), 8)
@final @final
@dataclasses.dataclass @dataclasses.dataclass
@ -138,10 +137,10 @@ class TempPathFactory:
basename = self._ensure_relative_to_basetemp(basename) basename = self._ensure_relative_to_basetemp(basename)
if not numbered: if not numbered:
p = self.getbasetemp().joinpath(basename) p = self.getbasetemp().joinpath(basename)
p.mkdir(mode=TMPDIR_FILE_MODE) p.mkdir(mode=tmpdir_file_mode())
else: else:
p = make_numbered_dir( 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) self._trace("mktemp", p)
return p return p
@ -159,7 +158,7 @@ class TempPathFactory:
basetemp = self._given_basetemp basetemp = self._given_basetemp
if basetemp.exists(): if basetemp.exists():
rm_rf(basetemp) rm_rf(basetemp)
basetemp.mkdir(mode=TMPDIR_FILE_MODE) basetemp.mkdir(mode=tmpdir_file_mode())
basetemp = basetemp.resolve() basetemp = basetemp.resolve()
else: else:
from_env = os.environ.get("PYTEST_DEBUG_TEMPROOT") from_env = os.environ.get("PYTEST_DEBUG_TEMPROOT")
@ -169,11 +168,11 @@ class TempPathFactory:
# make_numbered_dir() call # make_numbered_dir() call
rootdir = temproot.joinpath(f"pytest-of-{user}") rootdir = temproot.joinpath(f"pytest-of-{user}")
try: try:
rootdir.mkdir(mode=TMPDIR_FILE_MODE, exist_ok=True) rootdir.mkdir(mode=tmpdir_file_mode(), exist_ok=True)
except OSError: except OSError:
# getuser() likely returned illegal characters for the platform, use unknown back off mechanism # getuser() likely returned illegal characters for the platform, use unknown back off mechanism
rootdir = temproot.joinpath("pytest-of-unknown") 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 # Because we use exist_ok=True with a predictable name, make sure
# we are the owners, to prevent any funny business (on unix, where # we are the owners, to prevent any funny business (on unix, where
# temproot is usually shared). # temproot is usually shared).
@ -201,7 +200,7 @@ class TempPathFactory:
root=rootdir, root=rootdir,
keep=keep, keep=keep,
lock_timeout=LOCK_TIMEOUT, lock_timeout=LOCK_TIMEOUT,
mode=TMPDIR_FILE_MODE, mode=tmpdir_file_mode(),
) )
assert basetemp is not None, basetemp assert basetemp is not None, basetemp
self._basetemp = basetemp self._basetemp = basetemp

View File

@ -631,7 +631,7 @@ def test_tmp_path_factory_user_specified_permissions(
"""Verify that pytest creates directories under /tmp with 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). # Use the test's tmp_path as the system temproot (/tmp).
monkeypatch.setenv("PYTEST_DEBUG_TEMPROOT", str(tmp_path)) 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) tmp_factory = TempPathFactory(None, 3, "all", lambda *args: None, _ispytest=True)
basetemp = tmp_factory.getbasetemp() basetemp = tmp_factory.getbasetemp()