Module

analysis.purity

Purity analysis for template introspection.

Determines if expressions and blocks are pure (deterministic). Pure blocks produce the same output for the same inputs.

Classes

PurityAnalyzer 45
Determine if an expression or block is pure (deterministic). Pure expressions produce the same out…

Determine if an expression or block is pure (deterministic).

Pure expressions produce the same output for the same inputs. This is used to determine cache safety.

Conservative: defaults to "unknown" when uncertain.

Purity Rules:

  • Constants, variables, attribute access: pure
  • Binary/unary operations, comparisons: pure
  • Known pure filters (upper, lower, sort, etc.): pure
  • Known impure filters (random, shuffle): impure
  • Unknown filters/functions: unknown

Methods

analyze 1 PurityLevel
Analyze a node and return its purity level.
def analyze(self, node: Node) -> PurityLevel
Parameters
Name Type Description
node

AST node to analyze.

Returns
PurityLevel "pure", "impure", or "unknown"
Internal Methods 44
__init__ 3
Initialize analyzer with optional extensions.
def __init__(self, extra_pure_functions: frozenset[str] | None = None, extra_impure_filters: frozenset[str] | None = None, template_resolver: Any | None = None) -> None
Parameters
Name Type Description
extra_pure_functions

Additional functions to treat as pure.

Default:None
extra_impure_filters

Additional filters to treat as impure.

Default:None
template_resolver

Optional callback(name: str) -> Template | None to resolve included templates. If None, includes return "unknown".

Default:None
_visit 1 PurityLevel
Visit a node and determine purity.
def _visit(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_children 1 PurityLevel
Visit children and combine purity.
def _visit_children(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_const 1 PurityLevel
Constants are pure.
def _visit_const(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_name 1 PurityLevel
Variable access is pure (reading doesn't mutate).
def _visit_name(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_getattr 1 PurityLevel
Attribute access is pure.
def _visit_getattr(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_optionalgetattr 1 PurityLevel
Optional attribute access is pure.
def _visit_optionalgetattr(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_getitem 1 PurityLevel
Subscript access is pure.
def _visit_getitem(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_optionalgetitem 1 PurityLevel
Optional subscript access is pure.
def _visit_optionalgetitem(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_binop 1 PurityLevel
Binary operations are pure.
def _visit_binop(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_unaryop 1 PurityLevel
Unary operations are pure.
def _visit_unaryop(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_compare 1 PurityLevel
Comparisons are pure.
def _visit_compare(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_boolop 1 PurityLevel
Boolean operations are pure.
def _visit_boolop(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_condexpr 1 PurityLevel
Conditional expressions are pure if all parts are pure.
def _visit_condexpr(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_nullcoalesce 1 PurityLevel
Null coalescing is pure.
def _visit_nullcoalesce(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_concat 1 PurityLevel
String concatenation is pure.
def _visit_concat(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_range 1 PurityLevel
Range literals are pure.
def _visit_range(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_slice 1 PurityLevel
Slice expressions are pure.
def _visit_slice(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_list 1 PurityLevel
List literals are pure if all items are pure.
def _visit_list(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_tuple 1 PurityLevel
Tuple literals are pure if all items are pure.
def _visit_tuple(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_dict 1 PurityLevel
Dict literals are pure if all keys and values are pure.
def _visit_dict(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_filter 1 PurityLevel
Filter purity depends on the filter.
def _visit_filter(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_pipeline 1 PurityLevel
Pipeline purity depends on all filters in the chain.
def _visit_pipeline(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_funccall 1 PurityLevel
Function call purity depends on the function.
def _visit_funccall(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_test 1 PurityLevel
Tests are pure (they're just predicates).
def _visit_test(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_for 1 PurityLevel
For loops are pure if body is pure.
def _visit_for(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_if 1 PurityLevel
Conditionals are pure if all branches are pure.
def _visit_if(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_match 1 PurityLevel
Match statements are pure if all branches are pure.
def _visit_match(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_output 1 PurityLevel
Output is pure if expression is pure.
def _visit_output(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_data 1 PurityLevel
Static data is pure.
def _visit_data(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_cache 1 PurityLevel
Cache blocks: the body is evaluated, but result is cached. The block itself is…
def _visit_cache(self, node: Any) -> PurityLevel

Cache blocks: the body is evaluated, but result is cached.

The block itself is pure if the body is pure.

Parameters
Name Type Description
node
Returns
PurityLevel
_visit_block 1 PurityLevel
Block is pure if body is pure.
def _visit_block(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_with 1 PurityLevel
With blocks are pure if bindings and body are pure.
def _visit_with(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_withconditional 1 PurityLevel
Conditional with is pure if expr and body are pure.
def _visit_withconditional(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_set 1 PurityLevel
Set is pure if value is pure.
def _visit_set(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_let 1 PurityLevel
Let is pure if value is pure.
def _visit_let(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_capture 1 PurityLevel
Capture is pure if body is pure.
def _visit_capture(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_include 1 PurityLevel
Include purity depends on included template. If template_resolver is provided …
def _visit_include(self, node: Any) -> PurityLevel

Include purity depends on included template.

If template_resolver is provided and template name is a constant, resolves and analyzes the included template. Otherwise returns "unknown".

Parameters
Name Type Description
node
Returns
PurityLevel
_visit_extends 1 PurityLevel
Extends is unknown (depends on parent template).
def _visit_extends(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_def 1 PurityLevel
Function definition is pure if body is pure.
def _visit_def(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_macro 1 PurityLevel
Macro definition (same as def).
def _visit_macro(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_inlinedfilter 1 PurityLevel
Inlined filter is pure (only pure filters are inlined).
def _visit_inlinedfilter(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_marksafe 1 PurityLevel
Mark safe is pure.
def _visit_marksafe(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel
_visit_await 1 PurityLevel
Await is unknown (async operations may have side effects).
def _visit_await(self, node: Any) -> PurityLevel
Parameters
Name Type Description
node
Returns
PurityLevel

Functions

_combine_purity 2 PurityLevel
Combine two purity levels (take worst case).
def _combine_purity(a: PurityLevel, b: PurityLevel) -> PurityLevel
Parameters
Name Type Description
a PurityLevel
b PurityLevel
Returns
PurityLevel