From 58ddc6d7548f605d904086220a73b4af8fe2b629 Mon Sep 17 00:00:00 2001 From: Yusuke Kadowaki Date: Thu, 27 Oct 2022 00:34:19 +0900 Subject: [PATCH] Introduce sessionfinish to cleanup --- src/_pytest/pathlib.py | 4 +++- src/_pytest/tmpdir.py | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/_pytest/pathlib.py b/src/_pytest/pathlib.py index a12d2d6f4..74d60b83a 100644 --- a/src/_pytest/pathlib.py +++ b/src/_pytest/pathlib.py @@ -339,6 +339,8 @@ def cleanup_numbered_dir( root: Path, prefix: str, keep: int, consider_lock_dead_if_created_before: float ) -> None: """Cleanup for lock driven numbered directories.""" + if not root.exists(): + return for path in cleanup_candidates(root, prefix, keep): try_cleanup(path, consider_lock_dead_if_created_before) for path in root.glob("garbage-*"): @@ -357,7 +359,7 @@ def make_numbered_dir_with_cleanup( for i in range(10): try: p = make_numbered_dir(root, prefix, mode) - # Do not lock the current dir when keep is 0 + # Only lock the current dir when keep is not 0 if keep != 0: lock_path = create_cleanup_lock(p) register_cleanup_lock_removal(lock_path) diff --git a/src/_pytest/tmpdir.py b/src/_pytest/tmpdir.py index fc454be7a..c11c92c84 100644 --- a/src/_pytest/tmpdir.py +++ b/src/_pytest/tmpdir.py @@ -1,10 +1,13 @@ """Support for providing temporary directories to test functions.""" +import atexit import os import re import sys import tempfile from pathlib import Path +from shutil import rmtree from typing import Optional +from typing import Union import attr @@ -14,6 +17,7 @@ from .pathlib import make_numbered_dir_with_cleanup from .pathlib import rm_rf from _pytest.compat import final from _pytest.config import Config +from _pytest.config import ExitCode from _pytest.deprecated import check_ispytest from _pytest.fixtures import fixture from _pytest.fixtures import FixtureRequest @@ -225,3 +229,23 @@ def tmp_path(request: FixtureRequest, tmp_path_factory: TempPathFactory) -> Path """ return _mk_tmp(request, tmp_path_factory) + + +def pytest_sessionfinish(session, exitstatus: Union[int, ExitCode]): + tmp_path_factory: TempPathFactory = session.config._tmp_path_factory + policy = tmp_path_factory._retention_policy + + if ( + exitstatus == 0 + and policy == "failed" + and tmp_path_factory._given_basetemp is None + ): + # Register to remove the base directory before starting cleanup_numbered_dir + if tmp_path_factory._basetemp is None: + return + + def cleanup_passed_dir(passed_dir: Path): + if passed_dir.exists(): + rmtree(passed_dir) + + atexit.register(cleanup_passed_dir, tmp_path_factory._basetemp)