pyssg is pre-1.0 and under active development - APIs, config, and themes may change.
pyssg.core.hook

1 min read

pyssg.core.hook

The hook system (control plane).

Four hook flavors borrowed from tapable, each encoding a different ordering / value-flow semantic. Taps declare relative order via stage (coarse integer bucket) plus before / after name constraints; before every call the taps are topologically sorted, and a constraint cycle raises HookOrderError. Stdlib only.

class Tap

A registered hook callback plus its ordering metadata.

order_taps(taps: list[Tap[F]]) -> list[Tap[F]]

Order taps by ascending stage, then topologically within each stage.

Within a stage, after means "run me after that named tap" and before means "run me before it". Ties break by registration order for determinism (build output must not depend on tap insertion races). Unknown names in constraints are ignored (tapable semantics). A cycle raises HookOrderError.

class SyncHook(_HookBase[Callable[P, object]])

Series hook: call every tap in order, ignore return values.

SyncHook.call(self, *args: P.args, **kwargs: P.kwargs) -> None

class BailHook(_HookBase[Callable[P, 'R | None']])

Bail hook: stop at the first tap returning a non-None value.

BailHook.call(self, *args: P.args, **kwargs: P.kwargs) -> R | None

class WaterfallHook(_HookBase[Callable[..., T]])

Waterfall hook: thread a value through each tap.

Each tap receives (value, *rest) and returns the next value. *rest carries unchanged context (e.g. the page being rendered).

WaterfallHook.call(self, value: T, *rest: object) -> T

class AsyncSeriesHook(_HookBase[Callable[P, Awaitable[object]]])

Async series hook: await each tap in order (for I/O phases).

async AsyncSeriesHook.call(self, *args: P.args, **kwargs: P.kwargs) -> None