Classes
Compiler
51
▼
Compile Kida AST to Python code objects.
The Compiler transforms a Kida Template AST into an `ast.…
Compiler
51
▼
Compile Kida AST to Python code objects.
The Compiler transforms a Kida Template AST into anast.Module, then
compiles it to a code object ready forexec(). The generated code
defines arender(ctx, _blocks=None)function.
Node Dispatch:
Uses O(1) dict lookup for node type → handler:
python dispatch = { "Data": self._compile_data, "Output": self._compile_output, "If": self._compile_if, ... } handler = dispatch[type(node).__name__]
Line Tracking:
For nodes that can cause runtime errors (Output, For, If, etc.),
generates_get_render_ctx().line = Nbefore the node's code.
This updates the ContextVar-stored RenderContext instead of polluting
the user's ctx dict, enabling rich error messages with source line
numbers while keeping user context clean.
Attributes
| Name | Type | Description |
|---|---|---|
_NODE_DISPATCH_NAMES |
ClassVar[dict[str, str]]
|
— |
_class_dispatch |
ClassVar[dict[str, Callable] | None]
|
— |
_SCOPED_PARENTS |
ClassVar[dict[str, str]]
|
— |
_last_block_cacheable_vars |
set[str]
|
— |
_last_block_compiled_stmts |
list[ast.stmt] | None
|
— |
_env |
— |
Parent Environment (for filter/test access) |
_name |
str | None
|
Template name for error messages |
_filename |
str | None
|
Source file path for compile() |
_locals |
set[str]
|
Set of local variable names (loop vars, macro args) |
_blocks |
dict[str, Block | Region]
|
Dict of block_name → Block node (for inheritance) |
_block_counter |
int
|
Counter for unique variable names |
Methods
warnings
0
list[TemplateWarning]
▼
Compile-time warnings accumulated during compilation.
property
warnings
0
list[TemplateWarning]
▼
def warnings(self) -> list[TemplateWarning]
Returns
list[TemplateWarning]
precomputed
0
list[Any]
▼
Values that must be injected into the exec() namespace as ``_pc_N``.
property
precomputed
0
list[Any]
▼
def precomputed(self) -> list[Any]
Returns
list[Any]
compile
3
types.CodeType
▼
Compile template AST to code object.
compile
3
types.CodeType
▼
def compile(self, node: TemplateNode, name: str | None = None, filename: str | None = None) -> types.CodeType
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
Root Template node |
name |
— |
Template name for error messages Default:None
|
filename |
— |
Source filename for error messages Default:None
|
Returns
types.CodeType
Compiled code object ready for exec()
Internal Methods 37 ▼
_ensure_dispatch
0
dict[str, Callable]
▼
Build and cache the class-level dispatch table of unbound functions.
classmethod
_ensure_dispatch
0
dict[str, Callable]
▼
def _ensure_dispatch(cls) -> dict[str, Callable]
Returns
dict[str, Callable]
__init_subclass__
1
▼
__init_subclass__
1
▼
def __init_subclass__(cls, **kwargs: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
**kwargs |
— |
__init__
1
▼
__init__
1
▼
def __init__(self, env: Environment)
Parameters
| Name | Type | Description |
|---|---|---|
env |
— |
_emit_warning
4
▼
Record a compile-time warning.
_emit_warning
4
▼
def _emit_warning(self, code: ErrorCode, message: str, *, lineno: int | None = None, suggestion: str | None = None) -> None
Parameters
| Name | Type | Description |
|---|---|---|
code |
— |
|
message |
— |
|
lineno |
— |
Default:None
|
suggestion |
— |
Default:None
|
_get_literal_extends_target
1
str | None
▼
Return literal extends target if template uses {% extends "literal" %}, else No…
_get_literal_extends_target
1
str | None
▼
def _get_literal_extends_target(self, node: TemplateNode) -> str | None
Return literal extends target if template uses {% extends "literal" %}, else None.
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
Returns
str | None
_check_definition_nesting
2
▼
Recursively walk the AST and reject {% def %} / {% region %}
nested inside any …
_check_definition_nesting
2
▼
def _check_definition_nesting(self, nodes: Sequence[Node], parent_chain: tuple[str, ...]) -> None
Recursively walk the AST and reject {% def %} / {% region %} nested inside any control-flow construct.
parent_chaincarries the human-readable tag names of enclosing
scoped parents (e.g.("for", "if")). When a Def or Region
is reached and the chain is non-empty, raisesTemplateSyntaxError
with codeK-TPL-004.
Other container nodes (Block, CallBlock, Embed, Def, Region, ...) are traversed but do not contribute to the chain — defining nested helpers inside them is a supported pattern.
Parameters
| Name | Type | Description |
|---|---|---|
nodes |
— |
|
parent_chain |
— |
_collect_blocks
1
▼
Populate blocks through the template-structure analysis phase.
_collect_blocks
1
▼
def _collect_blocks(self, nodes: Sequence[Node]) -> None
Parameters
| Name | Type | Description |
|---|---|---|
nodes |
— |
_emit_output
1
ast.stmt
▼
Generate output statement: yield (streaming) or _append (StringBuilder).
All o…
_emit_output
1
ast.stmt
▼
def _emit_output(self, value_expr: ast.expr) -> ast.stmt
Generate output statement: yield (streaming) or _append (StringBuilder).
All output generation in compiled templates flows through this method, allowing the compiler to switch between StringBuilder and generator modes.
Parameters
| Name | Type | Description |
|---|---|---|
value_expr |
— |
Returns
ast.stmt
_lowering_mode
2
Iterator[None]
▼
Temporarily select compiler lowering flags and always restore them.
_lowering_mode
2
Iterator[None]
▼
def _lowering_mode(self, *, streaming: bool | None = None, async_mode: bool | None = None) -> Iterator[None]
Parameters
| Name | Type | Description |
|---|---|---|
streaming |
— |
Default:None
|
async_mode |
— |
Default:None
|
Returns
Iterator[None]
_compile_template
1
ast.Module
▼
Generate Python module from template.
Produces both StringBuilder functions (r…
_compile_template
1
ast.Module
▼
def _compile_template(self, node: TemplateNode) -> ast.Module
Generate Python module from template.
Produces both StringBuilder functions (render, block) and generator functions (render_stream, block_stream) in a single module. The StringBuilder path is used by Template.render() and the generator path by Template.render_stream().
When async constructs are detected (AsyncFor, Await), also generates async generator functions (render_stream_async, block*_stream_async).
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
Returns
ast.Module
_lower_block_function_variants
3
BlockFunctionVariants
▼
Lower one block into its sync, stream, and async-stream functions.
_lower_block_function_variants
3
BlockFunctionVariants
▼
def _lower_block_function_variants(self, name: str, block_node: Block | Region, *, template_has_regions: bool) -> BlockFunctionVariants
Parameters
| Name | Type | Description |
|---|---|---|
name |
— |
|
block_node |
— |
|
template_has_regions |
— |
Returns
BlockFunctionVariants
_make_globals_setup
1
ast.FunctionDef | None
▼
Generate _globals_setup(ctx) from {% globals %}, {% imports %}, and top-level i…
_make_globals_setup
1
ast.FunctionDef | None
▼
def _make_globals_setup(self, node: TemplateNode) -> ast.FunctionDef | None
Generate _globals_setup(ctx) from {% globals %}, {% imports %}, and top-level imports.
Scans the template body for:
- Top-level FromImport and Import nodes (so render_block has macros in scope)
- Globals and Imports nodes (macros/variables for block context)
This function is called by render_block() to inject macros and variables into the block's context. Returns None if neither globals nor top-level imports exist.
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
Returns
ast.FunctionDef | None
_make_runtime_preamble
10
list[ast.stmt]
▼
Build shared runtime locals preamble for generated functions.
_make_runtime_preamble
10
list[ast.stmt]
▼
def _make_runtime_preamble(self, *, include_blocks_guard: bool = False, include_scope_stack: bool = False, include_escape_str: bool = False, include_getattr: bool = False, include_buf_append: bool = False, include_acc: bool = False, acc_none: bool = False, include_cap: bool = False, include_lookup_scope: bool = False, include_render_ctx: bool = False) -> list[ast.stmt]
Parameters
| Name | Type | Description |
|---|---|---|
include_blocks_guard |
— |
Default:False
|
include_scope_stack |
— |
Default:False
|
include_escape_str |
— |
Default:False
|
include_getattr |
— |
Default:False
|
include_buf_append |
— |
Default:False
|
include_acc |
— |
Default:False
|
acc_none |
— |
Default:False
|
include_cap |
— |
Default:False
|
include_lookup_scope |
— |
Default:False
|
include_render_ctx |
— |
Default:False
|
Returns
list[ast.stmt]
_make_block_preamble
1
list[ast.stmt]
▼
Common setup stmts for block functions.
Non-streaming adds buf and _append for…
_make_block_preamble
1
list[ast.stmt]
▼
def _make_block_preamble(self, streaming: bool) -> list[ast.stmt]
Common setup stmts for block functions.
Non-streaming adds buf and _append for StringBuilder.
Parameters
| Name | Type | Description |
|---|---|---|
streaming |
— |
Returns
list[ast.stmt]
_build_region_keywords
1
tuple[list[str], list[as…
▼
Build param_names and keywords for region block delegation.
Returns (param_nam…
_build_region_keywords
1
tuple[list[str], list[as…
▼
def _build_region_keywords(self, region_node: Region) -> tuple[list[str], list[ast.keyword]]
Build param_names and keywords for region block delegation.
Returns (param_names, keywords) where keywords includes both the per-param entries and the trailing _outer_ctx / _blocks keywords.
Parameters
| Name | Type | Description |
|---|---|---|
region_node |
— |
Returns
tuple[list[str], list[ast.keyword]]
_make_region_block_function
2
ast.FunctionDef
▼
Generate block wrapper that delegates to region callable with ctx params.
_make_region_block_function
2
ast.FunctionDef
▼
def _make_region_block_function(self, name: str, region_node: Region) -> ast.FunctionDef
Parameters
| Name | Type | Description |
|---|---|---|
name |
— |
|
region_node |
— |
Returns
ast.FunctionDef
_has_unconditional_exprs
1
bool
▼
Delegate the fast CSE guard to its named analysis owner.
staticmethod
_has_unconditional_exprs
1
bool
▼
def _has_unconditional_exprs(body: Sequence) -> bool
Parameters
| Name | Type | Description |
|---|---|---|
body |
— |
Returns
bool
_analyze_for_cse
1
set[str]
▼
Combined CSE analysis: returns cacheable variable names.
Performs the fast unc…
_analyze_for_cse
1
set[str]
▼
def _analyze_for_cse(self, body_nodes: Sequence) -> set[str]
Combined CSE analysis: returns cacheable variable names.
Performs the fast unconditional-expression guard check followed by the full variable reference collection in a single call, deduplicating the pattern used across _make_block_function and _make_render_direct_body.
Parameters
| Name | Type | Description |
|---|---|---|
body_nodes |
— |
Returns
set[str]
_collect_var_refs
1
tuple[dict[str, int], se…
▼
Delegate variable traversal to its named analysis owner.
staticmethod
_collect_var_refs
1
tuple[dict[str, int], se…
▼
def _collect_var_refs(nodes: Any) -> tuple[dict[str, int], set[str]]
Parameters
| Name | Type | Description |
|---|---|---|
nodes |
— |
Returns
tuple[dict[str, int], set[str]]
_emit_cache_assignments
1
list[ast.stmt]
▼
Emit _cv_name = _ls(ctx, _scope_stack, 'name') for each cached variable.
_emit_cache_assignments
1
list[ast.stmt]
▼
def _emit_cache_assignments(self, names: set[str]) -> list[ast.stmt]
Parameters
| Name | Type | Description |
|---|---|---|
names |
— |
Returns
list[ast.stmt]
_is_append_constant
1
str | None
▼
If *stmt* is ``_append()``, return the string; else None.
staticmethod
_is_append_constant
1
str | None
▼
def _is_append_constant(stmt: ast.stmt) -> str | None
Parameters
| Name | Type | Description |
|---|---|---|
stmt |
— |
Returns
str | None
_is_line_tracking
1
bool
▼
Return True if *stmt* is ``_rc.line = N`` (render-context line tracking).
staticmethod
_is_line_tracking
1
bool
▼
def _is_line_tracking(stmt: ast.stmt) -> bool
Parameters
| Name | Type | Description |
|---|---|---|
stmt |
— |
Returns
bool
_is_single_append_expr
1
ast.expr | None
▼
If *stmt* is ``_append(expr)``, return *expr*; else None.
staticmethod
_is_single_append_expr
1
ast.expr | None
▼
def _is_single_append_expr(stmt: ast.stmt) -> ast.expr | None
Parameters
| Name | Type | Description |
|---|---|---|
stmt |
— |
Returns
ast.expr | None
_make_block_function
2
ast.FunctionDef
▼
Generate a block function: _block_name(ctx, _blocks) -> str.
Also stores the r…
_make_block_function
2
ast.FunctionDef
▼
def _make_block_function(self, name: str, block_node: Block | Region) -> ast.FunctionDef
Generate a block function: _block_name(ctx, _blocks) -> str.
Also stores the raw compiled stmts in_last_block_compiled_stmts
so the stream variant can be derived without recompiling the Kida AST.
Parameters
| Name | Type | Description |
|---|---|---|
name |
— |
|
block_node |
— |
Returns
ast.FunctionDef
_make_render_preamble
0
list[ast.stmt]
▼
Shared init block for render functions: if _blocks, _scope_stack, _acc, _cap.
_make_render_preamble
0
list[ast.stmt]
▼
def _make_render_preamble(self) -> list[ast.stmt]
Returns
list[ast.stmt]
_make_render_extends_body
5
list[ast.stmt]
▼
Top-level statements, block registration, and extends return/yield.
_make_render_extends_body
5
list[ast.stmt]
▼
def _make_render_extends_body(self, node: TemplateNode, extends_node: Extends, block_names: dict[str, Block | Region], block_suffix: str, extends_helper: str) -> list[ast.stmt]
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
|
extends_node |
— |
|
block_names |
— |
|
block_suffix |
— |
|
extends_helper |
— |
Returns
list[ast.stmt]
_make_render_direct_body
2
list[ast.stmt]
▼
No-extends path: buf setup (if not streaming), body compile, return vs yield.
_make_render_direct_body
2
list[ast.stmt]
▼
def _make_render_direct_body(self, node: TemplateNode, streaming: bool) -> list[ast.stmt]
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
|
streaming |
— |
Returns
list[ast.stmt]
_make_render_function
1
ast.FunctionDef
▼
Generate the render(ctx, _blocks=None) function.
Optimization: Cache global fu…
_make_render_function
1
ast.FunctionDef
▼
def _make_render_function(self, node: TemplateNode) -> ast.FunctionDef
Generate the render(ctx, _blocks=None) function.
Optimization: Cache global function references as locals for O(1) LOAD_FAST instead of O(1) LOAD_GLOBAL + hash lookup.
For templates with extends:
def render(ctx, _blocks=None):
if _blocks is None: _blocks = {}
# Register child blocks
_blocks.setdefault('name', _block_name)
# Render parent with blocks
return _extends('parent.html', ctx, _blocks)
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
Returns
ast.FunctionDef
_make_block_function_stream
2
ast.FunctionDef
▼
Generate a streaming block: _block_name_stream(ctx, _blocks) -> Generator[str].
_make_block_function_stream
2
ast.FunctionDef
▼
def _make_block_function_stream(self, name: str, block_node: Block | Region) -> ast.FunctionDef
Generate a streaming block: _block_name_stream(ctx, _blocks) -> Generator[str].
Parameters
| Name | Type | Description |
|---|---|---|
name |
— |
|
block_node |
— |
Returns
ast.FunctionDef
_make_render_function_stream
2
ast.FunctionDef
▼
Generate render_stream(ctx, _blocks=None) generator function.
For templates wi…
_make_render_function_stream
2
ast.FunctionDef
▼
def _make_render_function_stream(self, node: TemplateNode, blocks: dict[str, Block | Region]) -> ast.FunctionDef
Generate render_stream(ctx, _blocks=None) generator function.
For templates with extends:
yield from _extends_stream('parent.html', ctx, _blocks)
For templates without extends:
yield chunks directly
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
|
blocks |
— |
Returns
ast.FunctionDef
_make_region_block_function_stream
2
ast.FunctionDef
▼
Streaming block wrapper for region — yields callable result.
_make_region_block_function_stream
2
ast.FunctionDef
▼
def _make_region_block_function_stream(self, name: str, region_node: Region) -> ast.FunctionDef
Parameters
| Name | Type | Description |
|---|---|---|
name |
— |
|
region_node |
— |
Returns
ast.FunctionDef
_make_region_block_function_stream_async
2
ast.AsyncFunctionDef
▼
Async streaming block wrapper for region.
_make_region_block_function_stream_async
2
ast.AsyncFunctionDef
▼
def _make_region_block_function_stream_async(self, name: str, region_node: Region) -> ast.AsyncFunctionDef
Parameters
| Name | Type | Description |
|---|---|---|
name |
— |
|
region_node |
— |
Returns
ast.AsyncFunctionDef
_make_block_function_stream_async
2
ast.AsyncFunctionDef
▼
Generate async streaming block: _block_name_stream_async(ctx, _blocks).
Mirror…
_make_block_function_stream_async
2
ast.AsyncFunctionDef
▼
def _make_block_function_stream_async(self, name: str, block_node: Block | Region) -> ast.AsyncFunctionDef
Generate async streaming block: _block_name_stream_async(ctx, _blocks).
Mirrors _make_block_function_stream() but produces an async generator function (async def + yield). Used when the template contains async constructs (AsyncFor, Await).
Part of RFC: rfc-async-rendering.
Parameters
| Name | Type | Description |
|---|---|---|
name |
— |
|
block_node |
— |
Returns
ast.AsyncFunctionDef
_make_render_function_stream_async
2
ast.AsyncFunctionDef
▼
Generate async render_stream_async(ctx, _blocks=None) function.
Mirrors _make_…
_make_render_function_stream_async
2
ast.AsyncFunctionDef
▼
def _make_render_function_stream_async(self, node: TemplateNode, blocks: dict[str, Block | Region]) -> ast.AsyncFunctionDef
Generate async render_stream_async(ctx, _blocks=None) function.
Mirrors _make_render_function_stream() but produces an async generator for native async iteration over AsyncFor loops and Await expressions.
For templates with extends:
async for chunk in _extends_stream_async(parent, ctx, _blocks):
yield chunk
For templates without extends:
yield chunks directly via async generator
Part of RFC: rfc-async-rendering.
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
|
blocks |
— |
Returns
ast.AsyncFunctionDef
_compile_template_context
1
list[ast.stmt]
▼
No-op: TemplateContext is a declaration, not code.
staticmethod
_compile_template_context
1
list[ast.stmt]
▼
def _compile_template_context(_node: Node) -> list[ast.stmt]
Parameters
| Name | Type | Description |
|---|---|---|
_node |
— |
Returns
list[ast.stmt]
_compile_node
1
list[ast.stmt]
▼
Compile a single AST node to Python statements.
Complexity: O(1) type dispatch…
_compile_node
1
list[ast.stmt]
▼
def _compile_node(self, node: Node) -> list[ast.stmt]
Compile a single AST node to Python statements.
Complexity: O(1) type dispatch using class name lookup.
For nodes that can cause runtime errors, injects a line marker statement (ctx['_line'] = N) before the node's code. This enables rich error messages with source line numbers.
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
Returns
list[ast.stmt]
_get_node_dispatch
0
dict[str, Callable]
▼
Get node type dispatch table.
_get_node_dispatch
0
dict[str, Callable]
▼
def _get_node_dispatch(self) -> dict[str, Callable]
Returns
dict[str, Callable]