Repository: pytest-dev/pytest
File: src/_pytest/cacheprovider.py (Python)

Code before:
    the race, the temporary directory is cleaned up.
    """
    target.parent.mkdir(parents=True, exist_ok=True)
    path = Path(tempfile.mkdtemp(prefix="pytest-cache-files-", dir=target.parent))
    try:
        # Reset permissions to the default, see #12308.
        # Note: there's no way to get the current umask atomically, eek.
        umask = os.umask(0o022)
        os.umask(umask)
        path.chmod(0o777 - umask)

        for name, content in CACHEDIR_FILES.items():
            path.joinpath(name).write_bytes(content)

        path.rename(target)
    except OSError as e:
        # If 2 concurrent pytests both race to the rename, the loser
        # gets "Directory not empty" from the rename. In this case,
        # everything is handled so just continue after cleanup.
        # On Windows, the error is a FileExistsError which translates to EEXIST.
        shutil.rmtree(path, ignore_errors=True)
        if e.errno not in (errno.ENOTEMPTY, errno.EEXIST):
            raise
    except BaseException:
        shutil.rmtree(path, ignore_errors=True)
        raise


@final
@dataclasses.dataclass
class Cache:
    """Instance of the `cache` fixture."""

    _cachedir: Path = dataclasses.field(repr=False)
    _config: Config = dataclasses.field(repr=False)

    # Sub-directory under cache-dir for directories created by `mkdir()`.
    _CACHE_PREFIX_DIRS = "d"

    # Sub-directory under cache-dir for values created by `set()`.
    _CACHE_PREFIX_VALUES = "v"

    def __init__(
        self, cachedir: Path, config: Config, *, _ispytest: bool = False
    ) -> None:
        check_ispytest(_ispytest)
        self._cachedir = cachedir
        self._config = config

    @classmethod
    def for_config(cls, config: Config, *, _ispytest: bool = False) -> Cache:

Review comment (security):
This flow might be simpler:

```suggestion
    target.parent.mkdir(parents=True, exist_ok=True)
    path = Path(tempfile.mkdtemp(prefix="pytest-cache-files-", dir=target.parent))
    try:
        # Reset permissions to the default, see #12308.
        # Note: there's no way to get the current umask atomically, eek.
        umask = os.umask(0o022)
        os.umask(umask)
        path.chmod(0o777 - umask)

        for name, content in CACHEDIR_FILES.items():
            path.joinpath(name).write_bytes(content)

        path.rename(target)
    except OSError as e:
        # If 2 concurrent pytests both race to the rename, the loser
        # gets "Directory not empty" from the rename. In this case,
        # everything is handled so just continue after cleanup.
        # On Windows, the error is a FileExistsError which translates to EEXIST.
        if e.errno not in (errno.ENOTEMPTY, errno.EEXIST):
            raise
    finally:
        shutil.rmtree(path, ignore_errors=True)
```

Code after:
    the race, the temporary directory is cleaned up.
    """
    target.parent.mkdir(parents=True, exist_ok=True)
    path = Path(tempfile.mkdtemp(prefix="pytest-cache-files-", dir=target.parent))
    try:
        # Reset permissions to the default, see #12308.
        # Note: there's no way to get the current umask atomically, eek.
        umask = os.umask(0o022)
        os.umask(umask)
        path.chmod(0o777 - umask)

        for name, content in CACHEDIR_FILES.items():
            path.joinpath(name).write_bytes(content)

        path.rename(target)
    except OSError as e:
        # If 2 concurrent pytests both race to the rename, the loser
        # gets "Directory not empty" from the rename. In this case,
        # everything is handled so just continue after cleanup.
        # On Windows, the error is a FileExistsError which translates to EEXIST.
        if e.errno not in (errno.ENOTEMPTY, errno.EEXIST):
            raise
    finally:
        shutil.rmtree(path, ignore_errors=True)


@final
@dataclasses.dataclass
class Cache:
    """Instance of the `cache` fixture."""

    _cachedir: Path = dataclasses.field(repr=False)
    _config: Config = dataclasses.field(repr=False)

    # Sub-directory under cache-dir for directories created by `mkdir()`.
    _CACHE_PREFIX_DIRS = "d"

    # Sub-directory under cache-dir for values created by `set()`.
    _CACHE_PREFIX_VALUES = "v"

    def __init__(
        self, cachedir: Path, config: Config, *, _ispytest: bool = False
    ) -> None:
        check_ispytest(_ispytest)
        self._cachedir = cachedir
        self._config = config

    @classmethod
    def for_config(cls, config: Config, *, _ispytest: bool = False) -> Cache:
        """Create the Cache instance for a Config.