Module

template

Kida Template — compiled template object ready for rendering.

The Template class wraps a compiled code object and provides therender() API. Templates are immutable and thread-safe for concurrent rendering.

Architecture:

```
Template
├── _env_ref: WeakRef[Environment]  # Prevents circular refs
├── _code: code object              # Compiled Python bytecode
├── _render_func: callable          # Extracted render() function
└── _name, _filename                # For error messages
```

StringBuilder Pattern:

Generated code usesbuf.append()+''.join(buf): python def render(ctx, _blocks=None): buf = [] _append = buf.append _append("Hello, ") _append(_e(_s(ctx["name"]))) return ''.join(buf) This is O(n) vs O(n²) for string concatenation.

Memory Safety:

Usesweakref.ref(env)to break potential cycles: Template → (weak) → Environment → cache → Template

Thread-Safety:

  • Templates are immutable after construction
  • render()creates only local state (buf list)
  • Multiple threads can callrender()concurrently

Complexity:

  • render(): O(n) where n = output size
  • _escape(): O(n) single-pass viastr.translate()

Classes

LoopContext 13
Loop iteration metadata accessible as `loop` inside `{% for %}` blocks. Provides index tracking, b…

Loop iteration metadata accessible asloopinside{% for %}blocks.

Provides index tracking, boundary detection, and utility methods for common iteration patterns. All properties are computed on-access.

Properties: index: 1-based iteration count (1, 2, 3, ...) index0: 0-based iteration count (0, 1, 2, ...) first: True on the first iteration last: True on the final iteration length: Total number of items in the sequence revindex: Reverse 1-based index (counts down to 1) revindex0: Reverse 0-based index (counts down to 0) previtem: Previous item in sequence (None on first) nextitem: Next item in sequence (None on last)

Methods: cycle(*values): Return values[index % len(values)]

