Jaunt
Guides

Dependencies

Ordering and incremental rebuild behavior.

You want one spec to call another, and you want a change to the first to rebuild the second. Jaunt handles both from a spec-level dependency graph, which it uses for:

  • generation order (dependencies before dependents)
  • incremental rebuilds (a dependent goes stale when a dependency's exported API changes)

Explicit Deps (deps=...)

Declare deps explicitly when you want guaranteed ordering:

@jaunt.magic(deps=["my_app.specs:normalize_email", "my_app.other.Helper"])
def is_corporate_email(raw: str) -> bool:
    ...

Accepted deps= formats:

  • string "pkg.mod:Qualname" (canonical)
  • string "pkg.mod.Qualname" (dot shorthand; last . becomes :)
  • an object (function/class) that Jaunt can convert to module:qualname

Inference (Best-Effort)

Jaunt can also infer edges best-effort. It’s useful, but it’s not magic.

Use explicit deps= when:

  • the dependency is in another module
  • you want deterministic ordering
  • inference is missing an edge or creating the wrong one

Base-Class Edges (Structural)

When a whole-class @jaunt.magic spec inherits from another spec — class Child(Base) where both carry @jaunt.magic — the base is an always-on dependency. This edge is not inference: it is a structural fact read straight from the class header, so it holds even with infer_deps turned off (or --no-infer-deps). The base's module always builds before the subclass's.

For a cross-module base (base and subclass live in different modules), the subclass's build context includes the base's generated public API — method signatures and docstrings read from the built artifact on disk — so the model builds on real inherited methods instead of a stale snapshot. A same-module base pair is co-generated as one component: both classes are designed together in a single shot, so there is no separate "base artifact first" step.

A base-class cycle (two specs inheriting from each other across modules) is a real cycle and raises JauntDependencyCycleError (exit 2).

What Happens During Generation

  • Dependencies are generated first.
  • If a dependency's exported API changes, dependents become stale on the next run.

Dependency API changes include:

  • signature changes
  • edits anywhere in the cleaned docstring contract
  • for whole-class specs, adding/removing/changing declared members or method signatures

Current limitation: dependency context plumbing is intentionally minimal. Ordering and staleness propagation work, but the backend does not currently get rich "here is the generated dependency source" context for dependents.

If a cycle exists, Jaunt raises JauntDependencyCycleError and exits with code 2.

Next: Spec Writing Tips.

On this page