Skip to content

API Reference

The top-level package for the project.

rig

Package initialization.

cli

Package initialization.

fixture(name=typer.Argument(help='Name of the fixture to create.'))

Scaffold a new pytest fixture stub in the project's shared fixtures module.

Appends an @pytest.fixture-decorated function stub to the shared fixtures module. The file is created if it does not already exist. If import pytest is not already present in the module, it is inserted automatically.

The name is normalized from kebab-case to snake_case so it forms a valid Python identifier (e.g. my-new-fixture becomes my_new_fixture).

Example

$ uv run pyrig mk fixture my-fixture

Source code in src/pyrig_fixtures/rig/cli/__init__.py
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@mk.command()
def fixture(
    name: str = typer.Argument(help="Name of the fixture to create."),
) -> None:
    """Scaffold a new pytest fixture stub in the project's shared fixtures module.

    Appends an `@pytest.fixture`-decorated function stub to the shared fixtures
    module. The file is created if it does not already exist. If `import pytest`
    is not already present in the module, it is inserted automatically.

    The name is normalized from kebab-case to snake_case so it forms a valid
    Python identifier (e.g. `my-new-fixture` becomes `my_new_fixture`).

    Example:
        $ uv run pyrig mk fixture my-fixture
    """
    from pyrig_fixtures.rig.cli.commands.make.fixture import (  # noqa: PLC0415
        make_fixture,
    )

    make_fixture(name)

commands

Package Initialization.

make

Package initialization.

fixture

Scaffold shared pytest fixtures for a pyrig-managed project.

make_fixture(name)

Scaffold a new pytest fixture in the project's shared fixtures module.

Ensures the shared fixtures.py file exists, then appends a new @pytest.fixture-decorated function with the given name. If import pytest is not already present in the file, it is added before the new fixture.

The name is normalized from kebab-case to snake_case so it forms a valid Python identifier (e.g. "my-new-fixture" becomes "my_new_fixture").

Parameters:

Name Type Description Default
name str

Name of the fixture in kebab-case or snake_case.

required
Source code in src/pyrig_fixtures/rig/cli/commands/make/fixture.py
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
def make_fixture(name: str) -> None:
    """Scaffold a new pytest fixture in the project's shared fixtures module.

    Ensures the shared ``fixtures.py`` file exists, then appends a new
    ``@pytest.fixture``-decorated function with the given name. If
    ``import pytest`` is not already present in the file, it is added
    before the new fixture.

    The name is normalized from kebab-case to snake_case so it forms a
    valid Python identifier (e.g. ``"my-new-fixture"`` becomes
    ``"my_new_fixture"``).

    Args:
        name: Name of the fixture in kebab-case or snake_case.
    """
    config_file = CopyModuleDocstringConfigFile.generate_subclass(fixtures)()
    config_file.validate()
    content = config_file.read_content()

    name = kebab_to_snake_case(name)
    pytest_import = f"import {pytest.__name__}"
    # checking with splitlines to avoid substring matches, like import pytest_mock
    if pytest_import not in content.splitlines():
        content += f"""
{pytest_import}
"""

    content += f'''

@{pytest.__name__}.{pytest.fixture.__name__}
def {name}() -> None:
    """This is a test fixture."""
'''

    config_file.write_content(content)

tests

Package initialization.

fixtures

Pytest fixture package for pyrig and pyrig-based projects.

All Python modules inside this package (excluding __init__.py) are automatically discovered by the project conftest and registered as pytest plugins. This makes every fixture defined in those submodules available in all test modules without explicit imports.

Installed packages that depend on pyrig and mirror this package path are discovered and registered in the same way, allowing downstream projects to extend the base fixture set transparently.

cli

Shared pytest fixtures for testing the project's CLI commands.

Provides helpers that assert a CLI command is registered and reachable, and that a command delegates to its expected implementation function.

command_calls_function(mocker)

Return a callable that verifies a CLI command delegates to the expected function.

The returned function patches the target function by its fully qualified name, invokes the command, and asserts the patch was called exactly once.

Parameters:

Name Type Description Default
mocker MockerFixture

pytest-mock fixture for patching.

required

Returns:

Type Description
Callable[[Callable[..., Any], Callable[..., Any]], None]

A callable (cmd, function) -> None that asserts cmd calls

Callable[[Callable[..., Any], Callable[..., Any]], None]

function exactly once.

