Module

analysis.dependencies

Dependency analysis for template introspection.

Extracts context variable dependencies from AST expressions and blocks. Produces a conservative superset — may include unused paths but never excludes paths that are actually used.

Classes

DependencyWalker 72
Extract context variable dependencies from AST expressions. Walks the AST and collects all context…

Extract context variable dependencies from AST expressions.

Walks the AST and collects all context paths (e.g., "page.title", "site.pages") that an expression or block may access.

Produces a conservative superset: may include paths not actually used at runtime, but never excludes paths that are used.

Thread-safe: Creates new state for each analyze() call.

Scope Handling:

  • Loop variables ({% for x in items %}) are excluded
  • With bindings ({% with expr as x %}) are excluded
  • Function arguments ({% def fn(x) %}) are excluded
  • Set/let assignments create local scope

Methods

analyze 1 frozenset[str]
Analyze a node and return all context dependencies.
def analyze(self, node: Node) -> frozenset[str]
Parameters
Name Type Description
node

AST node to analyze (Block, Template, expression, etc.)

Returns
frozenset[str] Frozen set of context paths (e.g., {"page.title", "site.pages"})
visit_Name 1
Handle variable reference.
def visit_Name(self, node: Name) -> None
Parameters
Name Type Description
node
visit_Getattr 1
Handle attribute access: obj.attr
def visit_Getattr(self, node: Getattr) -> None
Parameters
Name Type Description
node
visit_OptionalGetattr 1
Handle optional attribute access: obj?.attr
def visit_OptionalGetattr(self, node: OptionalGetattr) -> None
Parameters
Name Type Description
node
visit_Getitem 1
Handle subscript access: obj[key]
def visit_Getitem(self, node: Getitem) -> None
Parameters
Name Type Description
node
visit_OptionalGetitem 1
Handle optional subscript access: obj?[key]
def visit_OptionalGetitem(self, node: OptionalGetitem) -> None
Parameters
Name Type Description
node
visit_For 1
Handle for loop: push loop variable into scope.
def visit_For(self, node: For | AsyncFor) -> None
Parameters
Name Type Description
node
visit_AsyncFor 1
Handle async for loop (same as regular for).
def visit_AsyncFor(self, node: AsyncFor) -> None
Parameters
Name Type Description
node
visit_While 1
Handle while loop.
def visit_While(self, node: While) -> None
Parameters
Name Type Description
node
visit_With 1
Handle with block: {% with x = expr %}...{% end %}
def visit_With(self, node: With) -> None
Parameters
Name Type Description
node
visit_WithConditional 1
Handle conditional with: {% with expr as target %}
def visit_WithConditional(self, node: WithConditional) -> None
Parameters
Name Type Description
node
visit_Def 1
Handle function definition: push args into scope.
def visit_Def(self, node: Def) -> None
Parameters
Name Type Description
node
visit_Region 1
Handle region: push params into scope, visit body (same as def).
def visit_Region(self, node: Region) -> None
Parameters
Name Type Description
node
visit_Macro 1
Handle macro definition (same as def).
def visit_Macro(self, node: Node) -> None
Parameters
Name Type Description
node
visit_Set 1
Handle set statement.
def visit_Set(self, node: Set) -> None
Parameters
Name Type Description
node
visit_Let 1
Handle let statement (template-scoped).
def visit_Let(self, node: Let) -> None
Parameters
Name Type Description
node
visit_Export 1
Handle export statement.
def visit_Export(self, node: Export) -> None
Parameters
Name Type Description
node
visit_Capture 1
Handle capture block: {% capture name %}...{% end %}
def visit_Capture(self, node: Capture) -> None
Parameters
Name Type Description
node
visit_Filter 1
Handle filter expression.
def visit_Filter(self, node: Filter) -> None
Parameters
Name Type Description
node
visit_OptionalFilter 1
Handle optional filter expression (same as regular filter).
def visit_OptionalFilter(self, node: Filter) -> None
Parameters
Name Type Description
node
visit_Pipeline 1
Handle pipeline expression: expr |> filter1 |> filter2
def visit_Pipeline(self, node: Pipeline) -> None
Parameters
Name Type Description
node
visit_SafePipeline 1
Handle safe pipeline expression (same as regular pipeline).
def visit_SafePipeline(self, node: SafePipeline) -> None
Parameters
Name Type Description
node
visit_FuncCall 1
Handle function call.
def visit_FuncCall(self, node: FuncCall) -> None
Parameters
Name Type Description
node
visit_NullCoalesce 1
Handle null coalescing: a ?? b
def visit_NullCoalesce(self, node: NullCoalesce) -> None
Parameters
Name Type Description
node
visit_CondExpr 1
Handle conditional expression: a if cond else b
def visit_CondExpr(self, node: CondExpr) -> None
Parameters
Name Type Description
node
visit_BoolOp 1
Handle boolean operations: a and b, a or b
def visit_BoolOp(self, node: BoolOp) -> None
Parameters
Name Type Description
node
visit_BinOp 1
Handle binary operations: a + b, a - b, etc.
def visit_BinOp(self, node: BinOp) -> None
Parameters
Name Type Description
node
visit_UnaryOp 1
Handle unary operations: -a, not a
def visit_UnaryOp(self, node: UnaryOp) -> None
Parameters
Name Type Description
node
visit_Compare 1
Handle comparisons: a < b < c
def visit_Compare(self, node: Compare) -> None
Parameters
Name Type Description
node
visit_Range 1
Handle range literal: start..end or start...end
def visit_Range(self, node: Range) -> None
Parameters
Name Type Description
node
visit_Slice 1
Handle slice expression: [start:stop:step]
def visit_Slice(self, node: Slice) -> None
Parameters
Name Type Description
node
visit_Concat 1
Handle string concatenation: a ~ b ~ c
def visit_Concat(self, node: Concat) -> None
Parameters
Name Type Description
node
visit_List 1
Handle list literal: [a, b, c]
def visit_List(self, node: List) -> None
Parameters
Name Type Description
node
visit_ListComp 1
Handle list comprehension: [expr for x in iterable if cond] The iterable is a …
def visit_ListComp(self, node: ListComp) -> None

