Coverage for jinja2_async_environment/compiler_modules/frame.py: 100%
65 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-03 14:09 -0700
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-03 14:09 -0700
1"""Async frame implementation for template compilation."""
3import typing as t
5from jinja2.compiler import EvalContext, Frame
7if t.TYPE_CHECKING:
8 pass
11class AsyncFrame(Frame):
12 """Async-aware frame for template compilation context."""
14 block_frame: "AsyncFrame | None"
15 require_output_check: bool
16 has_known_extends: bool
17 toplevel: bool
18 rootlevel: bool
19 buffer: str | None
20 block_buffer: list[str]
21 extended_buffer: list[str] | None
22 require_yield: bool
23 buffer_count: int
24 is_async: bool
26 def __init__(self, eval_ctx: EvalContext | None = None) -> None:
27 if eval_ctx is None:
28 from jinja2.environment import Environment
29 from jinja2.nodes import EvalContext
31 eval_ctx = EvalContext(Environment(autoescape=True), "template")
33 super().__init__(eval_ctx)
34 self.buffer = None
35 self.block_buffer = []
36 self.extended_buffer = None
37 self.block_frame = None
38 self.require_output_check = False
39 self.has_known_extends = False
40 self.toplevel = False
41 self.rootlevel = False
42 self.require_yield = False
43 self.buffer_count = 0
44 self.is_async = False
45 self.block_counters: dict[str, int] = {}
46 self.block_frame_id = 0
48 def copy(self) -> t.Self:
49 """Create a copy of this frame."""
50 rv = self.__class__(self.eval_ctx)
51 rv.symbols = self.symbols.copy() # noqa: FURB145
52 rv.buffer = self.buffer
53 rv.block_buffer = self.block_buffer
54 rv.extended_buffer = self.extended_buffer
55 rv.eval_ctx = self.eval_ctx
56 rv.parent = self
57 rv.require_output_check = self.require_output_check
58 rv.has_known_extends = self.has_known_extends
59 rv.toplevel = self.toplevel
60 rv.rootlevel = self.rootlevel
61 rv.block_frame = self.block_frame
62 rv.require_yield = self.require_yield
63 rv.buffer_count = self.buffer_count
64 rv.is_async = self.is_async
65 rv.block_counters = self.block_counters.copy() # noqa: FURB145
66 rv.block_frame_id = self.block_frame_id
67 return rv
69 def inspect(self, nodes: t.Any | None = None) -> None:
70 """Inspect nodes for symbol analysis."""
71 if nodes:
72 for node in nodes:
73 self.symbols.analyze_node(node)
75 def push_scope(self) -> None:
76 """Push a new scope (no-op for async frame)."""
77 pass
79 def pop_scope(self) -> None:
80 """Pop the current scope (no-op for async frame)."""
81 pass
83 def find_break(self) -> bool:
84 """Check if break statement is valid (always False)."""
85 return False
87 def find_continue(self) -> bool:
88 """Check if continue statement is valid (always False)."""
89 return False
91 def inner(self) -> "AsyncFrame":
92 """Create an inner frame."""
93 return self.copy()