Source code in src/pyrig_fixtures/rig/tests/fixtures/cli.py
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
@pytest.fixture
def command_calls_function(
    mocker: MockerFixture,
) -> Callable[[Callable[..., Any], Callable[..., Any]], None]:
    """Return a callable that verifies a CLI command delegates to the expected function.

    The returned function patches the target function by its fully qualified
    name, invokes the command, and asserts the patch was called exactly once.

    Args:
        mocker: pytest-mock fixture for patching.

    Returns:
        A callable ``(cmd, function) -> None`` that asserts ``cmd`` calls
        ``function`` exactly once.
    """

    def check(cmd: Callable[..., Any], function: Callable[..., Any]) -> None:
        mock = mocker.patch(function.__module__ + "." + function.__name__)  # ty:ignore[unresolved-attribute]
        cmd()
        mock.assert_called_once()

    return check
command_works()

Return a callable that verifies a CLI command is registered and executable.

The returned function runs the command with --help and asserts that the command executes successfully and that its name appears in stdout.

Returns:

Type Description
Callable[[Callable[..., Any]], None]

A callable (cmd) -> None that accepts a CLI function and asserts

Callable[[Callable[..., Any]], None]

it is reachable and produces help output.

Source code in src/pyrig_fixtures/rig/tests/fixtures/cli.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@pytest.fixture
def command_works() -> Callable[[Callable[..., Any]], None]:
    """Return a callable that verifies a CLI command is registered and executable.

    The returned function runs the command with ``--help`` and asserts that
    the command executes successfully and that its name appears in stdout.

    Returns:
        A callable ``(cmd) -> None`` that accepts a CLI function and asserts
        it is reachable and produces help output.
    """

    def check(cmd: Callable[..., Any]) -> None:
        # run the --help command to see if it is available
        args = PackageManager.I.project_cmd_args("--help", cmd=cmd)
        completed_process = args.run()
        stdout = completed_process.stdout
        name = cmd.__name__.replace("_", "-")  # ty:ignore[unresolved-attribute]
        assert name in stdout

    return check
configs

Shared pytest fixtures for testing ConfigFile subclasses in isolation.

Provides a factory that redirects a ConfigFile subclass's file operations to pytest's tmp_path so tests never touch real project files.

config_file_factory(tmp_path)

Return a factory that wraps a ConfigFile subclass for isolated testing.

The factory creates a dynamic subclass that redirects all file operations to pytest's tmp_path. This prevents tests from reading or writing real project files. The following methods are overridden to enforce isolation:

  • path() and parent_path(): prepend tmp_path to the original path if it is not already inside tmp_path and the current working directory is not tmp_path.
  • _dump() and _load(): change the working directory to tmp_path before delegating to the parent implementation.
  • create_file(): changes the working directory to tmp_path before delegating to the parent implementation.

Parameters:

Name Type Description Default
tmp_path Path

Pytest's per-test temporary directory.

required

Returns:

Type Description
Callable[[type[T]], type[T]]

A callable (type[T]) -> type[T] that accepts a ConfigFile

Callable[[type[T]], type[T]]

subclass and returns a test-safe subclass with tmp_path-based

Callable[[type[T]], type[T]]

file operations.

Source code in src/pyrig_fixtures/rig/tests/fixtures/configs.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
@pytest.fixture
def config_file_factory[T: ConfigFile[dict[str, Any] | list[Any]]](
    tmp_path: Path,
) -> Callable[[type[T]], type[T]]:
    """Return a factory that wraps a ``ConfigFile`` subclass for isolated testing.

    The factory creates a dynamic subclass that redirects all file operations
    to pytest's ``tmp_path``. This prevents tests from reading or writing
    real project files. The following methods are overridden to enforce
    isolation:

    - ``path()`` and ``parent_path()``: prepend ``tmp_path`` to the original
      path if it is not already inside ``tmp_path`` and the current working
      directory is not ``tmp_path``.
    - ``_dump()`` and ``_load()``: change the working directory to
      ``tmp_path`` before delegating to the parent implementation.
    - ``create_file()``: changes the working directory to ``tmp_path`` before
      delegating to the parent implementation.

    Args:
        tmp_path: Pytest's per-test temporary directory.

    Returns:
        A callable ``(type[T]) -> type[T]`` that accepts a ``ConfigFile``
        subclass and returns a test-safe subclass with ``tmp_path``-based
        file operations.
    """

    def _make_test_config(
        base_class: type[T],
    ) -> type[T]:
        """Wrap ``base_class`` with ``tmp_path``-redirected file operations.

        Args:
            base_class: The ``ConfigFile`` subclass to wrap.

        Returns:
            A subclass of ``base_class`` with all file paths redirected to
            ``tmp_path``.
        """

        class TestConfigFile(base_class):  # ty: ignore[unsupported-base]
            """Test config file with tmp_path override."""

            def path(self) -> Path:
                """Get the file path redirected to tmp_path.

                Returns:
                    Path within tmp_path.
                """
                path = super().path()
                # append tmp_path to path if not already in tmp_path
                if not (path.is_relative_to(tmp_path) or Path.cwd() == tmp_path):
                    path = tmp_path / path
                return path

            def _dump(self, configs: dict[str, Any] | list[Any]) -> None:
                """Write config to tmp_path, ensuring isolated test execution."""
                with chdir(tmp_path):
                    super()._dump(configs)

            def _load(self) -> dict[str, Any] | list[Any]:
                """Load config from tmp_path, ensuring isolated test execution."""
                with chdir(tmp_path):
                    return super()._load()

            def create_file(self) -> None:
                """Create file in tmp_path, ensuring isolated test execution."""
                with chdir(tmp_path):
                    super().create_file()

        return TestConfigFile  # ty:ignore[invalid-return-type]

    return _make_test_config
