Module

template.helpers

Pure runtime helper functions injected into the template namespace.

These functions are called by compiled template code at render time. None of them close over Environment state — they are pure functions that use only their parameters and deferred imports.

Thread-Safety: All functions are stateless and safe for concurrent use.

Classes

_Undefined 11
Sentinel for failed attribute access on objects. - ``str(_Undefined())`` returns ``""`` (template …

Sentinel for failed attribute access on objects.

  • str(_Undefined()) returns ""(template output unchanged)
  • bool(_Undefined()) returns False(falsy guard works)
  • is_defined()recognises it as "not defined"

Methods

get 2 object
Return default for any key; enables obj.missing.get('x', 'fb') pattern. If ``d…
def get(self, key: str, default: object | None = _no_default) -> object

Return default for any key; enables obj.missing.get('x', 'fb') pattern.

Ifdefaultis provided, return it unchanged (including an explicit None). If default is omitted, return UNDEFINEDso Kida can distinguish an omitted default from an explicitNone.

Parameters
Name Type Description
key
default Default:_no_default
Returns
object
keys 0 list[str]
Empty keys; enables {% for k in missing.keys() %} without error.
def keys(self) -> list[str]
Returns
list[str]
values 0 list[object]
Empty values; enables {% for v in missing.values() %} without error.
def values(self) -> list[object]
Returns
list[object]
items 0 list[tuple[str, object]]
Empty items; enables {% for k, v in missing.items() %} without error.
def items(self) -> list[tuple[str, object]]
Returns
list[tuple[str, object]]
Internal Methods 7
__str__ 0 str
def __str__(self) -> str
Returns
str
__repr__ 0 str
def __repr__(self) -> str
Returns
str
__bool__ 0 bool
def __bool__(self) -> bool
Returns
bool
__eq__ 1 bool
def __eq__(self, other: object) -> bool
Parameters
Name Type Description
other
Returns
bool
__hash__ 0 int
def __hash__(self) -> int
Returns
int
__iter__ 0
Empty iterator so ``{% for x in missing %}`` silently yields nothing.
def __iter__(self)
__len__ 0 int
def __len__(self) -> int
Returns
int

Functions

safe_getattr 2 object
Get attribute with dict fallback and None-safe handling. Resolution order: - D…
def safe_getattr(obj: object, name: str) -> object

Get attribute with dict fallback and None-safe handling.

Resolution order:

  • Dicts: subscript first (user data), getattr fallback (methods). This prevents dict method names likeitems, keys, values, getfrom shadowing user data keys.
  • Objects: getattr first, subscript fallback.

None Handling (like Hugo/Go templates):

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

Not-Found Handling:

  • Returns theUNDEFINEDsentinel when the attribute/key is not found.UNDEFINED stringifies as ""(so template output is unchanged) butis_defined()recognises it as not defined, fixingx.missing is defined→ False.

Complexity: O(1)

Parameters
Name Type Description
obj object
name str
Returns
object
getattr_preserve_none 2 object
Get attribute with dict fallback, preserving None values. Like safe_getattr bu…
def getattr_preserve_none(obj: object, name: str) -> object

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.

Resolution order matches safe_getattr: dicts try subscript first.

Complexity: O(1)

Parameters
Name Type Description
obj object
name str
Returns
object
_raise_undefined_attr 3 Any
Raise UndefinedError for missing attribute/key access.
def _raise_undefined_attr(obj: object, name: str, *, preserve_none: bool = False) -> Any
Parameters
Name Type Description
obj object
name str
preserve_none bool Default:False
Returns
Any
strict_getattr 2 object
Like safe_getattr but raises UndefinedError on missing attributes. Used when E…
def strict_getattr(obj: object, name: str) -> object

Like safe_getattr but raises UndefinedError on missing attributes.

Used when Environment(strict_undefined=True) to catch typos in attribute access at render time.

Parameters
Name Type Description
obj object
name str
Returns
object
strict_getattr_preserve_none 2 object
Like getattr_preserve_none but raises UndefinedError on missing attributes.
def strict_getattr_preserve_none(obj: object, name: str) -> object
Parameters
Name Type Description
obj object
name str
Returns
object
markup_concat 2 str
Concatenate for ~ operator, preserving Markup safety. If either operand is Mar…
def markup_concat(left: Any, right: Any) -> str

Concatenate for ~ operator, preserving Markup safety.

If either operand is Markup, the result is Markup and the non-Markup operand is HTML-escaped via Markup.add/radd. If neither is Markup, both are converted to plain strings.

Parameters
Name Type Description
left Any
right Any
Returns
str
record_filter_usage 3 Any
Record filter usage for profiling, returning the result unchanged. Called by c…
def record_filter_usage(acc: RenderAccumulator | None, name: str, result: Any) -> Any

Record filter usage for profiling, returning the result unchanged.

Called by compiled code for every filter invocation. When profiling is disabled (acc is None), the cost is a single falsy check + return.

Parameters
Name Type Description
acc RenderAccumulator | None

RenderAccumulator instance, or None when profiling is off

name str

Filter name for recording

result Any

The filter's return value (passed through unchanged)

Returns
Any
record_macro_usage 3 Any
Record macro ({% def %}) call for profiling, returning the result unchanged. C…
def record_macro_usage(acc: RenderAccumulator | None, name: str, result: Any) -> Any

Record macro ({% def %}) call for profiling, returning the result unchanged.

Called by compiled code for every macro invocation. When profiling is disabled (acc is None), the cost is a single falsy check + return.

Parameters
Name Type Description
acc RenderAccumulator | None

RenderAccumulator instance, or None when profiling is off

name str

Macro/def name for recording

result Any

The macro's return value (passed through unchanged)

Returns
Any
lookup 2 Any
Look up a variable in strict mode. In strict mode, undefined variables raise U…
def lookup(ctx: dict[str, Any], var_name: str) -> Any

Look up a variable in strict mode.

In strict mode, undefined variables raise UndefinedError instead of silently returning None. This catches typos and missing variables early, improving debugging experience.

Performance:

  • Fast path (defined var): O(1) dict lookup, no imports
  • Error path: Raises UndefinedError with template context
Parameters
Name Type Description
ctx dict[str, Any]
var_name str
Returns
Any
lookup_scope 3 Any
Lookup variable in scope stack (top to bottom), then ctx. Checks scopes from i…
def lookup_scope(ctx: dict[str, Any], scope_stack: list[dict[str, Any]], var_name: str) -> Any

Lookup variable in scope stack (top to bottom), then ctx.

Checks scopes from innermost to outermost, then falls back to ctx. Raises UndefinedError if not found (strict mode).

Parameters
Name Type Description
ctx dict[str, Any]
scope_stack list[dict[str, Any]]
var_name str
Returns
Any
default_safe 3 Any
Safe default filter that works with strict mode. In strict mode, the value exp…
def default_safe(value_fn: Callable[[], Any], default_value: Any = '', boolean: bool = False) -> Any

Safe default filter that works with strict mode.

In strict mode, the value expression might raise UndefinedError. This helper catches that and returns the default value.

Parameters
Name Type Description
value_fn Callable[[], Any]

A lambda that evaluates the value expression

default_value Any

The fallback value if undefined or None/falsy

Default:''
boolean bool

If True, check for falsy values; if False, check for None only

Default:False
Returns
Any
is_defined 1 bool
Check if a value is defined in strict mode. In strict mode, we need to catch U…
def is_defined(value_fn: Callable[[], Any]) -> bool

Check if a value is defined in strict mode.

In strict mode, we need to catch UndefinedError to determine if a variable is defined.

A value is considered undefined when:

  • The variable doesn't exist (raises UndefinedError)
  • The value isNone
  • The value is the_Undefinedsentinel (failed attribute access)

This meansobj.missing_attr is definedcorrectly returns False even whenobj itself exists, because _safe_getattrreturns theUNDEFINEDsentinel for missing attributes.

Parameters
Name Type Description
value_fn Callable[[], Any]

A lambda that evaluates the value expression

Returns
bool
null_coalesce 2 Any
Safe null coalescing that handles undefined variables. In strict mode, the lef…
def null_coalesce(left_fn: Callable[[], Any], right_fn: Callable[[], Any]) -> Any

Safe null coalescing that handles undefined variables.

In strict mode, the left expression might raise UndefinedError. This helper catches that and returns the right value.

Unlike the default filter:

  • Returns right ONLY if left is None or undefined
  • Does NOT treat falsy values (0, '', False, []) as needing replacement
Parameters
Name Type Description
left_fn Callable[[], Any]

A lambda that evaluates the left expression

right_fn Callable[[], Any]

A lambda that evaluates the right expression (lazy)

Returns
Any
spaceless 1 str
Remove whitespace between HTML tags. RFC: kida-modern-syntax-features
def spaceless(html: str) -> str
Parameters
Name Type Description
html str
Returns
str
add_polymorphic 2 str
Polymorphic + operator with safe string-concatenation fallback. **Goals:** - K…
def add_polymorphic(left: Any, right: Any) -> str

Polymorphic + operator with safe string-concatenation fallback.

Goals:

  • Keep natural Python behavior for compatible operand types (list + list, tuple + tuple, etc.).
  • Support Jinja-style string ergonomics (count + " items").
  • Avoid silently stringifying collection arithmetic, which can explode output.
Parameters
Name Type Description
left Any

Left operand

right Any

Right operand

Returns
str
coerce_numeric 1 int | float
Coerce value to numeric type for arithmetic operations. Handles Markup objects…
def coerce_numeric(value: Any) -> int | float

Coerce value to numeric type for arithmetic operations.

Handles Markup objects (from macros) and strings that represent numbers. This prevents string multiplication when doing arithmetic with macro results.

Parameters
Name Type Description
value Any

Any value, typically Markup from macro or filter result

Returns
int | float
str_safe 1 str
Convert value to string, treating None as empty string. This is used for templ…
def str_safe(value: Any) -> str

Convert value to string, treating None as empty string.

This is used for template output so that optional chaining expressions that evaluate to None produce empty output rather than the literal string 'None'.

Preserves Markup instances (and objects with html) so that the escape function can detect them and avoid double-escaping.

RFC: kida-modern-syntax-features — needed for optional chaining.

Parameters
Name Type Description
value Any
Returns
str
consume 2 Any
Read a value from the nearest ``{% provide %}`` ancestor. Template-level funct…
def consume(key: str, default: Any = None) -> Any

Read a value from the nearest{% provide %}ancestor.

Template-level function that reads from the RenderContext provider stack. Returns default if no provider is active for key.

Example::

{% provide color = "red" %}
    {{ consume("color") }}  {# outputs: red #}
{% end %}
Parameters
Name Type Description
key str
default Any Default:None
Returns
Any
optional_call 3 Any
Call callee only if it is not None or UNDEFINED. Used for obj?.method() so tha…
def optional_call(callee: Any, *args: object, **kwargs: object) -> Any

Call callee only if it is not None or UNDEFINED.

Used for obj?.method() so that when obj is None or obj.attr is UNDEFINED, the call short-circuits and returns UNDEFINED (outputs as "").

Parameters
Name Type Description
callee Any
*args object
**kwargs object
Returns
Any