Kida 0.1.2
RenderContext isolation and profiling
Released: January 13, 2026
ContextVar-based state isolation and opt-in profiling for template rendering.
Highlights
- 🔒 RenderContext — Per-render state isolated from user context
- 📊 RenderAccumulator — Opt-in profiling with zero overhead when disabled
- ⚡ F-string coalescing — 11% faster output-heavy templates
- 🧹 Clean user context — No more internal key pollution
Added
RenderContext
ContextVar-based per-render state management that isolates internal state from user context:
from kida import get_render_context
# During render, access render state without ctx pollution
ctx = get_render_context()
print(ctx.template_name) # Current template
print(ctx.line) # Current line number
print(ctx.include_depth) # Include nesting level
Benefits:
- User
ctxdicts are now clean (no_template,_line, etc.) - No key collision risk (users can use
_templateas a variable) - Thread-safe via ContextVar
- Async-safe (ContextVars propagate to
asyncio.to_threadin Python 3.14)
RenderAccumulator
Opt-in profiling for debugging slow templates:
from kida import profiled_render
with profiled_render() as metrics:
html = template.render(page=page)
print(metrics.summary())
# {
# "total_ms": 12.5,
# "blocks": {"content": {"ms": 8.2, "calls": 1}},
# "macros": {"render_card": 15},
# "includes": {"partials/sidebar.html": 1},
# "filters": {"escape": 45, "truncate": 12},
# }
Zero overhead when profiling is disabled — get_accumulator() returns None.
F-string Coalescing
Consecutive template outputs are merged into single f-string appends:
# Before: Multiple append calls
_out.append(escape(x))
_out.append(" - ")
_out.append(escape(y))
# After: Single f-string append
_out.append(f"{escape(x)} - {escape(y)}")
~11% faster for output-heavy templates. Controlled via:
Environment.fstring_coalescing(enabled by default)Environment.pure_filtersfor custom filter registration
Public API Exports
New exports fromkida:
RenderContext,render_context,get_render_context,get_render_context_requiredRenderAccumulator,profiled_render,get_accumulator,timed_block
Changed
Clean User Context
Template rendering no longer injects internal keys into user context:
| Before (0.1.1) | After (0.1.2) |
|---|---|
ctx["_template"] |
get_render_context().template_name |
ctx["_line"] |
get_render_context().line |
ctx["_include_depth"] |
get_render_context().include_depth |
Users can now safely use_template or _lineas variable names.
Removed
{% do %}Directive
The{% do %} directive has been removed. Use {% set _ = expr %}for side effects:
{# Before #}
{% do my_list.append(item) %}
{# After #}
{% set _ = my_list.append(item) %}
Upgrade Guide
- If using
{% do %}: Replace with{% set _ = expr %} - If accessing
ctx["_template"]: Useget_render_context().template_name - If using internal keys as variables: No changes needed (collision risk removed)