Skip to content

Errors

TripwireError

Bases: Exception

Base class for all tripwire errors.

UnmockedInteractionError

UnmockedInteractionError(source_id, args, kwargs, hint)

Bases: TripwireError

Raised at call time: an interaction fired with no matching registered mock.

Message includes: source description, args/kwargs, copy-pasteable mock hint.

Source code in src/tripwire/_errors.py
def __init__(
    self,
    source_id: str,
    args: tuple[Any, ...],
    kwargs: dict[str, Any],
    hint: str,
) -> None:
    self.source_id = source_id
    self.args_tuple = args
    self.kwargs = kwargs
    self.hint = hint
    super().__init__(
        f"Unmocked call to {source_id!r}.\n\n"
        f"Add a mock before entering the sandbox:\n"
        f"{hint}\n\n"
        f"Then assert it after the sandbox closes:\n"
        f"    with tripwire:\n"
        f"        # ... your code that triggers the call\n"
        f"    # assert_* call here (REQUIRED)"
    )

UnassertedInteractionsError

UnassertedInteractionsError(interactions, hint)

Bases: TripwireError

Raised at teardown: timeline contains interactions not matched by assert_interaction().

Message lists each unasserted interaction with copy-pasteable assert hint.

Source code in src/tripwire/_errors.py
def __init__(self, interactions: list[Any], hint: str) -> None:
    self.interactions = interactions
    self.hint = hint
    count = len(interactions)
    header = f"{count} interaction{'s were' if count > 1 else ' was'} not asserted."
    super().__init__(f"{header}\n\n{hint}")

UnusedMocksError

UnusedMocksError(mocks, hint)

Bases: TripwireError

Raised at teardown: registered mocks with required=True were never triggered.

Message lists each unused mock with hint to either remove or set required=False.

Source code in src/tripwire/_errors.py
def __init__(self, mocks: list[Any], hint: str) -> None:
    self.mocks = mocks
    self.hint = hint
    super().__init__(f"{hint}")

VerificationError

VerificationError(unasserted, unused)

Bases: TripwireError

Raised at teardown when BOTH UnassertedInteractionsError and UnusedMocksError apply.

Contains both reports in separate sections.

Source code in src/tripwire/_errors.py
def __init__(
    self,
    unasserted: UnassertedInteractionsError | None,
    unused: UnusedMocksError | None,
) -> None:
    self.unasserted = unasserted
    self.unused = unused

    sections: list[str] = []
    if unasserted is not None:
        sections.append(f"--- Unasserted Interactions ---\n{unasserted}")
    if unused is not None:
        sections.append(f"--- Unused Mocks ---\n{unused}")

    if sections:
        message = "\n\n".join(sections)
    else:
        message = "VerificationError: (no details)"

    super().__init__(message)

InteractionMismatchError

InteractionMismatchError(expected, actual, hint)

Bases: TripwireError

Raised by assert_interaction() when expected source/fields don't match the next interaction in the timeline.

Message includes: expected description, actual next interaction, remaining timeline.

Source code in src/tripwire/_errors.py
def __init__(
    self,
    expected: object,
    actual: object,
    hint: str,
) -> None:
    self.expected = expected
    self.actual = actual
    self.hint = hint
    super().__init__(hint)

MissingAssertionFieldsError

MissingAssertionFieldsError(missing_fields, provided_fields=None)

Bases: TripwireError

Raised by assert_interaction() when the caller omits one or more assertable fields from **expected.

Attributes: missing_fields: frozenset of field names that were required but absent.

Source code in src/tripwire/_errors.py
def __init__(
    self,
    missing_fields: frozenset[str],
    provided_fields: frozenset[str] | None = None,
) -> None:
    self.missing_fields = missing_fields
    self.provided_fields = provided_fields
    missing_str = ", ".join(sorted(missing_fields))
    lines = [
        f"Missing assertion fields: {missing_str}",
    ]
    if provided_fields is not None:
        provided_str = ", ".join(sorted(provided_fields))
        lines.append(f"  Provided: {provided_str}")
    lines.append("")
    lines.append(
        "Include them in **expected or use a dirty-equals"
        " matcher (e.g., IsAnything())"
    )
    lines.append(
        "if the value is not the focus of this assertion."
    )
    super().__init__("\n".join(lines))

SandboxNotActiveError

SandboxNotActiveError(source_id)

Bases: TripwireError

Raised when an intercepted call fires but no sandbox is active.

Attributes: source_id: Identifier of the interceptor that fired without a sandbox.

Message includes hint: 'Did you forget tripwire_verifier fixture or sandbox() CM?'

Source code in src/tripwire/_errors.py
def __init__(self, source_id: str) -> None:
    self.source_id = source_id
    super().__init__(
        f"SandboxNotActiveError: source_id={source_id!r}, "
        "hint='Did you forget tripwire_verifier fixture or sandbox() CM?'"
    )

ConflictError

ConflictError(target, patcher)

Bases: TripwireError

Raised at activate() time if target method is already patched by another library.

Message names the conflicting library and the patched target.

Source code in src/tripwire/_errors.py
def __init__(self, target: str, patcher: str) -> None:
    self.target = target
    self.patcher = patcher
    super().__init__(f"ConflictError: target={target!r}, patcher={patcher!r}")