Kida 0.2.5

render_block performance, filter modularization, polymorphic + fix, release automation

Status: Released March 7, 2026.

This release focuses on performance, maintainability, and release automation. Highlights include a ~2µs improvement perrender_block() call, filter modularization, safer polymorphic +operator behavior, and a PyPI publish workflow with regression gates.

Highlights

  • render_block()performance — Lock removed from cache-hit path; ~2µs per call improvement.
  • Filter modularization — Built-in filters split into category submodules for maintainability.
  • Polymorphic+ fix — Preserves list + list, tuple + tuple; avoids silently stringifying collections.
  • PyPI publish workflow — Regression gate (tests + benchmarks) runs before publish.
  • Docs — Tests reference and configuration reference pages.

Added

Filter Modularization

Built-in filters are now organized into category submodules:_collections, _debug, _html_security, _misc, _numbers, _string, _type_conversion, _validation. The main _impl.pyacts as a registry. Improves maintainability and discoverability.

Documentation

  • Tests reference — New reference page for all built-in tests (defined, undefined, string, number, mapping, comparison tests, HTMX tests).
  • Configuration reference — Expanded docs for allEnvironmentoptions.

Benchmark Dimensions

New benchmark suites: static_context vs dynamic render, bytecode cache disk load, introspection (template_metadata, list_blocks, get_template_structure, render_block).benchmark_compare.shintegrated into release gate.

Release Automation

  • PyPI publish workflow.github/workflows/python-publish.ymlruns on release publish. Regression gate (expression tests, render output guards, benchmark compare) before build and upload.
  • Render output regression guards — Test suite for non-empty render, loop count parity, include chain counts, inheritance block deduplication, stream/render parity.

Changed

render_block() Performance

Lock removed from cache-hit path in_effective_block_map and _inheritance_chain. Cache-hit reads are lock-free; lock acquired only on miss for double-check.

Polymorphic + Operator

add_polymorphic() now preserves Python semantics for compatible types (list + list, tuple + tuple). Avoids silently stringifying collection arithmetic. String concatenation ({{ count + " items" }}) unchanged when one operand is string-like.

Template Refactor

  • TemplateInheritanceMixin — Extracted totemplate/inheritance.pywith cached inheritance chain and effective block maps.
  • enhance_template_error() — Pure function intemplate/error_enhancement.py; converts generic exceptions to TemplateRuntimeErrorwith context.
  • Attribute helperssafe_getattr() and getattr_preserve_none() moved to template/helpers.py.

Fixed

  • Inherited block benchmark regression — Lock acquisition on cache-hit path was adding ~2µs perrender_block()call.

Upgrade Notes

  1. No breaking changes — Existing templates continue to work.
  2. Polymorphic+ — Only affects expressions where both operands are non-string and incompatible (e.g. {{ count + items }} int + list). Previously stringified; now raises TypeError. String concat ({{ count + " items" }}) unchanged.