Temporary Directory Management

This module provides fixtures and utilities for creating and managing temporary directories unique to each test function invocation. It addresses the need for isolated, disposable filesystem locations during test runs, ensuring tests do not interfere with each other's data and enabling configurable retention policies for debugging or cleanup purposes.


Core Concepts and Purpose

Temporary directories are essential in testing scenarios where tests need to write files, logs, or other artifacts without polluting the global filesystem or affecting other tests. This module:


How It Works

TempPathFactory: The Central Factory

`TempPathFactory` is a dataclass responsible for managing the lifecycle and creation of temporary directories within a shared base directory (`basetemp`).

Per-Test Temporary Directory Fixture (tmp_path)

Lifecycle and Cleanup Hooks


Interaction with Other System Parts


Important Concepts and Design Patterns


Code References and Examples

Creation of TempPathFactory from pytest config

@classmethod
def from_config(cls, config: Config, *, _ispytest: bool = False) -> TempPathFactory:
    count = int(config.getini("tmp_path_retention_count"))
    policy = config.getini("tmp_path_retention_policy")
    return cls(
        given_basetemp=config.option.basetemp,
        retention_count=count,
        retention_policy=policy,
        trace=config.trace.get("tmpdir"),
        _ispytest=True,
    )

This snippet shows how the factory is configured with retention parameters and optionally a user-defined base temp directory.


Fixture Providing Per-Test Temporary Directory

@fixture
def tmp_path(request: FixtureRequest, tmp_path_factory: TempPathFactory) -> Generator[Path]:
    path = _mk_tmp(request, tmp_path_factory)
    yield path

    policy = tmp_path_factory._retention_policy
    result_dict = request.node.stash[tmppath_result_key]

    if policy == "failed" and result_dict.get("call", True):
        rmtree(path, ignore_errors=True)

    del request.node.stash[tmppath_result_key]

This fixture creates a unique temp directory per test, yields it, and cleans up after test execution according to the retention policy.


Cleanup After Test Session

def pytest_sessionfinish(session, exitstatus: int | ExitCode):
    tmp_path_factory: TempPathFactory = session.config._tmp_path_factory
    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
    ):
        if basetemp.is_dir():
            rmtree(basetemp, ignore_errors=True)

    if basetemp.is_dir():
        cleanup_dead_symlinks(basetemp)

This hook removes the base temp directory if all tests passed and retention policy dictates so, plus it cleans up dead symbolic links.


Mermaid Diagram: Temporary Directory Management Workflow

flowchart TD
    Start[Start Test Session]
    Config[Load tmp_path_retention_count & tmp_path_retention_policy]
    CreateFactory[Create TempPathFactory]
    RegisterFactory[Attach Factory to Config]
    ForEachTest[Test Function Start]
    TmpDir[Create Unique Temp Directory via Factory]
    RunTest[Test Execution]
    StoreResult[Store Test Outcome]
    CleanupTmpDir{Retention Policy?}
    RemoveDir[Remove Temp Directory]
    KeepDir[Keep Temp Directory]
    NextTest[Next Test or Session Finish]
    SessionFinish[After Session Finish]
    CleanupBaseDir{Retention Policy & Outcome}
    RemoveBaseDir[Remove Base Temp Directory]
    KeepBaseDir[Keep Base Temp Directory]
    CleanupSymlinks[Cleanup Dead Symlinks]

    Start --> Config --> CreateFactory --> RegisterFactory
    RegisterFactory --> ForEachTest
    ForEachTest --> TmpDir --> RunTest --> StoreResult --> CleanupTmpDir
    CleanupTmpDir -->|Remove if passed & policy=failed| RemoveDir
    CleanupTmpDir -->|Otherwise| KeepDir
    RemoveDir --> NextTest
    KeepDir --> NextTest
    NextTest -->|More Tests| ForEachTest
    NextTest -->|No More Tests| SessionFinish
    SessionFinish --> CleanupBaseDir
    CleanupBaseDir -->|Remove if all passed & policy=failed| RemoveBaseDir
    CleanupBaseDir -->|Otherwise| KeepBaseDir
    RemoveBaseDir --> CleanupSymlinks
    KeepBaseDir --> CleanupSymlinks

This documentation explains the temporary directory management system's role, behavior, and integration within pytest, focusing on providing isolated, configurable, and secure filesystem locations for test executions.