environment

Shared pytest fixtures for gating tests by platform and Python version.

Provides session-scoped predicates for the current OS and interpreter version, used to restrict environment-sensitive tests to a canonical CI environment while still running them locally.

on_latest_python_version(on_python_version)

Return whether the running Python version matches the latest stable release.

The latest version is read from the project's bundled LATEST_PYTHON_VERSION resource via PyprojectConfigFile.

Parameters:

Name Type Description Default
on_python_version Callable[[str], bool]

Fixture for checking the current Python version.

required

Returns:

Type Description
bool

True if the current Python micro version matches the latest stable

bool

release.

Source code in src/pyrig_fixtures/rig/tests/fixtures/environment.py
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
@pytest.fixture(scope="session")
def on_latest_python_version(on_python_version: Callable[[str], bool]) -> bool:
    """Return whether the running Python version matches the latest stable release.

    The latest version is read from the project's bundled
    ``LATEST_PYTHON_VERSION`` resource via ``PyprojectConfigFile``.

    Args:
        on_python_version: Fixture for checking the current Python version.

    Returns:
        True if the current Python micro version matches the latest stable
        release.
    """
    latest_version = PyprojectConfigFile.I.latest_python_version("micro")
    return on_python_version(str(latest_version))
on_linux(on_platform)

Return whether the current system is Linux.

Parameters:

Name Type Description Default
on_platform Callable[[str], bool]

Fixture for checking the current platform by name.

required

Returns:

Type Description
bool

True if the system is Linux.

Source code in src/pyrig_fixtures/rig/tests/fixtures/environment.py
57
58
59
60
61
62
63
64
65
66
67
@pytest.fixture(scope="session")
def on_linux(on_platform: Callable[[str], bool]) -> bool:
    """Return whether the current system is Linux.

    Args:
        on_platform: Fixture for checking the current platform by name.

    Returns:
        True if the system is Linux.
    """
    return on_platform("Linux")
on_linux_and_latest_python_version(*, on_linux, on_latest_python_version)

Return whether the current environment is Linux with the latest Python version.

Parameters:

Name Type Description Default
on_linux bool

Whether the current system is Linux.

required
on_latest_python_version bool

Whether the current Python version is the latest.

required

Returns:

Type Description
bool

True if both conditions are met.

Source code in src/pyrig_fixtures/rig/tests/fixtures/environment.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
@pytest.fixture(scope="session")
def on_linux_and_latest_python_version(
    *, on_linux: bool, on_latest_python_version: bool
) -> bool:
    """Return whether the current environment is Linux with the latest Python version.

    Args:
        on_linux: Whether the current system is Linux.
        on_latest_python_version: Whether the current Python version is the latest.

    Returns:
        True if both conditions are met.
    """
    return on_linux and on_latest_python_version
on_linux_and_latest_python_version_or_not_in_ci(*, on_linux_and_latest_python_version)

Return whether tests that require a canonical environment should run.

True when running on Linux with the latest Python version, or when not running in CI at all. This is used to gate environment-sensitive tests, allowing them to always run locally while restricting them to the canonical CI environment in GitHub Actions.

Parameters:

Name Type Description Default
on_linux_and_latest_python_version bool

Whether the environment is Linux with the latest Python version.

required

Returns:

Type Description
bool

True if the canonical CI conditions are met, or if not running in CI.

