Parser Architecture

The Kaizo parser is responsible for loading configuration files, resolving references, dynamically importing Python objects, and controlling execution, laziness, and caching behavior.

The parser is designed to be deterministic, composable, and side-effect aware, ensuring predictable execution of declarative configurations.

Main Class

ConfigParser is the core class responsible for parsing and resolving Kaizo configuration files.

It performs static resolution (imports, references) and dynamic execution (calling functions, dispatching plugins) using a unified Entry abstraction.

Initialization

ConfigParser(
    config_path: str | Path,
    kwargs: dict | None = None
)

Parameters:

  • config_path Path to the YAML configuration file.

  • kwargs Optional runtime keyword arguments. These values take precedence during resolution.

Note

Runtime kwargs override values found in configuration files and imported modules when resolving variables.

Parser Stages

The parser processes configuration files in a fixed sequence.

1. Load YAML

The configuration file is loaded using yaml.safe_load and converted into a Python dictionary.

Note

YAML parsing occurs before any imports or execution logic.

2. Load Local Python Module

If a top-level local key is present, the referenced Python file is dynamically loaded as a module.

local: ./helpers.py

All attributes inside the local module become accessible using module: local.

Warning

The local file must exist and be a valid Python module. Otherwise, parsing fails immediately.

3. Import Sub-Configurations

If an import section exists, each referenced YAML file is parsed using a new ``ConfigParser`` instance.

import:
  common: ./common.yaml

Imported configurations:

  • Are resolved independently

  • Maintain separate storage

  • Are accessible via their import key

Important

Imported configurations are fully parsed before the current configuration is resolved.

4. Load Plugins

If a plugins section is present, plugin metadata is collected and plugin dispatchers are registered.

Plugins:

  • Must subclass Plugin

  • Are loaded from kaizo.plugins

  • Are executed through their dispatch method

Note

Plugin arguments are resolved before plugin dispatch occurs.

5. Resolve Entries

Each configuration entry is converted into an Entry instance.

Resolution includes:

  • Variable extraction

  • Reference lookup

  • Argument resolution

  • Entry type determination

Important

Resolution does not necessarily trigger execution. Execution is deferred until an entry is accessed.

6. Execute or Cache Results

Execution occurs when an entry’s __call__ method is invoked.

Depending on entry settings, results may be:

  • Executed immediately

  • Returned lazily

  • Cached by argument identity

Entry Resolution

Kaizo resolves entries recursively based on their type.

Strings

Strings are inspected for variable references using a strict syntax.

Supported syntax:

module.key.{sub_key}

Components:

  • module (optional)imported module name

  • key (optional) — entry key

  • sub_key — field name

Note

If no module is specified, resolution occurs in the current scope.

Resolution order:

  1. Runtime keyword arguments

  2. Local storage

  3. Imported module storage

Warning

If a referenced value does not exist, resolution fails with an error.

Lists

Lists are resolved element-by-element.

values:
  - 1
  - "{other.value}"

Each list element is converted into an Entry and resolved independently.

Tip

Lists may contain mixed literal values and executable entries.

Dicts

Dictionaries are resolved in one of two ways:

  • Executable dictionary If both module and source exist → ModuleEntry

  • Structured dictionary Otherwise → recursively resolved into DictEntry

Important

Only dictionaries containing both module and source are treated as executable entries.

Execution Model

All resolved values are wrapped in an Entry abstraction.

Entry Types

  • FieldEntry Returns a literal value.

  • DictEntry Resolves child entries on access.

  • ListEntry Resolves list elements on access.

  • ModuleEntry Controls execution behavior, caching, and laziness.

Execution Flow

  1. Access entry

  2. Call __call__

  3. Resolve arguments

  4. Execute or return callable

  5. Cache result if enabled

Note

Execution is demand-driven. No code is executed unless an entry is accessed.

Summary

The Kaizo parser separates:

  • Resolution (static structure)

  • Execution (dynamic behavior)

This design allows Kaizo to remain predictable, composable, and efficient while supporting complex execution graphs.