eric7/DebugClients/Python/coverage/templite.py

branch
eric7
changeset 8775
0802ae193343
parent 8312
800c432b34c8
equal deleted inserted replaced
8774:d728227e8ebb 8775:0802ae193343
9 """ 9 """
10 10
11 # Coincidentally named the same as http://code.activestate.com/recipes/496702/ 11 # Coincidentally named the same as http://code.activestate.com/recipes/496702/
12 12
13 import re 13 import re
14
15 from coverage import env
16 14
17 15
18 class TempliteSyntaxError(ValueError): 16 class TempliteSyntaxError(ValueError):
19 """Raised when a template has a syntax error.""" 17 """Raised when a template has a syntax error."""
20 pass 18 pass
23 class TempliteValueError(ValueError): 21 class TempliteValueError(ValueError):
24 """Raised when an expression won't evaluate in a template.""" 22 """Raised when an expression won't evaluate in a template."""
25 pass 23 pass
26 24
27 25
28 class CodeBuilder(object): 26 class CodeBuilder:
29 """Build source code conveniently.""" 27 """Build source code conveniently."""
30 28
31 def __init__(self, indent=0): 29 def __init__(self, indent=0):
32 self.code = [] 30 self.code = []
33 self.indent_level = indent 31 self.indent_level = indent
69 global_namespace = {} 67 global_namespace = {}
70 exec(python_source, global_namespace) 68 exec(python_source, global_namespace)
71 return global_namespace 69 return global_namespace
72 70
73 71
74 class Templite(object): 72 class Templite:
75 """A simple template renderer, for a nano-subset of Django syntax. 73 """A simple template renderer, for a nano-subset of Django syntax.
76 74
77 Supported constructs are extended variable access:: 75 Supported constructs are extended variable access::
78 76
79 {{var.modifier.modifier|filter|filter}} 77 {{var.modifier.modifier|filter|filter}}
135 code.indent() 133 code.indent()
136 vars_code = code.add_section() 134 vars_code = code.add_section()
137 code.add_line("result = []") 135 code.add_line("result = []")
138 code.add_line("append_result = result.append") 136 code.add_line("append_result = result.append")
139 code.add_line("extend_result = result.extend") 137 code.add_line("extend_result = result.extend")
140 if env.PY2: 138 code.add_line("to_str = str")
141 code.add_line("to_str = unicode")
142 else:
143 code.add_line("to_str = str")
144 139
145 buffered = [] 140 buffered = []
146 141
147 def flush_output(): 142 def flush_output():
148 """Force `buffered` to the code builder.""" 143 """Force `buffered` to the code builder."""
191 if len(words) != 4 or words[2] != 'in': 186 if len(words) != 4 or words[2] != 'in':
192 self._syntax_error("Don't understand for", token) 187 self._syntax_error("Don't understand for", token)
193 ops_stack.append('for') 188 ops_stack.append('for')
194 self._variable(words[1], self.loop_vars) 189 self._variable(words[1], self.loop_vars)
195 code.add_line( 190 code.add_line(
196 "for c_%s in %s:" % ( 191 "for c_{} in {}:".format(
197 words[1], 192 words[1],
198 self._expr_code(words[3]) 193 self._expr_code(words[3])
199 ) 194 )
200 ) 195 )
201 code.indent() 196 code.indent()
231 self._syntax_error("Unmatched action tag", ops_stack[-1]) 226 self._syntax_error("Unmatched action tag", ops_stack[-1])
232 227
233 flush_output() 228 flush_output()
234 229
235 for var_name in self.all_vars - self.loop_vars: 230 for var_name in self.all_vars - self.loop_vars:
236 vars_code.add_line("c_%s = context[%r]" % (var_name, var_name)) 231 vars_code.add_line(f"c_{var_name} = context[{var_name!r}]")
237 232
238 code.add_line('return "".join(result)') 233 code.add_line('return "".join(result)')
239 code.dedent() 234 code.dedent()
240 self._render_function = code.get_globals()['render_function'] 235 self._render_function = code.get_globals()['render_function']
241 236
244 if "|" in expr: 239 if "|" in expr:
245 pipes = expr.split("|") 240 pipes = expr.split("|")
246 code = self._expr_code(pipes[0]) 241 code = self._expr_code(pipes[0])
247 for func in pipes[1:]: 242 for func in pipes[1:]:
248 self._variable(func, self.all_vars) 243 self._variable(func, self.all_vars)
249 code = "c_%s(%s)" % (func, code) 244 code = f"c_{func}({code})"
250 elif "." in expr: 245 elif "." in expr:
251 dots = expr.split(".") 246 dots = expr.split(".")
252 code = self._expr_code(dots[0]) 247 code = self._expr_code(dots[0])
253 args = ", ".join(repr(d) for d in dots[1:]) 248 args = ", ".join(repr(d) for d in dots[1:])
254 code = "do_dots(%s, %s)" % (code, args) 249 code = f"do_dots({code}, {args})"
255 else: 250 else:
256 self._variable(expr, self.all_vars) 251 self._variable(expr, self.all_vars)
257 code = "c_%s" % expr 252 code = "c_%s" % expr
258 return code 253 return code
259 254
260 def _syntax_error(self, msg, thing): 255 def _syntax_error(self, msg, thing):
261 """Raise a syntax error using `msg`, and showing `thing`.""" 256 """Raise a syntax error using `msg`, and showing `thing`."""
262 raise TempliteSyntaxError("%s: %r" % (msg, thing)) 257 raise TempliteSyntaxError(f"{msg}: {thing!r}")
263 258
264 def _variable(self, name, vars_set): 259 def _variable(self, name, vars_set):
265 """Track that `name` is used as a variable. 260 """Track that `name` is used as a variable.
266 261
267 Adds the name to `vars_set`, a set of variable names. 262 Adds the name to `vars_set`, a set of variable names.
291 try: 286 try:
292 value = getattr(value, dot) 287 value = getattr(value, dot)
293 except AttributeError: 288 except AttributeError:
294 try: 289 try:
295 value = value[dot] 290 value = value[dot]
296 except (TypeError, KeyError): 291 except (TypeError, KeyError) as exc:
297 raise TempliteValueError( 292 raise TempliteValueError(
298 "Couldn't evaluate %r.%s" % (value, dot) 293 f"Couldn't evaluate {value!r}.{dot}"
299 ) 294 ) from exc
300 if callable(value): 295 if callable(value):
301 value = value() 296 value = value()
302 return value 297 return value

eric ide

mercurial