Source code in src/pyrig_fixtures/rig/tests/fixtures/environment.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@pytest.fixture(scope="session")
def on_linux_and_latest_python_version_or_not_in_ci(
    *, on_linux_and_latest_python_version: bool
) -> bool:
    """Return whether tests that require a canonical environment should run.

    True when running on Linux with the latest Python version, or when not
    running in CI at all. This is used to gate environment-sensitive tests,
    allowing them to always run locally while restricting them to the
    canonical CI environment in GitHub Actions.

    Args:
        on_linux_and_latest_python_version: Whether the environment is Linux
            with the latest Python version.

    Returns:
        True if the canonical CI conditions are met, or if not running in CI.
    """
    return (
        on_linux_and_latest_python_version
    ) or not RemoteVersionController.I.running_in_ci()
on_platform()

Check if the current system platform matches a given name.

Returns:

Type Description
Callable[[str], bool]

A callable (platform_name) -> bool that compares

Callable[[str], bool]

platform.system() against the given name (e.g., "Linux",

Callable[[str], bool]

"Windows", "Darwin").

Source code in src/pyrig_fixtures/rig/tests/fixtures/environment.py
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
@pytest.fixture(scope="session")
def on_platform() -> Callable[[str], bool]:
    """Check if the current system platform matches a given name.

    Returns:
        A callable ``(platform_name) -> bool`` that compares
        ``platform.system()`` against the given name (e.g., ``"Linux"``,
        ``"Windows"``, ``"Darwin"``).
    """

    def check(platform_name: str) -> bool:
        """Check if the current system is the specified platform."""
        return platform.system() == platform_name

    return check
on_python_version()

Check if the current Python version matches a given version string.

Returns:

Type Description
Callable[[str], bool]

A callable (version) -> bool that compares

Callable[[str], bool]

platform.python_version() against the given version string

Callable[[str], bool]

(e.g., "3.13.2").

Source code in src/pyrig_fixtures/rig/tests/fixtures/environment.py
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
@pytest.fixture(scope="session")
def on_python_version() -> Callable[[str], bool]:
    """Check if the current Python version matches a given version string.

    Returns:
        A callable ``(version) -> bool`` that compares
        ``platform.python_version()`` against the given version string
        (e.g., ``"3.13.2"``).
    """

    def check(version: str) -> bool:
        """Check if the current Python version matches the specified version."""
        return platform.python_version() == version

    return check
fixtures

Shared pytest fixtures for pyrig and all projects built with it.

Fixtures defined here or any other file in the same package are automatically discovered by pytest and made available to any pytest suite that inherits from this project.

modules

Shared pytest fixtures for creating temporary modules and packages.

Provides callables that build real Python modules and packages on disk (with the appropriate __init__.py hierarchy) and import them, for tests that need live module objects to introspect.

create_module()

Return a callable that creates a Python module at a given path.

The returned function ensures the parent directory is a proper package hierarchy (adding __init__.py files up to the current working directory), touches the module file, and imports it.

Returns:

Type Description
Callable[[Path], ModuleType]

A callable (path) -> ModuleType that creates and imports the

Callable[[Path], ModuleType]

module at path.

Source code in src/pyrig_fixtures/rig/tests/fixtures/modules.py
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
@pytest.fixture
def create_module() -> Callable[[Path], ModuleType]:
    """Return a callable that creates a Python module at a given path.

    The returned function ensures the parent directory is a proper package
    hierarchy (adding ``__init__.py`` files up to the current working
    directory), touches the module file, and imports it.

    Returns:
        A callable ``(path) -> ModuleType`` that creates and imports the
        module at ``path``.
    """

    def create(path: Path) -> ModuleType:
        """Create a module from the given path."""
        make_package_dir(path.parent, until=(), content="")
        path.touch()
        return import_module_with_file_fallback(path, name=path_as_module_name(path))

    return create
create_package()

Return a callable that creates a Python package at a given path.

The returned function initializes the full directory tree as a package hierarchy by adding __init__.py files up to the current working directory, then imports and returns the package.

Returns:

Type Description
Callable[[Path], ModuleType]

A callable (path) -> ModuleType that creates and imports the

Callable[[Path], ModuleType]

package at path.

Source code in src/pyrig_fixtures/rig/tests/fixtures/modules.py
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
@pytest.fixture
def create_package() -> Callable[[Path], ModuleType]:
    """Return a callable that creates a Python package at a given path.

    The returned function initializes the full directory tree as a package
    hierarchy by adding ``__init__.py`` files up to the current working
    directory, then imports and returns the package.

    Returns:
        A callable ``(path) -> ModuleType`` that creates and imports the
        package at ``path``.
    """

    def create(path: Path) -> ModuleType:
        """Create a package from the given path."""
        make_package_dir(path, until=(), content="")
        return import_package_with_dir_fallback(path, name=path_as_module_name(path))

    return create
create_source_package(tmp_source_root_path, create_package)

Return a callable that creates a Python package under the temporary source root.

