Ticket #295: eval.patch
| File eval.patch, 9.1 KB (added by Christoph Zwerschke <cito@…>, 4 years ago) |
|---|
-
base.py
36 36 37 37 def __init__(self, message, filename=None, lineno=-1, offset=-1): 38 38 """Create the exception. 39 39 40 40 :param message: the error message 41 41 :param filename: the filename of the template 42 42 :param lineno: the number of line in the template at which the error … … 61 61 62 62 def __init__(self, message, filename=None, lineno=-1, offset=-1): 63 63 """Create the exception 64 64 65 65 :param message: the error message 66 66 :param filename: the filename of the template 67 67 :param lineno: the number of line in the template at which the error … … 76 76 class BadDirectiveError(TemplateSyntaxError): 77 77 """Exception raised when an unknown directive is encountered when parsing 78 78 a template. 79 79 80 80 An unknown directive is any attribute using the namespace for directives, 81 81 with a local name that doesn't match any registered directive. 82 82 """ 83 83 84 84 def __init__(self, name, filename=None, lineno=-1): 85 85 """Create the exception 86 86 87 87 :param name: the name of the directive 88 88 :param filename: the filename of the template 89 89 :param lineno: the number of line in the template at which the error … … 101 101 102 102 class Context(object): 103 103 """Container for template input data. 104 104 105 105 A context provides a stack of scopes (represented by dictionaries). 106 106 107 107 Template directives such as loops can push a new scope on the stack with 108 108 data that should only be available inside the loop. When the loop 109 109 terminates, that scope can get popped off the stack again. 110 110 111 111 >>> ctxt = Context(one='foo', other=1) 112 112 >>> ctxt.get('one') 113 113 'foo' … … 151 151 152 152 def __contains__(self, key): 153 153 """Return whether a variable exists in any of the scopes. 154 154 155 155 :param key: the name of the variable 156 156 """ 157 157 return self._find(key)[1] is not None … … 159 159 160 160 def __delitem__(self, key): 161 161 """Remove a variable from all scopes. 162 162 163 163 :param key: the name of the variable 164 164 """ 165 165 for frame in self.frames: … … 169 169 def __getitem__(self, key): 170 170 """Get a variables's value, starting at the current scope and going 171 171 upward. 172 172 173 173 :param key: the name of the variable 174 174 :return: the variable value 175 175 :raises KeyError: if the requested variable wasn't found in any scope … … 181 181 182 182 def __len__(self): 183 183 """Return the number of distinctly named variables in the context. 184 184 185 185 :return: the number of variables in the context 186 186 """ 187 187 return len(self.items()) 188 188 189 189 def __setitem__(self, key, value): 190 190 """Set a variable in the current scope. 191 191 192 192 :param key: the name of the variable 193 193 :param value: the variable value 194 194 """ … … 198 198 """Retrieve a given variable's value and the frame it was found in. 199 199 200 200 Intended primarily for internal use by directives. 201 201 202 202 :param key: the name of the variable 203 203 :param default: the default value to return when the variable is not 204 204 found … … 211 211 def get(self, key, default=None): 212 212 """Get a variable's value, starting at the current scope and going 213 213 upward. 214 214 215 215 :param key: the name of the variable 216 216 :param default: the default value to return when the variable is not 217 217 found … … 223 223 224 224 def keys(self): 225 225 """Return the name of all variables in the context. 226 226 227 227 :return: a list of variable names 228 228 """ 229 229 keys = [] … … 234 234 def items(self): 235 235 """Return a list of ``(name, value)`` tuples for all variables in the 236 236 context. 237 237 238 238 :return: a list of variables 239 239 """ 240 240 return [(key, self.get(key)) for key in self.keys()] … … 245 245 246 246 def push(self, data): 247 247 """Push a new scope on the stack. 248 248 249 249 :param data: the data dictionary to push on the context stack. 250 250 """ 251 251 … … 255 255 256 256 def _apply_directives(stream, directives, ctxt, **vars): 257 257 """Apply the given directives to the stream. 258 258 259 259 :param stream: the stream the directives should be applied to 260 260 :param directives: the list of directives to apply 261 261 :param ctxt: the `Context` … … 269 269 270 270 def _eval_expr(expr, ctxt, **vars): 271 271 """Evaluate the given `Expression` object. 272 272 273 273 :param expr: the expression to evaluate 274 274 :param ctxt: the `Context` 275 275 :param vars: additional variables that should be available to the … … 285 285 286 286 def _exec_suite(suite, ctxt, **vars): 287 287 """Execute the given `Suite` object. 288 288 289 289 :param suite: the code suite to execute 290 290 :param ctxt: the `Context` 291 291 :param vars: additional variables that should be available to the … … 314 314 315 315 class DirectiveFactory(object): 316 316 """Base for classes that provide a set of template directives. 317 317 318 318 :since: version 0.6 319 319 """ 320 320 __metaclass__ = DirectiveFactoryMeta … … 336 336 337 337 def get_directive(self, name): 338 338 """Return the directive class for the given name. 339 339 340 340 :param name: the directive name as used in the template 341 341 :return: the directive class 342 342 :see: `Directive` … … 346 346 347 347 class Template(DirectiveFactory): 348 348 """Abstract template base class. 349 349 350 350 This class implements most of the template processing model, but does not 351 351 specify the syntax of templates. 352 352 """ … … 372 372 encoding=None, lookup='strict', allow_exec=True): 373 373 """Initialize a template from either a string, a file-like object, or 374 374 an already parsed markup stream. 375 375 376 376 :param source: a string, file-like object, or markup stream to read the 377 377 template from 378 378 :param filepath: the absolute path to the template file … … 385 385 default), "lenient", or a custom lookup class 386 386 :param allow_exec: whether Python code blocks in templates should be 387 387 allowed 388 388 389 389 :note: Changed in 0.5: Added the `allow_exec` argument 390 390 """ 391 391 self.filepath = filepath or filename … … 431 431 432 432 def _parse(self, source, encoding): 433 433 """Parse the template. 434 434 435 435 The parsing stage parses the template and constructs a list of 436 436 directives that will be executed in the render stage. The input is 437 437 split up into literal output (text that does not depend on the context 438 438 data) and directives or expressions. 439 439 440 440 :param source: a file-like object containing the XML source of the 441 441 template, or an XML event stream 442 442 :param encoding: the encoding of the `source` … … 445 445 446 446 def _prepare(self, stream): 447 447 """Call the `attach` method of every directive found in the template. 448 448 449 449 :param stream: the event stream of the template 450 450 """ 451 451 from genshi.template.loader import TemplateNotFound … … 492 492 493 493 def generate(self, *args, **kwargs): 494 494 """Apply the template to the given context data. 495 495 496 496 Any keyword arguments are made available to the template as context 497 497 data. 498 498 499 499 Only one positional argument is accepted: if it is provided, it must be 500 500 an instance of the `Context` class, and keyword arguments are ignored. 501 501 This calling style is used for internal processing. 502 502 503 503 :return: a markup event stream representing the result of applying 504 504 the template to the context data. 505 505 """ … … 531 531 tag, attrs = data 532 532 new_attrs = [] 533 533 for name, substream in attrs: 534 if type(substream) is list:535 value s = []536 for event in self._flatten(substream, ctxt, **vars):537 if event[0] is TEXT:538 values.append(event[1])539 value = [x for x in values if xis not None]534 if isinstance(substream, basestring): 535 value = substream 536 else: 537 value = [event[1] 538 for event in self._flatten(substream, ctxt, **vars) 539 if event[0] is TEXT and event[1] is not None] 540 540 if not value: 541 541 continue 542 else: 543 value = substream 544 new_attrs.append((name, u''.join(value))) 542 value = u''.join(value) 543 new_attrs.append((name, value)) 545 544 yield kind, (tag, Attrs(new_attrs)), pos 546 545 547 546 elif kind is EXPR:
