Module

render_context

Kida RenderContext — per-render state isolated from user context.

This module implements ContextVar-based render state management, replacing the internal keys (_template, _line, _include_depth, _cached_blocks, _cached_stats) that were previously injected into the user's ctx dict.

Benefits:

  • Clean user context (no internal key pollution)
  • No key collision risk (user can use _template as variable)
  • Centralized state management
  • Thread-safe via ContextVar
  • Async-safe (ContextVars propagate to asyncio.to_thread in Python 3.14)

RFC: kida-contextvar-patterns

Classes

_NullRenderContext 1 ▼
Lightweight stub used when generated code runs outside a render context. Silently absorbs `_rc.lin…

Lightweight stub used when generated code runs outside a render context.

Silently absorbs_rc.line = Nassignments without raising. Provides safe no-opcomponent_stack and template_namefor generated def code that pushes/pops component stack frames.

Methods

Internal Methods 1 ▼
__init__ 0 ▼
def __init__(self) -> None
RenderContext 29 ▼
Per-render state isolated from user context. Replaces the _template, _line, _include_depth, _cache…

Per-render state isolated from user context.

Replaces the _template, _line, _include_depth, _cached_blocks, and _cached_stats keys that were previously injected into the user's ctx dict.

Thread Safety: ContextVars are thread-local by design. Each thread/async task has its own RenderContext instance.

Async Safety: ContextVars propagate correctly to asyncio.to_thread() in Python 3.14, so render_async() works without special handling.

Context Contracts:

  • ctx (render context): User-provided dict passed to render(**ctx).
    Framework keys (e.g. ``site``, ``page``) are documented by the framework.
    
  • _meta: Framework metadata (HTMX, CSRF, etc.). See get_meta().

Attributes

Name Type Description
template_name str | None

Current template name for error messages

filename str | None

Source file path for error messages

source str | None —
line int

Current line number (updated during render by generated code)

include_depth int

Current include/embed depth (DoS protection)

max_include_depth int

Maximum allowed include depth

extends_depth int —
max_extends_depth int —
template_stack list[tuple[str, int]]

Stack of (template_name, line) for error traces

component_stack list[tuple[str, int, str]] —
component_call_template str | None —
component_call_line int | None —
cached_blocks dict[str, str]

Site-scoped block cache (shared across includes)

cached_block_names frozenset[str]

Frozenset of cached block names for O(1) lookup

cache_stats dict[str, int] | None

Optional dict for cache hit/miss tracking

declared_definitions frozenset[str] —
import_stack list[str] —
_stacks dict[str, list[str]] —
_providers dict[str, list[Any]] —
_meta dict[str, object] —

Methods

get_meta 2 object ▼
Get framework-specific metadata. Used by frameworks (like Chirp) to pass reque…
def get_meta(self, key: str, default: object = None) -> object

Get framework-specific metadata.

Used by frameworks (like Chirp) to pass request context into templates.

Commonly used for:

  • HTMX headers: hx_request, hx_target, hx_trigger, hx_boosted
  • Security: csrf_token
  • User context: current_user, permissions
Parameters
Name Type Description
key —

Metadata key

default —

Value to return if key not found

Default:None
Returns
object Metadata value or default
set_meta 2 ▼
Set framework-specific metadata.
def set_meta(self, key: str, value: object) -> None
Parameters
Name Type Description
key —

Metadata key

value —

Metadata value

provide 2 ▼
Push a value onto the provider stack for *key*. Used by ``{% provide key = exp…
def provide(self, key: str, value: Any) -> None

Push a value onto the provider stack for key.

Used by{% provide key = expr %}. Stack-based so nested provides shadow outer ones for the same key.

Parameters
Name Type Description
key —
value —
unprovide 1 ▼
Pop the most recent value for *key* from the provider stack. Called in the ``f…
def unprovide(self, key: str) -> None

Pop the most recent value for key from the provider stack.

Called in thefinally block of compiled {% provide %}to guarantee cleanup even when the body raises.

Parameters
Name Type Description
key —
consume 2 Any ▼
Read the current value for *key* from the nearest provider. Returns *default* …
def consume(self, key: str, default: Any = None) -> Any

Read the current value for key from the nearest provider.

Returns default if no provider is active for key. Used by theconsume()template function.

Parameters
Name Type Description
key —
default — Default:None
Returns
Any
check_include_depth 1 ▼
Check if include depth limit exceeded.
def check_include_depth(self, template_name: str) -> None
Parameters
Name Type Description
template_name —

Name of template being included

check_extends_depth 1 ▼
Check if extends chain depth limit exceeded.
def check_extends_depth(self, template_name: str) -> None
Parameters
Name Type Description
template_name —

Name of parent template being extended

child_context 2 RenderContext ▼
Create child context for include/embed with incremented depth. Shares cached_b…
def child_context(self, template_name: str | None = None, *, source: str | None = None) -> RenderContext

Create child context for include/embed with incremented depth.

Shares cached_blocks, cache_stats, and _meta with parent (they're document-wide). Child gets a copy of import_stack to avoid shared mutable state under parallel rendering.

Parameters
Name Type Description
template_name —

Optional override for child template name

Default:None
source —

Optional template source for error snippets in child

Default:None
Returns
RenderContext New RenderContext with incremented include_depth and updated stack
child_context_for_extends 2 RenderContext ▼
Create child context for extends with incremented extends_depth. Used when ren…
def child_context_for_extends(self, parent_name: str, *, source: str | None = None) -> RenderContext

Create child context for extends with incremented extends_depth.

Used when rendering a parent template from {% extends %}. Shares cached_blocks, cache_stats, etc. Does not increment include_depth.

Parameters
Name Type Description
parent_name —

Name of parent template being extended

source —

Optional template source for error snippets in parent

Default:None
Returns
RenderContext

Functions

get_render_context 0 RenderContext | None ▼
Get current render context (None if not in render).
def get_render_context() -> RenderContext | None
Returns
RenderContext | None
get_render_context_required 0 RenderContext ▼
Get current render context, raise if not in render. Used by generated code for…
def get_render_context_required() -> RenderContext

Get current render context, raise if not in render.

Used by generated code for line tracking.

Returns
RenderContext
_make_render_context 8 RenderContext ▼
Construct and return a RenderContext from the given parameters. Shared by rend…
def _make_render_context(template_name: str | None = None, filename: str | None = None, source: str | None = None, cached_blocks: dict[str, str] | None = None, cache_stats: dict[str, int] | None = None, parent_meta: dict[str, object] | None = None, max_extends_depth: int = 50, max_include_depth: int = 50) -> RenderContext

Construct and return a RenderContext from the given parameters.

Shared by render_context() and async_render_context(). Does NOT touch the ContextVar — callers are responsible for set/reset.

Parameters
Name Type Description
template_name str | None

Template name for error messages

Default:None
filename str | None

Source file path for error messages

Default:None
source str | None

Template source for runtime error snippets

Default:None
cached_blocks dict[str, str] | None

Site-scoped block cache

Default:None
cache_stats dict[str, int] | None

Optional dict for cache hit/miss tracking

Default:None
parent_meta dict[str, object] | None

Metadata from parent context to inherit (for framework integration)

Default:None
max_extends_depth int

Maximum extends nesting depth

Default:50
max_include_depth int

Maximum include nesting depth

Default:50
Returns
RenderContext
render_context 8 Iterator[RenderContext] ▼
Context manager for render-scoped state. Creates a new RenderContext and sets …
def render_context(template_name: str | None = None, filename: str | None = None, source: str | None = None, cached_blocks: dict[str, str] | None = None, cache_stats: dict[str, int] | None = None, parent_meta: dict[str, object] | None = None, max_extends_depth: int = 50, max_include_depth: int = 50) -> Iterator[RenderContext]

Context manager for render-scoped state.

Creates a new RenderContext and sets it as the current context for the duration of the with block. Automatically restores the previous context when exiting.

Parameters
Name Type Description
template_name str | None

Template name for error messages

Default:None
filename str | None

Source file path for error messages

Default:None
source str | None

Template source for runtime error snippets

Default:None
cached_blocks dict[str, str] | None

Site-scoped block cache

Default:None
cache_stats dict[str, int] | None

Optional dict for cache hit/miss tracking

Default:None
parent_meta dict[str, object] | None

Metadata from parent context to inherit (for framework integration)

Default:None
max_extends_depth int Default:50
max_include_depth int Default:50
Returns
Iterator[RenderContext]
async_render_context 8 AsyncIterator[RenderCont… ▼
Async context manager for render-scoped state. Identical to render_context() b…
async
async def async_render_context(template_name: str | None = None, filename: str | None = None, source: str | None = None, cached_blocks: dict[str, str] | None = None, cache_stats: dict[str, int] | None = None, parent_meta: dict[str, object] | None = None, max_extends_depth: int = 50, max_include_depth: int = 50) -> AsyncIterator[RenderContext]

Async context manager for render-scoped state.

Identical to render_context() but for use withasync with. ContextVar reset is synchronous — the async wrapper is structural only.

Part of RFC: rfc-async-rendering.

Parameters
Name Type Description
template_name str | None

Template name for error messages

Default:None
filename str | None

Source file path for error messages

Default:None
source str | None

Template source for runtime error snippets

Default:None
cached_blocks dict[str, str] | None

Site-scoped block cache

Default:None
cache_stats dict[str, int] | None

Optional dict for cache hit/miss tracking

Default:None
parent_meta dict[str, object] | None

Metadata from parent context to inherit (for framework integration)

Default:None
max_extends_depth int Default:50
max_include_depth int Default:50
Returns
AsyncIterator[RenderContext]
set_render_context 1 Token[RenderContext | No… ▼
Set a RenderContext and return the reset token. Low-level function for cases w…
def set_render_context(ctx: RenderContext) -> Token[RenderContext | None]

Set a RenderContext and return the reset token.

Low-level function for cases where the context manager isn't suitable (e.g., nested include/embed calls that need to restore context manually).

Parameters
Name Type Description
ctx RenderContext

The RenderContext to set

Returns
Token[RenderContext | None]
reset_render_context 1 None ▼
Reset render context using a token from set_render_context.
def reset_render_context(token: Token[RenderContext | None]) -> None
Parameters
Name Type Description
token Token[RenderContext | None]

Token returned from set_render_context()