Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7.3.x] Fix tmp_path regression introduced in 7.3.0 #10912

Merged
merged 1 commit into from
Apr 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/10896.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed performance regression related to :fixture:`tmp_path` and the new :confval:`tmp_path_retention_policy` option.
4 changes: 2 additions & 2 deletions src/_pytest/pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ def cleanup_candidates(root: Path, prefix: str, keep: int) -> Iterator[Path]:
yield path


def cleanup_dead_symlink(root: Path):
def cleanup_dead_symlinks(root: Path):
for left_dir in root.iterdir():
if left_dir.is_symlink():
if not left_dir.resolve().exists():
Expand All @@ -371,7 +371,7 @@ def cleanup_numbered_dir(
for path in root.glob("garbage-*"):
try_cleanup(path, consider_lock_dead_if_created_before)

cleanup_dead_symlink(root)
cleanup_dead_symlinks(root)


def make_numbered_dir_with_cleanup(
Expand Down
21 changes: 10 additions & 11 deletions src/_pytest/tmpdir.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,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 cleanup_dead_symlinks
from _pytest.compat import final, get_user_id
from _pytest.config import Config
from _pytest.config import ExitCode
Expand Down Expand Up @@ -289,31 +289,30 @@ def tmp_path(

del request.node.stash[tmppath_result_key]

# remove dead symlink
basetemp = tmp_path_factory._basetemp
if basetemp is None:
return
cleanup_dead_symlink(basetemp)


def pytest_sessionfinish(session, exitstatus: Union[int, ExitCode]):
"""After each session, remove base directory if all the tests passed,
the policy is "failed", and the basetemp is not specified by a user.
"""
tmp_path_factory: TempPathFactory = session.config._tmp_path_factory
if tmp_path_factory._basetemp is None:
basetemp = tmp_path_factory._basetemp
if basetemp is None:
return

policy = tmp_path_factory._retention_policy
if (
exitstatus == 0
and policy == "failed"
and tmp_path_factory._given_basetemp is None
):
passed_dir = tmp_path_factory._basetemp
if passed_dir.exists():
if basetemp.is_dir():
# We do a "best effort" to remove files, but it might not be possible due to some leaked resource,
# permissions, etc, in which case we ignore it.
rmtree(passed_dir, ignore_errors=True)
rmtree(basetemp, ignore_errors=True)

# Remove dead symlinks.
if basetemp.is_dir():
cleanup_dead_symlinks(basetemp)


@hookimpl(tryfirst=True, hookwrapper=True)
Expand Down