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 — Preserveslist + 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 all
Environmentoptions.
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 to
template/inheritance.pywith cached inheritance chain and effective block maps. - enhance_template_error() — Pure function in
template/error_enhancement.py; converts generic exceptions toTemplateRuntimeErrorwith context. - Attribute helpers —
safe_getattr()andgetattr_preserve_none()moved totemplate/helpers.py.
Fixed
- Inherited block benchmark regression — Lock acquisition on cache-hit path was adding ~2µs per
render_block()call.
Upgrade Notes
- No breaking changes — Existing templates continue to work.
- Polymorphic
+— Only affects expressions where both operands are non-string and incompatible (e.g.{{ count + items }}int + list). Previously stringified; now raisesTypeError. String concat ({{ count + " items" }}) unchanged.