Coverage for jinja2_async_environment/compiler_modules/patterns.py: 100%
44 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"""Pre-compiled regex patterns for template compilation optimization."""
3import re
6class CompiledPatterns:
7 """Pre-compiled regex patterns for template compilation optimization."""
9 # Pattern for async yield detection
10 ASYNC_YIELD_PATTERN = re.compile(
11 r"async for event in self\._async_yield_from\([^)]+\):\s*$", re.MULTILINE
12 )
14 # Pattern for undefined variable detection
15 UNDEFINED_VAR_PATTERN = re.compile(
16 r"undefined\(name='([^']+)'\) if l_0_\1 is missing else l_0_\1"
17 )
19 # Pattern for loop variable optimization
20 LOOP_VAR_PATTERN = re.compile(r"l_0_(\w+)")
22 # Pattern for context block detection
23 CONTEXT_BLOCK_PATTERN = re.compile(r"yield from context\.blocks")
25 # Additional performance patterns
26 HASATTR_CHECK_PATTERN = re.compile(r"hasattr\(([^,]+),\s*'__await__'\)")
27 AUTO_AITER_PATTERN = re.compile(r"auto_aiter\(([^)]+)\)")
28 TEMPLATE_RUNTIME_ERROR_PATTERN = re.compile(r'TemplateRuntimeError\("([^"]+)"\)')
29 DUPLICATE_IMPORT_PATTERN = re.compile(r"^from ([\w.]+) import (.+)$", re.MULTILINE)
30 REDUNDANT_ESCAPE_PATTERN = re.compile(r"escape\(escape\(([^)]+)\)\)")
31 CONSTANT_UNDEFINED_PATTERN = re.compile(r"undefined\(name=None\)")
33 # Cached import statements for faster code generation
34 _CACHED_IMPORTS = {
35 "runtime": "from jinja2.runtime import Undefined, Macro, missing, LoopContext, AsyncLoopContext, auto_aiter, Namespace, TemplateRuntimeError",
36 "markupsafe": "from markupsafe import escape",
37 "defaults": "from jinja2.defaults import DEFAULT_FILTERS",
38 }
40 @classmethod
41 def get_optimized_imports(cls) -> str:
42 """Return optimized import statements as a single string."""
43 return "\n".join(cls._CACHED_IMPORTS.values())
45 @classmethod
46 def optimize_generated_code(cls, code: str) -> str:
47 """Apply pattern-based optimizations to generated template code."""
48 optimized_code = code
50 # Fast string replacements for common patterns
51 optimizations = [
52 ("yield from context.blocks", "pass # yield from replaced"),
53 ("undefined(name='item') if l_0_item is missing else l_0_item", "item"),
54 ("undefined(name=None)", "Undefined()"),
55 ("escape(escape(", "escape("), # Remove double escaping
56 (
57 "if hasattr(value, '__await__'):\n return await value\nelse:\n return value",
58 "return await value if hasattr(value, '__await__') else value",
59 ),
60 ]
62 for pattern, replacement in optimizations:
63 optimized_code = optimized_code.replace(pattern, replacement)
65 # Use regex patterns for more complex optimizations
66 optimized_code = cls._optimize_with_regex(optimized_code)
68 # Remove duplicate imports
69 optimized_code = cls._deduplicate_imports(optimized_code)
71 return optimized_code
73 @classmethod
74 def _optimize_with_regex(cls, code: str) -> str:
75 """Apply regex-based optimizations."""
77 # Optimize hasattr checks
78 def optimize_hasattr(match):
79 var = match.group(1)
80 return f"getattr({var}, '__await__', None) is not None"
82 code = cls.HASATTR_CHECK_PATTERN.sub(optimize_hasattr, code)
84 # Remove redundant escape calls
85 code = cls.REDUNDANT_ESCAPE_PATTERN.sub(r"escape(\1)", code)
87 return code
89 @classmethod
90 def _deduplicate_imports(cls, code: str) -> str:
91 """Remove duplicate import statements."""
92 lines = code.split("\n")
93 seen_imports = set()
94 deduplicated_lines = []
96 for line in lines:
97 if line.strip().startswith("from ") and " import " in line:
98 if line not in seen_imports:
99 seen_imports.add(line)
100 deduplicated_lines.append(line)
101 else:
102 deduplicated_lines.append(line)
104 return "\n".join(deduplicated_lines)