Classes
DependencyWalker
66
▼
Extract context variable dependencies from AST expressions.
Walks the AST and collects all context…
DependencyWalker
66
▼
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.
analyze
1
frozenset[str]
▼
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"})
Internal Methods 65 ▼
__init__
0
▼
Initialize walker (stateless until analyze() is called).
__init__
0
▼
def __init__(self) -> None
_visit
1
▼
Visit a node and its children.
_visit
1
▼
def _visit(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_children
1
▼
Visit all child nodes (generic handler).
_visit_children
1
▼
def _visit_children(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_name
1
▼
Handle variable reference.
_visit_name
1
▼
def _visit_name(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_getattr
1
▼
Handle attribute access: obj.attr
_visit_getattr
1
▼
def _visit_getattr(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_optionalgetattr
1
▼
Handle optional attribute access: obj?.attr
_visit_optionalgetattr
1
▼
def _visit_optionalgetattr(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_getitem
1
▼
Handle subscript access: obj[key]
_visit_getitem
1
▼
def _visit_getitem(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_optionalgetitem
1
▼
Handle optional subscript access: obj?[key]
_visit_optionalgetitem
1
▼
def _visit_optionalgetitem(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_for
1
▼
Handle for loop: push loop variable into scope.
_visit_for
1
▼
def _visit_for(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_asyncfor
1
▼
Handle async for loop (same as regular for).
_visit_asyncfor
1
▼
def _visit_asyncfor(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_while
1
▼
Handle while loop.
_visit_while
1
▼
def _visit_while(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_with
1
▼
Handle with block: {% with x = expr %}...{% end %}
_visit_with
1
▼
def _visit_with(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_withconditional
1
▼
Handle conditional with: {% with expr as target %}
_visit_withconditional
1
▼
def _visit_withconditional(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_def
1
▼
Handle function definition: push args into scope.
_visit_def
1
▼
def _visit_def(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_macro
1
▼
Handle macro definition (same as def).
_visit_macro
1
▼
def _visit_macro(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_set
1
▼
Handle set statement.
_visit_set
1
▼
def _visit_set(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_let
1
▼
Handle let statement (template-scoped).
_visit_let
1
▼
def _visit_let(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_export
1
▼
Handle export statement.
_visit_export
1
▼
def _visit_export(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_capture
1
▼
Handle capture block: {% capture name %}...{% end %}
_visit_capture
1
▼
def _visit_capture(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_filter
1
▼
Handle filter expression.
_visit_filter
1
▼
def _visit_filter(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_pipeline
1
▼
Handle pipeline expression: expr |> filter1 |> filter2
_visit_pipeline
1
▼
def _visit_pipeline(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_funccall
1
▼
Handle function call.
_visit_funccall
1
▼
def _visit_funccall(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_nullcoalesce
1
▼
Handle null coalescing: a ?? b
_visit_nullcoalesce
1
▼
def _visit_nullcoalesce(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_condexpr
1
▼
Handle conditional expression: a if cond else b
_visit_condexpr
1
▼
def _visit_condexpr(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_boolop
1
▼
Handle boolean operations: a and b, a or b
_visit_boolop
1
▼
def _visit_boolop(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_binop
1
▼
Handle binary operations: a + b, a - b, etc.
_visit_binop
1
▼
def _visit_binop(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_unaryop
1
▼
Handle unary operations: -a, not a
_visit_unaryop
1
▼
def _visit_unaryop(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_compare
1
▼
Handle comparisons: a < b < c
_visit_compare
1
▼
def _visit_compare(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_range
1
▼
Handle range literal: start..end or start...end
_visit_range
1
▼
def _visit_range(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_slice
1
▼
Handle slice expression: [start:stop:step]
_visit_slice
1
▼
def _visit_slice(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_concat
1
▼
Handle string concatenation: a ~ b ~ c
_visit_concat
1
▼
def _visit_concat(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_list
1
▼
Handle list literal: [a, b, c]
_visit_list
1
▼
def _visit_list(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_tuple
1
▼
Handle tuple literal: (a, b, c)
_visit_tuple
1
▼
def _visit_tuple(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_dict
1
▼
Handle dict literal: {a: b, c: d}
_visit_dict
1
▼
def _visit_dict(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_test
1
▼
Handle test expression: x is defined
_visit_test
1
▼
def _visit_test(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_match
1
▼
Handle match statement.
_visit_match
1
▼
def _visit_match(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_cache
1
▼
Handle cache block: {% cache key %}...{% end %}
_visit_cache
1
▼
def _visit_cache(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_include
1
▼
Handle include statement.
_visit_include
1
▼
def _visit_include(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_import
1
▼
Handle import statement.
_visit_import
1
▼
def _visit_import(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_fromimport
1
▼
Handle from...import statement.
_visit_fromimport
1
▼
def _visit_fromimport(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_if
1
▼
Handle if statement.
_visit_if
1
▼
def _visit_if(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_output
1
▼
Handle output: {{ expr }}
_visit_output
1
▼
def _visit_output(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_block
1
▼
Handle block: {% block name %}...{% end %}
_visit_block
1
▼
def _visit_block(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_extends
1
▼
Handle extends: {% extends 'base.html' %}
_visit_extends
1
▼
def _visit_extends(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_template
1
▼
Handle template root node.
_visit_template
1
▼
def _visit_template(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_filterblock
1
▼
Handle filter block: {% filter upper %}...{% end %}
_visit_filterblock
1
▼
def _visit_filterblock(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_callblock
1
▼
Handle call block: {% call name(args) %}body{% end %}
_visit_callblock
1
▼
def _visit_callblock(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_spaceless
1
▼
Handle spaceless block.
_visit_spaceless
1
▼
def _visit_spaceless(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_autoescape
1
▼
Handle autoescape block.
_visit_autoescape
1
▼
def _visit_autoescape(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_trim
1
▼
Handle trim block.
_visit_trim
1
▼
def _visit_trim(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_embed
1
▼
Handle embed: {% embed 'card.html' %}...{% end %}
_visit_embed
1
▼
def _visit_embed(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_await
1
▼
Handle await expression.
_visit_await
1
▼
def _visit_await(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_marksafe
1
▼
Handle safe marker.
_visit_marksafe
1
▼
def _visit_marksafe(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_inlinedfilter
1
▼
Handle inlined filter (optimization).
_visit_inlinedfilter
1
▼
def _visit_inlinedfilter(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_const
1
▼
Constants have no dependencies.
_visit_const
1
▼
def _visit_const(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_data
1
▼
Static data has no dependencies.
_visit_data
1
▼
def _visit_data(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_raw
1
▼
Raw blocks have no dependencies.
_visit_raw
1
▼
def _visit_raw(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_slot
1
▼
Slots have no dependencies.
_visit_slot
1
▼
def _visit_slot(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_break
1
▼
Break has no dependencies.
_visit_break
1
▼
def _visit_break(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_continue
1
▼
Continue has no dependencies.
_visit_continue
1
▼
def _visit_continue(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_do
1
▼
Handle do statement.
_visit_do
1
▼
def _visit_do(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_visit_loopvar
1
▼
Loop variable access (loop.index, etc.) - no context deps.
_visit_loopvar
1
▼
def _visit_loopvar(self, node: Any) -> None
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
_build_path
1
str | None
▼
Build dotted path from chained attribute/item access.
Returns None if the path…
_build_path
1
str | None
▼
def _build_path(self, node: Any) -> 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.
_extract_targets
1
set[str]
▼
def _extract_targets(self, node: Any) -> set[str]
Parameters
| Name | Type | Description |
|---|---|---|
node |
— |
Returns
set[str]
_is_local
1
bool
▼
Check if a name is in local scope.
_is_local
1
bool
▼
def _is_local(self, name: str) -> bool
Parameters
| Name | Type | Description |
|---|---|---|
name |
— |
Returns
bool