Handle list comprehension: [expr for x in iterable if cond]

The iterable is a context dependency. The target variable is local to the comprehension — elt and ifs must be visited with it in scope.

Parameters
Name Type Description
node
visit_Tuple 1
Handle tuple literal: (a, b, c)
def visit_Tuple(self, node: Tuple) -> None
Parameters
Name Type Description
node
visit_Dict 1
Handle dict literal: {a: b, c: d}
def visit_Dict(self, node: Dict) -> None
Parameters
Name Type Description
node
visit_Test 1
Handle test expression: x is defined
def visit_Test(self, node: Test) -> None
Parameters
Name Type Description
node
visit_Match 1
Handle match statement.
def visit_Match(self, node: Match) -> None
Parameters
Name Type Description
node
visit_Trans 1
Handle trans block: walk variable expressions and count_expr.
def visit_Trans(self, node: Trans) -> None
Parameters
Name Type Description
node
visit_TransVar 1
Handle trans variable binding: walk the expression.
def visit_TransVar(self, node: TransVar) -> None
Parameters
Name Type Description
node
visit_Cache 1
Handle cache block: {% cache key %}...{% end %}
def visit_Cache(self, node: Cache) -> None
Parameters
Name Type Description
node
visit_Include 1
Handle include statement.
def visit_Include(self, node: Include) -> None
Parameters
Name Type Description
node
visit_Import 1
Handle import statement.
def visit_Import(self, node: Import) -> None
Parameters
Name Type Description
node
visit_FromImport 1
Handle from...import statement.
def visit_FromImport(self, node: FromImport) -> None
Parameters
Name Type Description
node
visit_If 1
Handle if statement.
def visit_If(self, node: If) -> None
Parameters
Name Type Description
node
visit_Output 1
Handle output: {{ expr }}
def visit_Output(self, node: Output) -> None
Parameters
Name Type Description
node
visit_Block 1
Handle block: {% block name %}...{% end %}
def visit_Block(self, node: Block) -> None
Parameters
Name Type Description
node
visit_Extends 1
Handle extends: {% extends 'base.html' %}
def visit_Extends(self, node: Extends) -> None
Parameters
Name Type Description
node
visit_Template 1
Handle template root node.
def visit_Template(self, node: Template) -> None
Parameters
Name Type Description
node
visit_FilterBlock 1
Handle filter block: {% filter upper %}...{% end %}
def visit_FilterBlock(self, node: FilterBlock) -> None
Parameters
Name Type Description
node
visit_CallBlock 1
Handle call block: {% call name(args) %}body{% end %} with named slots.
def visit_CallBlock(self, node: CallBlock) -> None
Parameters
Name Type Description
node
visit_Spaceless 1
Handle spaceless block.
def visit_Spaceless(self, node: Spaceless) -> None
Parameters
Name Type Description
node
visit_Autoescape 1
Handle autoescape block.
def visit_Autoescape(self, node: Autoescape) -> None
Parameters
Name Type Description
node
visit_Trim 1
Handle trim block.
def visit_Trim(self, node: Trim) -> None
Parameters
Name Type Description
node
visit_Embed 1
Handle embed: {% embed 'card.html' %}...{% end %}
def visit_Embed(self, node: Embed) -> None
Parameters
Name Type Description
node
visit_Await 1
Handle await expression.
def visit_Await(self, node: Await) -> None
Parameters
Name Type Description
node
visit_MarkSafe 1
Handle safe marker.
def visit_MarkSafe(self, node: MarkSafe) -> None
Parameters
Name Type Description
node
visit_InlinedFilter 1
Handle inlined filter (optimization).
def visit_InlinedFilter(self, node: InlinedFilter) -> None
Parameters
Name Type Description
node
visit_Const 1
Constants have no dependencies.
def visit_Const(self, node: Const) -> None
Parameters
Name Type Description
node
visit_Data 1
Static data has no dependencies.
def visit_Data(self, node: Data) -> None
Parameters
Name Type Description
node
visit_Raw 1
Raw blocks have no dependencies.
def visit_Raw(self, node: Raw) -> None
Parameters
Name Type Description
node
visit_Slot 1
Slots have no dependencies.
def visit_Slot(self, node: Slot) -> None
Parameters
Name Type Description
node
visit_Break 1
Break has no dependencies.
def visit_Break(self, node: Break) -> None
Parameters
Name Type Description
node
visit_Continue 1
Continue has no dependencies.
def visit_Continue(self, node: Continue) -> None
Parameters
Name Type Description
node
visit_Do 1
Handle do statement.
def visit_Do(self, node: Node) -> None
Parameters
Name Type Description
node
visit_LoopVar 1
Loop variable access (loop.index, etc.) - no context deps.
def visit_LoopVar(self, node: LoopVar) -> None
Parameters
Name Type Description
node
Internal Methods 6
__init__ 0
Initialize walker (stateless until analyze() is called).
def __init__(self) -> None
_build_path 1 str | None
Build dotted path from chained attribute/item access. Returns None if the path…
def _build_path(self, node: Node) -> str | None

Build dotted path from chained attribute/item access.

Returns None if the path can't be determined statically (e.g., dynamic keys, local variables).

Parameters
Name Type Description
node
Returns
str | None
_extract_targets 1 set[str]
Extract variable names from assignment target.
def _extract_targets(self, node: Node) -> set[str]
Parameters
Name Type Description
node
Returns
set[str]
_push_scope 1
Push a new scope and update the flat locals set.
def _push_scope(self, names: set[str]) -> None
Parameters
Name Type Description
names
_pop_scope 0
Pop the top scope and rebuild the flat locals set.
def _pop_scope(self) -> None
_is_local 1 bool
Check if a name is in local scope (O(1) via flat set).
def _is_local(self, name: str) -> bool
Parameters
Name Type Description
name
Returns
bool