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

2 min read

pyssg.core.build

Per-build scope: Build (Compilation) and its hooks.

A Build is created fresh for each (re)build and owns the graph and nodes of that build. Long-lived state (cache, registries) lives on the Builder and is reached through self.builder so the cache survives across a watch session.

class AssetStage(IntEnum)

Numeric buckets for process_assets taps.

Rule: minify before HASH; HASH before REPORT. Plugins declare only a stage; they never need to know about each other.

class BuildStats

Per-build counters; changed_outputs feeds live-reload.

class ResolveContext

Context handed to resolvers.

Minimal in M2; resolution helpers (by_slug, placeholder, ...) are added with the resolver plugins in M3/M6.

class ParserSlot

Tap points for one parser kind.

class BuildHooks

Hooks scoped to a single build.

class Build

The per-build compilation.

For an incremental watch session this same object persists across rebuild passes, carrying the graph plus the bookkeeping the incremental engine needs: committed per-aspect hashes (for early-cutoff), the path->node map (for FS events), and which pages each document generated (page-set diff).

Build.__init__(self, builder: Builder) -> None

Build.loaders(self) -> Registry[str, BailHook[[str], Node]]

Build.parsers(self) -> Registry[str, ParserSlot]

Build.resolvers(self) -> Registry[str, BailHook[[Dependency, ResolveContext], Connection]]

Build.cache(self) -> Cache

Build.plugin_set_version(self) -> Digest

Digest of the plugin set + their cache versions.

Build.pipeline_version(self, phase: Phase) -> Digest

Version of the code chain for phase.

Simplified in M4: the plugin set defines the pipeline, so bumping any plugin's cache_version busts the relevant cache entries.

Build.relevant_config(self, phase: Phase) -> Digest

Digest of the config keys that affect phase.

Build.create_connection(self, *, src: NodeId, dst: NodeId | None, kind: ConnectionKind, dependency: Dependency, sensitive_to: frozenset[Aspect] = frozenset(), restart_phase: Phase = Phase.RENDER, reverse: bool = False) -> Connection

Declare and register a resolved edge.

This is the plugin's declaration point; the engine owns what the sensitive_to / restart_phase / reverse facts mean for invalidation.

Build.emit_page(self, page: Page) -> None

Register a page produced by a generator.

Build.take_generated_pages(self) -> list[Page]

Return and clear the pages accumulated since the last call.

Build.prev_hashes(self, nid: NodeId) -> dict[Aspect, Digest]

Per-aspect hashes committed by the previous stable build.

Build.commit_hashes(self, nid: NodeId) -> None

Snapshot a node's current hashes as the new baseline.

Build.forget_node(self, nid: NodeId) -> None

Drop all incremental bookkeeping for a removed node.

Build.register_path(self, path: str, nid: NodeId) -> None

Build.id_of_path(self, path: str) -> NodeId | None

Build.forget_path(self, path: str) -> None

Build.set_pages_of(self, did: NodeId, page_ids: list[NodeId]) -> None

Build.pages_of(self, did: NodeId) -> list[NodeId]

Build.record_emit(self, pid: NodeId, output_rel: str) -> None

Build.emitted_output(self, pid: NodeId) -> str | None

Build.known_pages(self) -> set[NodeId]

Build.set_known_pages(self, pages: set[NodeId]) -> None