Wraps create_package with a chdir to tmp_source_root_path so that all relative path operations resolve within the temporary source tree.

Parameters:

Name Type Description Default
tmp_source_root_path Path

Temporary source root directory.

required
create_package Callable[[Path], ModuleType]

Fixture that creates a package from a relative path.

required

Returns:

Type Description
Callable[[Path], ModuleType]

A callable (path) -> ModuleType that creates and imports the

Callable[[Path], ModuleType]

package at path relative to the temporary source root.

Source code in src/pyrig_fixtures/rig/tests/fixtures/modules.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@pytest.fixture
def create_source_package(
    tmp_source_root_path: Path, create_package: Callable[[Path], ModuleType]
) -> Callable[[Path], ModuleType]:
    """Return a callable that creates a Python package under the temporary source root.

    Wraps ``create_package`` with a ``chdir`` to ``tmp_source_root_path``
    so that all relative path operations resolve within the temporary source
    tree.

    Args:
        tmp_source_root_path: Temporary source root directory.
        create_package: Fixture that creates a package from a relative path.

    Returns:
        A callable ``(path) -> ModuleType`` that creates and imports the
        package at ``path`` relative to the temporary source root.
    """

    def create(path: Path) -> ModuleType:
        """Create the package relative to the source root."""
        with chdir(tmp_source_root_path):
            return create_package(path)

    return create
paths

Shared pytest fixtures providing temporary project/source/package roots.

Builds a temporary directory tree mirroring the project's layout (project root → source root → package root) so tests can operate on a realistic, isolated copy of the project structure.

tmp_package_root_path(tmp_project_root_path, tmp_source_root_path, create_source_package)

Provide the temporary package root directory and its imported package module.

Creates the package root directory under the temporary source root, initializes it as a Python package, and returns both the path and the imported module.

Parameters:

Name Type Description Default
tmp_project_root_path Path

Temporary project root directory.

required
tmp_source_root_path Path

Temporary source root directory.

required
create_source_package Callable[[Path], ModuleType]

Fixture for creating packages in the source root.

required

Returns:

Type Description
Path

Tuple of (path, package) where path is the package root

ModuleType

directory and package is the imported package module.

Source code in src/pyrig_fixtures/rig/tests/fixtures/paths.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@pytest.fixture
def tmp_package_root_path(
    tmp_project_root_path: Path,
    tmp_source_root_path: Path,
    create_source_package: Callable[[Path], ModuleType],
) -> tuple[Path, ModuleType]:
    """Provide the temporary package root directory and its imported package module.

    Creates the package root directory under the temporary source root,
    initializes it as a Python package, and returns both the path and the
    imported module.

    Args:
        tmp_project_root_path: Temporary project root directory.
        tmp_source_root_path: Temporary source root directory.
        create_source_package: Fixture for creating packages in the source root.

    Returns:
        Tuple of ``(path, package)`` where ``path`` is the package root
        directory and ``package`` is the imported package module.
    """
    path = tmp_project_root_path / PackageManager.I.package_root()

    package = create_source_package(path.relative_to(tmp_source_root_path))
    return path, package
tmp_project_root_path(tmp_path)

Provide a temporary project root directory named after the current project.

Parameters:

Name Type Description Default
tmp_path Path

Pytest's per-test temporary directory.

required

Returns:

Type Description
Path

Path to the temporary project root directory.

Source code in src/pyrig_fixtures/rig/tests/fixtures/paths.py
60
61
62
63
64
65
66
67
68
69
70
71
72
@pytest.fixture
def tmp_project_root_path(tmp_path: Path) -> Path:
    """Provide a temporary project root directory named after the current project.

    Args:
        tmp_path: Pytest's per-test temporary directory.

    Returns:
        Path to the temporary project root directory.
    """
    path = tmp_path / PackageManager.I.project_name()
    path.mkdir()
    return path
tmp_source_root_path(tmp_project_root_path)

Provide the temporary source root directory.

Creates the source root directory inside the temporary project root.

Parameters:

Name Type Description Default
tmp_project_root_path Path

Temporary project root directory.

required

Returns:

Type Description
Path

Path to the temporary source root directory.

Source code in src/pyrig_fixtures/rig/tests/fixtures/paths.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
@pytest.fixture
def tmp_source_root_path(tmp_project_root_path: Path) -> Path:
    """Provide the temporary source root directory.

    Creates the source root directory inside the temporary project root.

    Args:
        tmp_project_root_path: Temporary project root directory.

    Returns:
        Path to the temporary source root directory.
    """
    path = tmp_project_root_path / PackageManager.I.source_root()
    path.mkdir()
    return path