papertrail documentation

To install:

uv add papertrail

Add the following lines to your pyproject.toml:

[project.entry-points.pytest11]
papertrail = "papertrail.__main__"
papertrail.example(fn: Callable, *args: tuple[Any, ...], **kwargs: dict[str, Any]) Example

Capture an example from a test to add to the docstring.

Wrap the example around the function before the equality operation and the function result will be captured and added to the docstring of the function. This only happens if the tests pass!

from papertrail import example

def test_add():
    assert example(add, 2, 3) == 5

This has captured the example and now once the tests are finished the docstring of the function will be updated like this:

def add(a: int, b: int) -> int:
    """Papertrail examples:

        >>> add(2, 3) == 5
        True
    ::
    """
    return a + b

You can use it with parametrized tests too:

@pytest.mark.parametrize(
    ("args", "kwargs", "expected_result"),
    [
        pytest.param((2, 2), {}, 0),
        pytest.param((2,), {"b": 3}, -1),
    ],
)
def test_func_b(args, kwargs, expected_result):
    assert example(func_b, *args, **kwargs) == expected_result

This captures all the cases and adds them to the functions docstring:

def func_b(a: float, b: float) -> float:
    """Simple docstring

    Args:
        a (float)
        b (float)

    Returns:
        float

    Papertrail examples:

        >>> func_b(2, 2) == 0
        True

        >>> func_b(2, b=3) == -1
        True
    ::
    """
    return a - b

For more exciting inputs and arguments the docstrings code will be formatted with black:

def enum_keys(enum_dict: dict[int, str]) -> list[str]:
    """Multiply the values by the key amount."""
    return [i * a for i, a in enum_dict.items()]

Imagine this test:

import string

import pytest
from mock_src.mod_b import enum_keys

from papertrail import example


@pytest.mark.parametrize(
    ("args", "kwargs", "expected_result"),
    [
        pytest.param(
            (dict(enumerate(string.ascii_lowercase[:5])),),
            {},
            [
                "",
                "b",
                "cc",
                "ddd",
                "eeee",
            ],
        ),
    ],
)
def test_enum_keys(args, kwargs, expected_result):
    assert example(enum_keys, *args, **kwargs) == expected_result

This is the result (Hopefully it clearly suggests what the function should do):

def enum_keys(enum_dict: dict[int, str]) -> list[str]:
    """Multiply the values by the key amount.

    Papertrail examples:

        >>> enum_keys({0: "a", 1: "b", 2: "c", 3: "d", 4: "e"}) == [
        ...     "",
        ...     "b",
        ...     "cc",
        ...     "ddd",
        ...     "eeee",
        ... ]
        True
    ::.
    """
    return [i * a for i, a in enum_dict.items()]

Indices and tables