Output:

        <ul>
            <li class="odd">1/3: Apple ← First</li>
            <li class="even">2/3: Banana</li>
            <li class="odd">3/3: Cherry ← Last</li>
        </ul>
        ```

Methods

index 0 int
1-based iteration count.
property
def index(self) -> int
Returns
int
index0 0 int
0-based iteration count.
property
def index0(self) -> int
Returns
int
first 0 bool
True if this is the first iteration.
property
def first(self) -> bool
Returns
bool
last 0 bool
True if this is the last iteration.
property
def last(self) -> bool
Returns
bool
length 0 int
Total number of items in the sequence.
property
def length(self) -> int
Returns
int
revindex 0 int
Reverse 1-based index (counts down to 1).
property
def revindex(self) -> int
Returns
int
revindex0 0 int
Reverse 0-based index (counts down to 0).
property
def revindex0(self) -> int
Returns
int
previtem 0 Any
Previous item in the sequence, or None if first.
property
def previtem(self) -> Any
Returns
Any
nextitem 0 Any
Next item in the sequence, or None if last.
property
def nextitem(self) -> Any
Returns
Any
cycle 0 Any
Cycle through the given values.
def cycle(self, *values: Any) -> Any
Returns
Any
Internal Methods 3
__init__ 1
def __init__(self, items: list[Any]) -> None
Parameters
Name Type Description
items
__iter__ 0 Any
Iterate through items, updating index for each.
def __iter__(self) -> Any
Returns
Any
__repr__ 0 str
def __repr__(self) -> str
Returns
str
CachedBlocksDict 8
Dict wrapper that returns cached HTML for site-scoped blocks. Used by Kida's block cache optimizat…

Dict wrapper that returns cached HTML for site-scoped blocks.

Used by Kida's block cache optimization to intercept .get() calls from templates and return pre-rendered HTML for site-wide blocks (nav, footer, etc.).

Complexity: O(1) for lookups.

Methods

get 2 Any
Intercept .get() calls to return cached HTML when available.
def get(self, key: str, default: Any = None) -> Any
Parameters
Name Type Description
key
default Default:None
Returns
Any
setdefault 2 Any
Preserve setdefault() behavior for block registration. Kida templates use .set…
def setdefault(self, key: str, default: Any = None) -> Any

Preserve setdefault() behavior for block registration.

Kida templates use .setdefault() to register their own block functions if not already overridden by a child template.

Parameters
Name Type Description
key
default Default:None
Returns
Any
keys 0 set[str]
Support .keys() iteration.
def keys(self) -> set[str]
Returns
set[str]
copy 0 dict[str, Any]
Support .copy() for embed/include operations.
def copy(self) -> dict[str, Any]
Returns
dict[str, Any]
Internal Methods 4
__init__ 4
def __init__(self, original: dict[str, Any] | None, cached: dict[str, str], cached_names: set[str], stats: dict[str, int] | None = None)
Parameters
Name Type Description
original
cached
cached_names
stats Default:None
__getitem__ 1 Any
Support dict[key] access.
def __getitem__(self, key: str) -> Any
Parameters
Name Type Description
key
Returns
Any
__setitem__ 2
Support dict[key] = value assignment.
def __setitem__(self, key: str, value: Any) -> None
Parameters
Name Type Description
key
value
__contains__ 1 bool
Support 'key in dict' checks.
def __contains__(self, key: str) -> bool
Parameters
Name Type Description
key
Returns
bool
Template 19
Compiled template ready for rendering. Wraps a compiled code object containing a `render(ctx, _blo…

Compiled template ready for rendering.

Wraps a compiled code object containing arender(ctx, _blocks)function. Templates are immutable and thread-safe for concurrentrender()calls.

Thread-Safety:

  • Template object is immutable after construction
  • Eachrender()call creates local state only (buf list)
  • Multiple threads can render the same template simultaneously

Memory Safety: Usesweakref.ref(env)to prevent circular reference leaks: Template → (weak) → Environment → _cache → Template

Methods: render(**context): Render template with given variables render_async(**context): Async render for templates with await

Error Enhancement:

Runtime errors are caught and enhanced with template context:

    ```
    TemplateRuntimeError: 'NoneType' has no attribute 'title'
      Location: article.html:15
      Expression: {{ post.title }}
      Values:
        post = None (NoneType)
      Suggestion: Check if 'post' is defined before accessing .title
    ```

Attributes

Name Type Description
name

Template identifier (for error messages)

filename

Source file path (for error messages)

Methods

name 0 str | None
Template name.
property
def name(self) -> str | None
Returns
str | None
filename 0 str | None
Source filename.
property
def filename(self) -> str | None
Returns
str | None
render 0 str
Render template with given context.
def render(self, *args: Any, **kwargs: Any) -> str
Returns
str Rendered template as string
render_block 1 str
Render a single block from the template. Renders just the named block, useful …
def render_block(self, block_name: str, *args: Any, **kwargs: Any) -> str

Render a single block from the template.

Renders just the named block, useful for caching blocks that only depend on site-wide context (e.g., navigation, footer).

Parameters
Name Type Description
block_name

Name of the block to render (e.g., "nav", "footer") *args: Single dict of context variables **kwargs: Context variables as keyword arguments

Returns
str Rendered block HTML as string
list_blocks 0 list[str]
List all blocks defined in this template.
def list_blocks(self) -> list[str]
Returns
list[str] List of block names available for render_block()
render_async 0 str
Async wrapper for synchronous render. Runs the synchronous `render()` method i…
async
async def render_async(self, *args: Any, **kwargs: Any) -> str

Async wrapper for synchronous render.

Runs the synchronousrender()method in a thread pool to avoid blocking the event loop. This is useful when calling from async code (e.g., FastAPI, aiohttp handlers).

Returns
str Rendered template as string
block_metadata 0 dict[str, Any]
Get metadata about template blocks. Returns a mapping of block name → BlockMet…
def block_metadata(self) -> dict[str, Any]

Get metadata about template blocks.

Returns a mapping of block name → BlockMetadata with:

  • depends_on: Context paths the block may access
  • is_pure: Whether output is deterministic
  • cache_scope: Recommended caching granularity
  • inferred_role: Heuristic classification

Results are cached after first call.

Returns empty dict if:

  • AST was not preserved (preserve_ast=False)
  • Template was loaded from bytecode cache without source
Returns
dict[str, Any]
template_metadata 0 Any
Get full template metadata including inheritance info. **Returns TemplateMetad…
def template_metadata(self) -> Any

Get full template metadata including inheritance info.

Returns TemplateMetadata with:

  • name: Template identifier
  • extends: Parent template name (if any)
  • blocks: Mapping of block name → BlockMetadata
  • top_level_depends_on: Context paths used outside blocks

Returns None if AST was not preserved (preserve_ast=False or loaded from bytecode cache without source).

Returns
Any
depends_on 0 frozenset[str]
Get all context paths this template may access. Convenience method combining a…
def depends_on(self) -> frozenset[str]

Get all context paths this template may access.

Convenience method combining all block dependencies and top-level dependencies.

Returns empty frozenset if AST was not preserved.

Returns
frozenset[str]
Internal Methods 8
_env 0 Environment
Get the Environment (dereferences weak reference).
property
def _env(self) -> Environment
Returns
Environment
__init__ 5
Initialize template with compiled code.
def __init__(self, env: Environment, code: Any, name: str | None, filename: str | None, optimized_ast: Any = None)
Parameters
Name Type Description
env

Parent Environment (stored as weak reference)

code

Compiled Python code object

name

Template name (for error messages)

filename

Source filename (for error messages)

optimized_ast

Optional preserved AST for introspection. If None, introspection methods return empty results.

Default:None
_enhance_error 2 Exception
Enhance a generic exception with template context. Converts generic Python exc…
def _enhance_error(self, error: Exception, ctx: dict[str, Any]) -> Exception

Enhance a generic exception with template context.

Converts generic Python exceptions into TemplateRuntimeError with template name and line number context.

Parameters
Name Type Description
error
ctx
Returns
Exception
_escape 1 str
HTML-escape a value. Uses optimized html_escape from utils.html module. Comple…
staticmethod
def _escape(value: Any) -> str

HTML-escape a value.

Uses optimized html_escape from utils.html module. Complexity: O(n) single-pass using str.translate().

Parameters
Name Type Description
value
Returns
str
_safe_getattr 2 Any
Get attribute with dict fallback and None-safe handling. Handles both: - obj.a…
staticmethod
def _safe_getattr(obj: Any, name: str) -> Any

Get attribute with dict fallback and None-safe handling.

Handles both:

  • obj.attr for objects with attributes
  • dict['key'] for dict-like objects

None Handling (like Hugo/Go templates):

  • If obj is None, returns "" (prevents crashes)
  • If attribute value is None, returns "" (normalizes output)

Complexity: O(1)

Parameters
Name Type Description
obj
name
Returns
Any
_getattr_preserve_none 2 Any
Get attribute with dict fallback, preserving None values. Like _safe_getattr b…
staticmethod
def _getattr_preserve_none(obj: Any, name: str) -> Any

Get attribute with dict fallback, preserving None values.

Like _safe_getattr but preserves None values instead of converting to empty string. Used for optional chaining (?.) so that null coalescing (??) can work correctly.

Part of RFC: kida-modern-syntax-features

Handles both:

  • obj.attr for objects with attributes
  • dict['key'] for dict-like objects

Complexity: O(1)

Parameters
Name Type Description
obj
name
Returns
Any
_analyze 0
Perform static analysis and cache results.
def _analyze(self) -> None
__repr__ 0 str
def __repr__(self) -> str
Returns
str
RenderedTemplate 3
Lazy rendered template (for streaming). Allows iteration over rendered chunks for streaming output…

Lazy rendered template (for streaming).

Allows iteration over rendered chunks for streaming output. Not implemented in initial version.

Methods

Internal Methods 3
__init__ 2
def __init__(self, template: Template, context: dict[str, Any])
Parameters
Name Type Description
template
context
__str__ 0 str
Render and return full string.
def __str__(self) -> str
Returns
str
__iter__ 0 Any
Iterate over rendered chunks.
def __iter__(self) -> Any
Returns
Any