OLD | NEW |
1 # -*- coding: utf-8 -*- | 1 # -*- coding: utf-8 -*- |
2 """ | 2 """ |
3 jinja2.environment | 3 jinja2.environment |
4 ~~~~~~~~~~~~~~~~~~ | 4 ~~~~~~~~~~~~~~~~~~ |
5 | 5 |
6 Provides a class that holds runtime and parsing time options. | 6 Provides a class that holds runtime and parsing time options. |
7 | 7 |
8 :copyright: (c) 2010 by the Jinja Team. | 8 :copyright: (c) 2010 by the Jinja Team. |
9 :license: BSD, see LICENSE for more details. | 9 :license: BSD, see LICENSE for more details. |
10 """ | 10 """ |
11 import os | 11 import os |
12 import sys | 12 import sys |
13 from jinja2 import nodes | 13 from jinja2 import nodes |
14 from jinja2.defaults import * | 14 from jinja2.defaults import BLOCK_START_STRING, \ |
| 15 BLOCK_END_STRING, VARIABLE_START_STRING, VARIABLE_END_STRING, \ |
| 16 COMMENT_START_STRING, COMMENT_END_STRING, LINE_STATEMENT_PREFIX, \ |
| 17 LINE_COMMENT_PREFIX, TRIM_BLOCKS, NEWLINE_SEQUENCE, \ |
| 18 DEFAULT_FILTERS, DEFAULT_TESTS, DEFAULT_NAMESPACE, \ |
| 19 KEEP_TRAILING_NEWLINE, LSTRIP_BLOCKS |
15 from jinja2.lexer import get_lexer, TokenStream | 20 from jinja2.lexer import get_lexer, TokenStream |
16 from jinja2.parser import Parser | 21 from jinja2.parser import Parser |
| 22 from jinja2.nodes import EvalContext |
17 from jinja2.optimizer import optimize | 23 from jinja2.optimizer import optimize |
18 from jinja2.compiler import generate | 24 from jinja2.compiler import generate |
19 from jinja2.runtime import Undefined, new_context | 25 from jinja2.runtime import Undefined, new_context |
20 from jinja2.exceptions import TemplateSyntaxError, TemplateNotFound, \ | 26 from jinja2.exceptions import TemplateSyntaxError, TemplateNotFound, \ |
21 TemplatesNotFound | 27 TemplatesNotFound, TemplateRuntimeError |
22 from jinja2.utils import import_string, LRUCache, Markup, missing, \ | 28 from jinja2.utils import import_string, LRUCache, Markup, missing, \ |
23 concat, consume, internalcode, _encode_filename | 29 concat, consume, internalcode |
| 30 from jinja2._compat import imap, ifilter, string_types, iteritems, \ |
| 31 text_type, reraise, implements_iterator, implements_to_string, \ |
| 32 get_next, encode_filename, PY2, PYPY |
| 33 from functools import reduce |
24 | 34 |
25 | 35 |
26 # for direct template usage we have up to ten living environments | 36 # for direct template usage we have up to ten living environments |
27 _spontaneous_environments = LRUCache(10) | 37 _spontaneous_environments = LRUCache(10) |
28 | 38 |
29 # the function to create jinja traceback objects. This is dynamically | 39 # the function to create jinja traceback objects. This is dynamically |
30 # imported on the first exception in the exception handler. | 40 # imported on the first exception in the exception handler. |
31 _make_traceback = None | 41 _make_traceback = None |
32 | 42 |
33 | 43 |
(...skipping 26 matching lines...) Expand all Loading... |
60 """Create an empty copy of the given cache.""" | 70 """Create an empty copy of the given cache.""" |
61 if cache is None: | 71 if cache is None: |
62 return None | 72 return None |
63 elif type(cache) is dict: | 73 elif type(cache) is dict: |
64 return {} | 74 return {} |
65 return LRUCache(cache.capacity) | 75 return LRUCache(cache.capacity) |
66 | 76 |
67 | 77 |
68 def load_extensions(environment, extensions): | 78 def load_extensions(environment, extensions): |
69 """Load the extensions from the list and bind it to the environment. | 79 """Load the extensions from the list and bind it to the environment. |
70 Returns a dict of instanciated environments. | 80 Returns a dict of instantiated environments. |
71 """ | 81 """ |
72 result = {} | 82 result = {} |
73 for extension in extensions: | 83 for extension in extensions: |
74 if isinstance(extension, basestring): | 84 if isinstance(extension, string_types): |
75 extension = import_string(extension) | 85 extension = import_string(extension) |
76 result[extension.identifier] = extension(environment) | 86 result[extension.identifier] = extension(environment) |
77 return result | 87 return result |
78 | 88 |
79 | 89 |
80 def _environment_sanity_check(environment): | 90 def _environment_sanity_check(environment): |
81 """Perform a sanity check on the environment.""" | 91 """Perform a sanity check on the environment.""" |
82 assert issubclass(environment.undefined, Undefined), 'undefined must ' \ | 92 assert issubclass(environment.undefined, Undefined), 'undefined must ' \ |
83 'be a subclass of undefined because filters depend on it.' | 93 'be a subclass of undefined because filters depend on it.' |
84 assert environment.block_start_string != \ | 94 assert environment.block_start_string != \ |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 `line_comment_prefix` | 137 `line_comment_prefix` |
128 If given and a string, this will be used as prefix for line based | 138 If given and a string, this will be used as prefix for line based |
129 based comments. See also :ref:`line-statements`. | 139 based comments. See also :ref:`line-statements`. |
130 | 140 |
131 .. versionadded:: 2.2 | 141 .. versionadded:: 2.2 |
132 | 142 |
133 `trim_blocks` | 143 `trim_blocks` |
134 If this is set to ``True`` the first newline after a block is | 144 If this is set to ``True`` the first newline after a block is |
135 removed (block, not variable tag!). Defaults to `False`. | 145 removed (block, not variable tag!). Defaults to `False`. |
136 | 146 |
| 147 `lstrip_blocks` |
| 148 If this is set to ``True`` leading spaces and tabs are stripped |
| 149 from the start of a line to a block. Defaults to `False`. |
| 150 |
137 `newline_sequence` | 151 `newline_sequence` |
138 The sequence that starts a newline. Must be one of ``'\r'``, | 152 The sequence that starts a newline. Must be one of ``'\r'``, |
139 ``'\n'`` or ``'\r\n'``. The default is ``'\n'`` which is a | 153 ``'\n'`` or ``'\r\n'``. The default is ``'\n'`` which is a |
140 useful default for Linux and OS X systems as well as web | 154 useful default for Linux and OS X systems as well as web |
141 applications. | 155 applications. |
142 | 156 |
| 157 `keep_trailing_newline` |
| 158 Preserve the trailing newline when rendering templates. |
| 159 The default is ``False``, which causes a single newline, |
| 160 if present, to be stripped from the end of the template. |
| 161 |
| 162 .. versionadded:: 2.7 |
| 163 |
143 `extensions` | 164 `extensions` |
144 List of Jinja extensions to use. This can either be import paths | 165 List of Jinja extensions to use. This can either be import paths |
145 as strings or extension classes. For more information have a | 166 as strings or extension classes. For more information have a |
146 look at :ref:`the extensions documentation <jinja-extensions>`. | 167 look at :ref:`the extensions documentation <jinja-extensions>`. |
147 | 168 |
148 `optimized` | 169 `optimized` |
149 should the optimizer be enabled? Default is `True`. | 170 should the optimizer be enabled? Default is `True`. |
150 | 171 |
151 `undefined` | 172 `undefined` |
152 :class:`Undefined` or a subclass of it that is used to represent | 173 :class:`Undefined` or a subclass of it that is used to represent |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 def __init__(self, | 238 def __init__(self, |
218 block_start_string=BLOCK_START_STRING, | 239 block_start_string=BLOCK_START_STRING, |
219 block_end_string=BLOCK_END_STRING, | 240 block_end_string=BLOCK_END_STRING, |
220 variable_start_string=VARIABLE_START_STRING, | 241 variable_start_string=VARIABLE_START_STRING, |
221 variable_end_string=VARIABLE_END_STRING, | 242 variable_end_string=VARIABLE_END_STRING, |
222 comment_start_string=COMMENT_START_STRING, | 243 comment_start_string=COMMENT_START_STRING, |
223 comment_end_string=COMMENT_END_STRING, | 244 comment_end_string=COMMENT_END_STRING, |
224 line_statement_prefix=LINE_STATEMENT_PREFIX, | 245 line_statement_prefix=LINE_STATEMENT_PREFIX, |
225 line_comment_prefix=LINE_COMMENT_PREFIX, | 246 line_comment_prefix=LINE_COMMENT_PREFIX, |
226 trim_blocks=TRIM_BLOCKS, | 247 trim_blocks=TRIM_BLOCKS, |
| 248 lstrip_blocks=LSTRIP_BLOCKS, |
227 newline_sequence=NEWLINE_SEQUENCE, | 249 newline_sequence=NEWLINE_SEQUENCE, |
| 250 keep_trailing_newline=KEEP_TRAILING_NEWLINE, |
228 extensions=(), | 251 extensions=(), |
229 optimized=True, | 252 optimized=True, |
230 undefined=Undefined, | 253 undefined=Undefined, |
231 finalize=None, | 254 finalize=None, |
232 autoescape=False, | 255 autoescape=False, |
233 loader=None, | 256 loader=None, |
234 cache_size=50, | 257 cache_size=50, |
235 auto_reload=True, | 258 auto_reload=True, |
236 bytecode_cache=None): | 259 bytecode_cache=None): |
237 # !!Important notice!! | 260 # !!Important notice!! |
238 # The constructor accepts quite a few arguments that should be | 261 # The constructor accepts quite a few arguments that should be |
239 # passed by keyword rather than position. However it's important to | 262 # passed by keyword rather than position. However it's important to |
240 # not change the order of arguments because it's used at least | 263 # not change the order of arguments because it's used at least |
241 # internally in those cases: | 264 # internally in those cases: |
242 # - spontaneus environments (i18n extension and Template) | 265 # - spontaneous environments (i18n extension and Template) |
243 # - unittests | 266 # - unittests |
244 # If parameter changes are required only add parameters at the end | 267 # If parameter changes are required only add parameters at the end |
245 # and don't change the arguments (or the defaults!) of the arguments | 268 # and don't change the arguments (or the defaults!) of the arguments |
246 # existing already. | 269 # existing already. |
247 | 270 |
248 # lexer / parser information | 271 # lexer / parser information |
249 self.block_start_string = block_start_string | 272 self.block_start_string = block_start_string |
250 self.block_end_string = block_end_string | 273 self.block_end_string = block_end_string |
251 self.variable_start_string = variable_start_string | 274 self.variable_start_string = variable_start_string |
252 self.variable_end_string = variable_end_string | 275 self.variable_end_string = variable_end_string |
253 self.comment_start_string = comment_start_string | 276 self.comment_start_string = comment_start_string |
254 self.comment_end_string = comment_end_string | 277 self.comment_end_string = comment_end_string |
255 self.line_statement_prefix = line_statement_prefix | 278 self.line_statement_prefix = line_statement_prefix |
256 self.line_comment_prefix = line_comment_prefix | 279 self.line_comment_prefix = line_comment_prefix |
257 self.trim_blocks = trim_blocks | 280 self.trim_blocks = trim_blocks |
| 281 self.lstrip_blocks = lstrip_blocks |
258 self.newline_sequence = newline_sequence | 282 self.newline_sequence = newline_sequence |
| 283 self.keep_trailing_newline = keep_trailing_newline |
259 | 284 |
260 # runtime information | 285 # runtime information |
261 self.undefined = undefined | 286 self.undefined = undefined |
262 self.optimized = optimized | 287 self.optimized = optimized |
263 self.finalize = finalize | 288 self.finalize = finalize |
264 self.autoescape = autoescape | 289 self.autoescape = autoescape |
265 | 290 |
266 # defaults | 291 # defaults |
267 self.filters = DEFAULT_FILTERS.copy() | 292 self.filters = DEFAULT_FILTERS.copy() |
268 self.tests = DEFAULT_TESTS.copy() | 293 self.tests = DEFAULT_TESTS.copy() |
269 self.globals = DEFAULT_NAMESPACE.copy() | 294 self.globals = DEFAULT_NAMESPACE.copy() |
270 | 295 |
271 # set the loader provided | 296 # set the loader provided |
272 self.loader = loader | 297 self.loader = loader |
273 self.bytecode_cache = None | |
274 self.cache = create_cache(cache_size) | 298 self.cache = create_cache(cache_size) |
275 self.bytecode_cache = bytecode_cache | 299 self.bytecode_cache = bytecode_cache |
276 self.auto_reload = auto_reload | 300 self.auto_reload = auto_reload |
277 | 301 |
278 # load extensions | 302 # load extensions |
279 self.extensions = load_extensions(self, extensions) | 303 self.extensions = load_extensions(self, extensions) |
280 | 304 |
281 _environment_sanity_check(self) | 305 _environment_sanity_check(self) |
282 | 306 |
283 def add_extension(self, extension): | 307 def add_extension(self, extension): |
284 """Adds an extension after the environment was created. | 308 """Adds an extension after the environment was created. |
285 | 309 |
286 .. versionadded:: 2.5 | 310 .. versionadded:: 2.5 |
287 """ | 311 """ |
288 self.extensions.update(load_extensions(self, [extension])) | 312 self.extensions.update(load_extensions(self, [extension])) |
289 | 313 |
290 def extend(self, **attributes): | 314 def extend(self, **attributes): |
291 """Add the items to the instance of the environment if they do not exist | 315 """Add the items to the instance of the environment if they do not exist |
292 yet. This is used by :ref:`extensions <writing-extensions>` to register | 316 yet. This is used by :ref:`extensions <writing-extensions>` to register |
293 callbacks and configuration values without breaking inheritance. | 317 callbacks and configuration values without breaking inheritance. |
294 """ | 318 """ |
295 for key, value in attributes.iteritems(): | 319 for key, value in iteritems(attributes): |
296 if not hasattr(self, key): | 320 if not hasattr(self, key): |
297 setattr(self, key, value) | 321 setattr(self, key, value) |
298 | 322 |
299 def overlay(self, block_start_string=missing, block_end_string=missing, | 323 def overlay(self, block_start_string=missing, block_end_string=missing, |
300 variable_start_string=missing, variable_end_string=missing, | 324 variable_start_string=missing, variable_end_string=missing, |
301 comment_start_string=missing, comment_end_string=missing, | 325 comment_start_string=missing, comment_end_string=missing, |
302 line_statement_prefix=missing, line_comment_prefix=missing, | 326 line_statement_prefix=missing, line_comment_prefix=missing, |
303 trim_blocks=missing, extensions=missing, optimized=missing, | 327 trim_blocks=missing, lstrip_blocks=missing, |
| 328 extensions=missing, optimized=missing, |
304 undefined=missing, finalize=missing, autoescape=missing, | 329 undefined=missing, finalize=missing, autoescape=missing, |
305 loader=missing, cache_size=missing, auto_reload=missing, | 330 loader=missing, cache_size=missing, auto_reload=missing, |
306 bytecode_cache=missing): | 331 bytecode_cache=missing): |
307 """Create a new overlay environment that shares all the data with the | 332 """Create a new overlay environment that shares all the data with the |
308 current environment except of cache and the overridden attributes. | 333 current environment except of cache and the overridden attributes. |
309 Extensions cannot be removed for an overlayed environment. An overlayed | 334 Extensions cannot be removed for an overlayed environment. An overlayed |
310 environment automatically gets all the extensions of the environment it | 335 environment automatically gets all the extensions of the environment it |
311 is linked to plus optional extra extensions. | 336 is linked to plus optional extra extensions. |
312 | 337 |
313 Creating overlays should happen after the initial environment was set | 338 Creating overlays should happen after the initial environment was set |
314 up completely. Not all attributes are truly linked, some are just | 339 up completely. Not all attributes are truly linked, some are just |
315 copied over so modifications on the original environment may not shine | 340 copied over so modifications on the original environment may not shine |
316 through. | 341 through. |
317 """ | 342 """ |
318 args = dict(locals()) | 343 args = dict(locals()) |
319 del args['self'], args['cache_size'], args['extensions'] | 344 del args['self'], args['cache_size'], args['extensions'] |
320 | 345 |
321 rv = object.__new__(self.__class__) | 346 rv = object.__new__(self.__class__) |
322 rv.__dict__.update(self.__dict__) | 347 rv.__dict__.update(self.__dict__) |
323 rv.overlayed = True | 348 rv.overlayed = True |
324 rv.linked_to = self | 349 rv.linked_to = self |
325 | 350 |
326 for key, value in args.iteritems(): | 351 for key, value in iteritems(args): |
327 if value is not missing: | 352 if value is not missing: |
328 setattr(rv, key, value) | 353 setattr(rv, key, value) |
329 | 354 |
330 if cache_size is not missing: | 355 if cache_size is not missing: |
331 rv.cache = create_cache(cache_size) | 356 rv.cache = create_cache(cache_size) |
332 else: | 357 else: |
333 rv.cache = copy_cache(self.cache) | 358 rv.cache = copy_cache(self.cache) |
334 | 359 |
335 rv.extensions = {} | 360 rv.extensions = {} |
336 for key, value in self.extensions.iteritems(): | 361 for key, value in iteritems(self.extensions): |
337 rv.extensions[key] = value.bind(rv) | 362 rv.extensions[key] = value.bind(rv) |
338 if extensions is not missing: | 363 if extensions is not missing: |
339 rv.extensions.update(load_extensions(rv, extensions)) | 364 rv.extensions.update(load_extensions(rv, extensions)) |
340 | 365 |
341 return _environment_sanity_check(rv) | 366 return _environment_sanity_check(rv) |
342 | 367 |
343 lexer = property(get_lexer, doc="The lexer for this environment.") | 368 lexer = property(get_lexer, doc="The lexer for this environment.") |
344 | 369 |
345 def iter_extensions(self): | 370 def iter_extensions(self): |
346 """Iterates over the extensions by priority.""" | 371 """Iterates over the extensions by priority.""" |
347 return iter(sorted(self.extensions.values(), | 372 return iter(sorted(self.extensions.values(), |
348 key=lambda x: x.priority)) | 373 key=lambda x: x.priority)) |
349 | 374 |
350 def getitem(self, obj, argument): | 375 def getitem(self, obj, argument): |
351 """Get an item or attribute of an object but prefer the item.""" | 376 """Get an item or attribute of an object but prefer the item.""" |
352 try: | 377 try: |
353 return obj[argument] | 378 return obj[argument] |
354 except (TypeError, LookupError): | 379 except (TypeError, LookupError): |
355 if isinstance(argument, basestring): | 380 if isinstance(argument, string_types): |
356 try: | 381 try: |
357 attr = str(argument) | 382 attr = str(argument) |
358 except Exception: | 383 except Exception: |
359 pass | 384 pass |
360 else: | 385 else: |
361 try: | 386 try: |
362 return getattr(obj, attr) | 387 return getattr(obj, attr) |
363 except AttributeError: | 388 except AttributeError: |
364 pass | 389 pass |
365 return self.undefined(obj=obj, name=argument) | 390 return self.undefined(obj=obj, name=argument) |
366 | 391 |
367 def getattr(self, obj, attribute): | 392 def getattr(self, obj, attribute): |
368 """Get an item or attribute of an object but prefer the attribute. | 393 """Get an item or attribute of an object but prefer the attribute. |
369 Unlike :meth:`getitem` the attribute *must* be a bytestring. | 394 Unlike :meth:`getitem` the attribute *must* be a bytestring. |
370 """ | 395 """ |
371 try: | 396 try: |
372 return getattr(obj, attribute) | 397 return getattr(obj, attribute) |
373 except AttributeError: | 398 except AttributeError: |
374 pass | 399 pass |
375 try: | 400 try: |
376 return obj[attribute] | 401 return obj[attribute] |
377 except (TypeError, LookupError, AttributeError): | 402 except (TypeError, LookupError, AttributeError): |
378 return self.undefined(obj=obj, name=attribute) | 403 return self.undefined(obj=obj, name=attribute) |
379 | 404 |
| 405 def call_filter(self, name, value, args=None, kwargs=None, |
| 406 context=None, eval_ctx=None): |
| 407 """Invokes a filter on a value the same way the compiler does it. |
| 408 |
| 409 .. versionadded:: 2.7 |
| 410 """ |
| 411 func = self.filters.get(name) |
| 412 if func is None: |
| 413 raise TemplateRuntimeError('no filter named %r' % name) |
| 414 args = [value] + list(args or ()) |
| 415 if getattr(func, 'contextfilter', False): |
| 416 if context is None: |
| 417 raise TemplateRuntimeError('Attempted to invoke context ' |
| 418 'filter without context') |
| 419 args.insert(0, context) |
| 420 elif getattr(func, 'evalcontextfilter', False): |
| 421 if eval_ctx is None: |
| 422 if context is not None: |
| 423 eval_ctx = context.eval_ctx |
| 424 else: |
| 425 eval_ctx = EvalContext(self) |
| 426 args.insert(0, eval_ctx) |
| 427 elif getattr(func, 'environmentfilter', False): |
| 428 args.insert(0, self) |
| 429 return func(*args, **(kwargs or {})) |
| 430 |
| 431 def call_test(self, name, value, args=None, kwargs=None): |
| 432 """Invokes a test on a value the same way the compiler does it. |
| 433 |
| 434 .. versionadded:: 2.7 |
| 435 """ |
| 436 func = self.tests.get(name) |
| 437 if func is None: |
| 438 raise TemplateRuntimeError('no test named %r' % name) |
| 439 return func(value, *(args or ()), **(kwargs or {})) |
| 440 |
380 @internalcode | 441 @internalcode |
381 def parse(self, source, name=None, filename=None): | 442 def parse(self, source, name=None, filename=None): |
382 """Parse the sourcecode and return the abstract syntax tree. This | 443 """Parse the sourcecode and return the abstract syntax tree. This |
383 tree of nodes is used by the compiler to convert the template into | 444 tree of nodes is used by the compiler to convert the template into |
384 executable source- or bytecode. This is useful for debugging or to | 445 executable source- or bytecode. This is useful for debugging or to |
385 extract information from templates. | 446 extract information from templates. |
386 | 447 |
387 If you are :ref:`developing Jinja2 extensions <writing-extensions>` | 448 If you are :ref:`developing Jinja2 extensions <writing-extensions>` |
388 this gives you a good overview of the node tree generated. | 449 this gives you a good overview of the node tree generated. |
389 """ | 450 """ |
390 try: | 451 try: |
391 return self._parse(source, name, filename) | 452 return self._parse(source, name, filename) |
392 except TemplateSyntaxError: | 453 except TemplateSyntaxError: |
393 exc_info = sys.exc_info() | 454 exc_info = sys.exc_info() |
394 self.handle_exception(exc_info, source_hint=source) | 455 self.handle_exception(exc_info, source_hint=source) |
395 | 456 |
396 def _parse(self, source, name, filename): | 457 def _parse(self, source, name, filename): |
397 """Internal parsing function used by `parse` and `compile`.""" | 458 """Internal parsing function used by `parse` and `compile`.""" |
398 return Parser(self, source, name, _encode_filename(filename)).parse() | 459 return Parser(self, source, name, encode_filename(filename)).parse() |
399 | 460 |
400 def lex(self, source, name=None, filename=None): | 461 def lex(self, source, name=None, filename=None): |
401 """Lex the given sourcecode and return a generator that yields | 462 """Lex the given sourcecode and return a generator that yields |
402 tokens as tuples in the form ``(lineno, token_type, value)``. | 463 tokens as tuples in the form ``(lineno, token_type, value)``. |
403 This can be useful for :ref:`extension development <writing-extensions>` | 464 This can be useful for :ref:`extension development <writing-extensions>` |
404 and debugging templates. | 465 and debugging templates. |
405 | 466 |
406 This does not perform preprocessing. If you want the preprocessing | 467 This does not perform preprocessing. If you want the preprocessing |
407 of the extensions to be applied you have to filter source through | 468 of the extensions to be applied you have to filter source through |
408 the :meth:`preprocess` method. | 469 the :meth:`preprocess` method. |
409 """ | 470 """ |
410 source = unicode(source) | 471 source = text_type(source) |
411 try: | 472 try: |
412 return self.lexer.tokeniter(source, name, filename) | 473 return self.lexer.tokeniter(source, name, filename) |
413 except TemplateSyntaxError: | 474 except TemplateSyntaxError: |
414 exc_info = sys.exc_info() | 475 exc_info = sys.exc_info() |
415 self.handle_exception(exc_info, source_hint=source) | 476 self.handle_exception(exc_info, source_hint=source) |
416 | 477 |
417 def preprocess(self, source, name=None, filename=None): | 478 def preprocess(self, source, name=None, filename=None): |
418 """Preprocesses the source with all extensions. This is automatically | 479 """Preprocesses the source with all extensions. This is automatically |
419 called for all parsing and compiling methods but *not* for :meth:`lex` | 480 called for all parsing and compiling methods but *not* for :meth:`lex` |
420 because there you usually only want the actual source tokenized. | 481 because there you usually only want the actual source tokenized. |
421 """ | 482 """ |
422 return reduce(lambda s, e: e.preprocess(s, name, filename), | 483 return reduce(lambda s, e: e.preprocess(s, name, filename), |
423 self.iter_extensions(), unicode(source)) | 484 self.iter_extensions(), text_type(source)) |
424 | 485 |
425 def _tokenize(self, source, name, filename=None, state=None): | 486 def _tokenize(self, source, name, filename=None, state=None): |
426 """Called by the parser to do the preprocessing and filtering | 487 """Called by the parser to do the preprocessing and filtering |
427 for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`. | 488 for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`. |
428 """ | 489 """ |
429 source = self.preprocess(source, name, filename) | 490 source = self.preprocess(source, name, filename) |
430 stream = self.lexer.tokenize(source, name, filename, state) | 491 stream = self.lexer.tokenize(source, name, filename, state) |
431 for ext in self.iter_extensions(): | 492 for ext in self.iter_extensions(): |
432 stream = ext.filter_stream(stream) | 493 stream = ext.filter_stream(stream) |
433 if not isinstance(stream, TokenStream): | 494 if not isinstance(stream, TokenStream): |
434 stream = TokenStream(stream, name, filename) | 495 stream = TokenStream(stream, name, filename) |
435 return stream | 496 return stream |
436 | 497 |
437 def _generate(self, source, name, filename, defer_init=False): | 498 def _generate(self, source, name, filename, defer_init=False): |
438 """Internal hook that can be overriden to hook a different generate | 499 """Internal hook that can be overridden to hook a different generate |
439 method in. | 500 method in. |
440 | 501 |
441 .. versionadded:: 2.5 | 502 .. versionadded:: 2.5 |
442 """ | 503 """ |
443 return generate(source, self, name, filename, defer_init=defer_init) | 504 return generate(source, self, name, filename, defer_init=defer_init) |
444 | 505 |
445 def _compile(self, source, filename): | 506 def _compile(self, source, filename): |
446 """Internal hook that can be overriden to hook a different compile | 507 """Internal hook that can be overridden to hook a different compile |
447 method in. | 508 method in. |
448 | 509 |
449 .. versionadded:: 2.5 | 510 .. versionadded:: 2.5 |
450 """ | 511 """ |
451 return compile(source, filename, 'exec') | 512 return compile(source, filename, 'exec') |
452 | 513 |
453 @internalcode | 514 @internalcode |
454 def compile(self, source, name=None, filename=None, raw=False, | 515 def compile(self, source, name=None, filename=None, raw=False, |
455 defer_init=False): | 516 defer_init=False): |
456 """Compile a node or template source code. The `name` parameter is | 517 """Compile a node or template source code. The `name` parameter is |
(...skipping 10 matching lines...) Expand all Loading... |
467 | 528 |
468 `defer_init` is use internally to aid the module code generator. This | 529 `defer_init` is use internally to aid the module code generator. This |
469 causes the generated code to be able to import without the global | 530 causes the generated code to be able to import without the global |
470 environment variable to be set. | 531 environment variable to be set. |
471 | 532 |
472 .. versionadded:: 2.4 | 533 .. versionadded:: 2.4 |
473 `defer_init` parameter added. | 534 `defer_init` parameter added. |
474 """ | 535 """ |
475 source_hint = None | 536 source_hint = None |
476 try: | 537 try: |
477 if isinstance(source, basestring): | 538 if isinstance(source, string_types): |
478 source_hint = source | 539 source_hint = source |
479 source = self._parse(source, name, filename) | 540 source = self._parse(source, name, filename) |
480 if self.optimized: | 541 if self.optimized: |
481 source = optimize(source, self) | 542 source = optimize(source, self) |
482 source = self._generate(source, name, filename, | 543 source = self._generate(source, name, filename, |
483 defer_init=defer_init) | 544 defer_init=defer_init) |
484 if raw: | 545 if raw: |
485 return source | 546 return source |
486 if filename is None: | 547 if filename is None: |
487 filename = '<template>' | 548 filename = '<template>' |
488 else: | 549 else: |
489 filename = _encode_filename(filename) | 550 filename = encode_filename(filename) |
490 return self._compile(source, filename) | 551 return self._compile(source, filename) |
491 except TemplateSyntaxError: | 552 except TemplateSyntaxError: |
492 exc_info = sys.exc_info() | 553 exc_info = sys.exc_info() |
493 self.handle_exception(exc_info, source_hint=source) | 554 self.handle_exception(exc_info, source_hint=source) |
494 | 555 |
495 def compile_expression(self, source, undefined_to_none=True): | 556 def compile_expression(self, source, undefined_to_none=True): |
496 """A handy helper method that returns a callable that accepts keyword | 557 """A handy helper method that returns a callable that accepts keyword |
497 arguments that appear as variables in the expression. If called it | 558 arguments that appear as variables in the expression. If called it |
498 returns the result of the expression. | 559 returns the result of the expression. |
499 | 560 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 `extensions` and `filter_func` are passed to :meth:`list_templates`. | 610 `extensions` and `filter_func` are passed to :meth:`list_templates`. |
550 Each template returned will be compiled to the target folder or | 611 Each template returned will be compiled to the target folder or |
551 zipfile. | 612 zipfile. |
552 | 613 |
553 By default template compilation errors are ignored. In case a | 614 By default template compilation errors are ignored. In case a |
554 log function is provided, errors are logged. If you want template | 615 log function is provided, errors are logged. If you want template |
555 syntax errors to abort the compilation you can set `ignore_errors` | 616 syntax errors to abort the compilation you can set `ignore_errors` |
556 to `False` and you will get an exception on syntax errors. | 617 to `False` and you will get an exception on syntax errors. |
557 | 618 |
558 If `py_compile` is set to `True` .pyc files will be written to the | 619 If `py_compile` is set to `True` .pyc files will be written to the |
559 target instead of standard .py files. | 620 target instead of standard .py files. This flag does not do anything |
| 621 on pypy and Python 3 where pyc files are not picked up by itself and |
| 622 don't give much benefit. |
560 | 623 |
561 .. versionadded:: 2.4 | 624 .. versionadded:: 2.4 |
562 """ | 625 """ |
563 from jinja2.loaders import ModuleLoader | 626 from jinja2.loaders import ModuleLoader |
564 | 627 |
565 if log_function is None: | 628 if log_function is None: |
566 log_function = lambda x: None | 629 log_function = lambda x: None |
567 | 630 |
568 if py_compile: | 631 if py_compile: |
569 import imp, marshal | 632 if not PY2 or PYPY: |
570 py_header = imp.get_magic() + \ | 633 from warnings import warn |
571 u'\xff\xff\xff\xff'.encode('iso-8859-15') | 634 warn(Warning('py_compile has no effect on pypy or Python 3')) |
| 635 py_compile = False |
| 636 else: |
| 637 import imp, marshal |
| 638 py_header = imp.get_magic() + \ |
| 639 u'\xff\xff\xff\xff'.encode('iso-8859-15') |
| 640 |
| 641 # Python 3.3 added a source filesize to the header |
| 642 if sys.version_info >= (3, 3): |
| 643 py_header += u'\x00\x00\x00\x00'.encode('iso-8859-15') |
572 | 644 |
573 def write_file(filename, data, mode): | 645 def write_file(filename, data, mode): |
574 if zip: | 646 if zip: |
575 info = ZipInfo(filename) | 647 info = ZipInfo(filename) |
576 info.external_attr = 0755 << 16L | 648 info.external_attr = 0o755 << 16 |
577 zip_file.writestr(info, data) | 649 zip_file.writestr(info, data) |
578 else: | 650 else: |
579 f = open(os.path.join(target, filename), mode) | 651 f = open(os.path.join(target, filename), mode) |
580 try: | 652 try: |
581 f.write(data) | 653 f.write(data) |
582 finally: | 654 finally: |
583 f.close() | 655 f.close() |
584 | 656 |
585 if zip is not None: | 657 if zip is not None: |
586 from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED, ZIP_STORED | 658 from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED, ZIP_STORED |
587 zip_file = ZipFile(target, 'w', dict(deflated=ZIP_DEFLATED, | 659 zip_file = ZipFile(target, 'w', dict(deflated=ZIP_DEFLATED, |
588 stored=ZIP_STORED)[zip]) | 660 stored=ZIP_STORED)[zip]) |
589 log_function('Compiling into Zip archive "%s"' % target) | 661 log_function('Compiling into Zip archive "%s"' % target) |
590 else: | 662 else: |
591 if not os.path.isdir(target): | 663 if not os.path.isdir(target): |
592 os.makedirs(target) | 664 os.makedirs(target) |
593 log_function('Compiling into folder "%s"' % target) | 665 log_function('Compiling into folder "%s"' % target) |
594 | 666 |
595 try: | 667 try: |
596 for name in self.list_templates(extensions, filter_func): | 668 for name in self.list_templates(extensions, filter_func): |
597 source, filename, _ = self.loader.get_source(self, name) | 669 source, filename, _ = self.loader.get_source(self, name) |
598 try: | 670 try: |
599 code = self.compile(source, name, filename, True, True) | 671 code = self.compile(source, name, filename, True, True) |
600 except TemplateSyntaxError, e: | 672 except TemplateSyntaxError as e: |
601 if not ignore_errors: | 673 if not ignore_errors: |
602 raise | 674 raise |
603 log_function('Could not compile "%s": %s' % (name, e)) | 675 log_function('Could not compile "%s": %s' % (name, e)) |
604 continue | 676 continue |
605 | 677 |
606 filename = ModuleLoader.get_module_filename(name) | 678 filename = ModuleLoader.get_module_filename(name) |
607 | 679 |
608 if py_compile: | 680 if py_compile: |
609 c = self._compile(code, _encode_filename(filename)) | 681 c = self._compile(code, encode_filename(filename)) |
610 write_file(filename + 'c', py_header + | 682 write_file(filename + 'c', py_header + |
611 marshal.dumps(c), 'wb') | 683 marshal.dumps(c), 'wb') |
612 log_function('Byte-compiled "%s" as %s' % | 684 log_function('Byte-compiled "%s" as %s' % |
613 (name, filename + 'c')) | 685 (name, filename + 'c')) |
614 else: | 686 else: |
615 write_file(filename, code, 'w') | 687 write_file(filename, code, 'w') |
616 log_function('Compiled "%s" as %s' % (name, filename)) | 688 log_function('Compiled "%s" as %s' % (name, filename)) |
617 finally: | 689 finally: |
618 if zip: | 690 if zip: |
619 zip_file.close() | 691 zip_file.close() |
(...skipping 17 matching lines...) Expand all Loading... |
637 .. versionadded:: 2.4 | 709 .. versionadded:: 2.4 |
638 """ | 710 """ |
639 x = self.loader.list_templates() | 711 x = self.loader.list_templates() |
640 if extensions is not None: | 712 if extensions is not None: |
641 if filter_func is not None: | 713 if filter_func is not None: |
642 raise TypeError('either extensions or filter_func ' | 714 raise TypeError('either extensions or filter_func ' |
643 'can be passed, but not both') | 715 'can be passed, but not both') |
644 filter_func = lambda x: '.' in x and \ | 716 filter_func = lambda x: '.' in x and \ |
645 x.rsplit('.', 1)[1] in extensions | 717 x.rsplit('.', 1)[1] in extensions |
646 if filter_func is not None: | 718 if filter_func is not None: |
647 x = filter(filter_func, x) | 719 x = ifilter(filter_func, x) |
648 return x | 720 return x |
649 | 721 |
650 def handle_exception(self, exc_info=None, rendered=False, source_hint=None): | 722 def handle_exception(self, exc_info=None, rendered=False, source_hint=None): |
651 """Exception handling helper. This is used internally to either raise | 723 """Exception handling helper. This is used internally to either raise |
652 rewritten exceptions or return a rendered traceback for the template. | 724 rewritten exceptions or return a rendered traceback for the template. |
653 """ | 725 """ |
654 global _make_traceback | 726 global _make_traceback |
655 if exc_info is None: | 727 if exc_info is None: |
656 exc_info = sys.exc_info() | 728 exc_info = sys.exc_info() |
657 | 729 |
658 # the debugging module is imported when it's used for the first time. | 730 # the debugging module is imported when it's used for the first time. |
659 # we're doing a lot of stuff there and for applications that do not | 731 # we're doing a lot of stuff there and for applications that do not |
660 # get any exceptions in template rendering there is no need to load | 732 # get any exceptions in template rendering there is no need to load |
661 # all of that. | 733 # all of that. |
662 if _make_traceback is None: | 734 if _make_traceback is None: |
663 from jinja2.debug import make_traceback as _make_traceback | 735 from jinja2.debug import make_traceback as _make_traceback |
664 traceback = _make_traceback(exc_info, source_hint) | 736 traceback = _make_traceback(exc_info, source_hint) |
665 if rendered and self.exception_formatter is not None: | 737 if rendered and self.exception_formatter is not None: |
666 return self.exception_formatter(traceback) | 738 return self.exception_formatter(traceback) |
667 if self.exception_handler is not None: | 739 if self.exception_handler is not None: |
668 self.exception_handler(traceback) | 740 self.exception_handler(traceback) |
669 exc_type, exc_value, tb = traceback.standard_exc_info | 741 exc_type, exc_value, tb = traceback.standard_exc_info |
670 raise exc_type, exc_value, tb | 742 reraise(exc_type, exc_value, tb) |
671 | 743 |
672 def join_path(self, template, parent): | 744 def join_path(self, template, parent): |
673 """Join a template with the parent. By default all the lookups are | 745 """Join a template with the parent. By default all the lookups are |
674 relative to the loader root so this method returns the `template` | 746 relative to the loader root so this method returns the `template` |
675 parameter unchanged, but if the paths should be relative to the | 747 parameter unchanged, but if the paths should be relative to the |
676 parent template, this function can be used to calculate the real | 748 parent template, this function can be used to calculate the real |
677 template name. | 749 template name. |
678 | 750 |
679 Subclasses may override this method and implement template path | 751 Subclasses may override this method and implement template path |
680 joining here. | 752 joining here. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 | 819 |
748 @internalcode | 820 @internalcode |
749 def get_or_select_template(self, template_name_or_list, | 821 def get_or_select_template(self, template_name_or_list, |
750 parent=None, globals=None): | 822 parent=None, globals=None): |
751 """Does a typecheck and dispatches to :meth:`select_template` | 823 """Does a typecheck and dispatches to :meth:`select_template` |
752 if an iterable of template names is given, otherwise to | 824 if an iterable of template names is given, otherwise to |
753 :meth:`get_template`. | 825 :meth:`get_template`. |
754 | 826 |
755 .. versionadded:: 2.3 | 827 .. versionadded:: 2.3 |
756 """ | 828 """ |
757 if isinstance(template_name_or_list, basestring): | 829 if isinstance(template_name_or_list, string_types): |
758 return self.get_template(template_name_or_list, parent, globals) | 830 return self.get_template(template_name_or_list, parent, globals) |
759 elif isinstance(template_name_or_list, Template): | 831 elif isinstance(template_name_or_list, Template): |
760 return template_name_or_list | 832 return template_name_or_list |
761 return self.select_template(template_name_or_list, parent, globals) | 833 return self.select_template(template_name_or_list, parent, globals) |
762 | 834 |
763 def from_string(self, source, globals=None, template_class=None): | 835 def from_string(self, source, globals=None, template_class=None): |
764 """Load a template from a string. This parses the source given and | 836 """Load a template from a string. This parses the source given and |
765 returns a :class:`Template` object. | 837 returns a :class:`Template` object. |
766 """ | 838 """ |
767 globals = self.make_globals(globals) | 839 globals = self.make_globals(globals) |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 def __new__(cls, source, | 881 def __new__(cls, source, |
810 block_start_string=BLOCK_START_STRING, | 882 block_start_string=BLOCK_START_STRING, |
811 block_end_string=BLOCK_END_STRING, | 883 block_end_string=BLOCK_END_STRING, |
812 variable_start_string=VARIABLE_START_STRING, | 884 variable_start_string=VARIABLE_START_STRING, |
813 variable_end_string=VARIABLE_END_STRING, | 885 variable_end_string=VARIABLE_END_STRING, |
814 comment_start_string=COMMENT_START_STRING, | 886 comment_start_string=COMMENT_START_STRING, |
815 comment_end_string=COMMENT_END_STRING, | 887 comment_end_string=COMMENT_END_STRING, |
816 line_statement_prefix=LINE_STATEMENT_PREFIX, | 888 line_statement_prefix=LINE_STATEMENT_PREFIX, |
817 line_comment_prefix=LINE_COMMENT_PREFIX, | 889 line_comment_prefix=LINE_COMMENT_PREFIX, |
818 trim_blocks=TRIM_BLOCKS, | 890 trim_blocks=TRIM_BLOCKS, |
| 891 lstrip_blocks=LSTRIP_BLOCKS, |
819 newline_sequence=NEWLINE_SEQUENCE, | 892 newline_sequence=NEWLINE_SEQUENCE, |
| 893 keep_trailing_newline=KEEP_TRAILING_NEWLINE, |
820 extensions=(), | 894 extensions=(), |
821 optimized=True, | 895 optimized=True, |
822 undefined=Undefined, | 896 undefined=Undefined, |
823 finalize=None, | 897 finalize=None, |
824 autoescape=False): | 898 autoescape=False): |
825 env = get_spontaneous_environment( | 899 env = get_spontaneous_environment( |
826 block_start_string, block_end_string, variable_start_string, | 900 block_start_string, block_end_string, variable_start_string, |
827 variable_end_string, comment_start_string, comment_end_string, | 901 variable_end_string, comment_start_string, comment_end_string, |
828 line_statement_prefix, line_comment_prefix, trim_blocks, | 902 line_statement_prefix, line_comment_prefix, trim_blocks, |
829 newline_sequence, frozenset(extensions), optimized, undefined, | 903 lstrip_blocks, newline_sequence, keep_trailing_newline, |
830 finalize, autoescape, None, 0, False, None) | 904 frozenset(extensions), optimized, undefined, finalize, autoescape, |
| 905 None, 0, False, None) |
831 return env.from_string(source, template_class=cls) | 906 return env.from_string(source, template_class=cls) |
832 | 907 |
833 @classmethod | 908 @classmethod |
834 def from_code(cls, environment, code, globals, uptodate=None): | 909 def from_code(cls, environment, code, globals, uptodate=None): |
835 """Creates a template object from compiled code and the globals. This | 910 """Creates a template object from compiled code and the globals. This |
836 is used by the loaders and environment to create a template object. | 911 is used by the loaders and environment to create a template object. |
837 """ | 912 """ |
838 namespace = { | 913 namespace = { |
839 'environment': environment, | 914 'environment': environment, |
840 '__file__': code.co_filename | 915 '__file__': code.co_filename |
841 } | 916 } |
842 exec code in namespace | 917 exec(code, namespace) |
843 rv = cls._from_namespace(environment, namespace, globals) | 918 rv = cls._from_namespace(environment, namespace, globals) |
844 rv._uptodate = uptodate | 919 rv._uptodate = uptodate |
845 return rv | 920 return rv |
846 | 921 |
847 @classmethod | 922 @classmethod |
848 def from_module_dict(cls, environment, module_dict, globals): | 923 def from_module_dict(cls, environment, module_dict, globals): |
849 """Creates a template object from a module. This is used by the | 924 """Creates a template object from a module. This is used by the |
850 module loader to create a template object. | 925 module loader to create a template object. |
851 | 926 |
852 .. versionadded:: 2.4 | 927 .. versionadded:: 2.4 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 @property | 1041 @property |
967 def is_up_to_date(self): | 1042 def is_up_to_date(self): |
968 """If this variable is `False` there is a newer version available.""" | 1043 """If this variable is `False` there is a newer version available.""" |
969 if self._uptodate is None: | 1044 if self._uptodate is None: |
970 return True | 1045 return True |
971 return self._uptodate() | 1046 return self._uptodate() |
972 | 1047 |
973 @property | 1048 @property |
974 def debug_info(self): | 1049 def debug_info(self): |
975 """The debug info mapping.""" | 1050 """The debug info mapping.""" |
976 return [tuple(map(int, x.split('='))) for x in | 1051 return [tuple(imap(int, x.split('='))) for x in |
977 self._debug_info.split('&')] | 1052 self._debug_info.split('&')] |
978 | 1053 |
979 def __repr__(self): | 1054 def __repr__(self): |
980 if self.name is None: | 1055 if self.name is None: |
981 name = 'memory:%x' % id(self) | 1056 name = 'memory:%x' % id(self) |
982 else: | 1057 else: |
983 name = repr(self.name) | 1058 name = repr(self.name) |
984 return '<%s %s>' % (self.__class__.__name__, name) | 1059 return '<%s %s>' % (self.__class__.__name__, name) |
985 | 1060 |
986 | 1061 |
| 1062 @implements_to_string |
987 class TemplateModule(object): | 1063 class TemplateModule(object): |
988 """Represents an imported template. All the exported names of the | 1064 """Represents an imported template. All the exported names of the |
989 template are available as attributes on this object. Additionally | 1065 template are available as attributes on this object. Additionally |
990 converting it into an unicode- or bytestrings renders the contents. | 1066 converting it into an unicode- or bytestrings renders the contents. |
991 """ | 1067 """ |
992 | 1068 |
993 def __init__(self, template, context): | 1069 def __init__(self, template, context): |
994 self._body_stream = list(template.root_render_func(context)) | 1070 self._body_stream = list(template.root_render_func(context)) |
995 self.__dict__.update(context.get_exported()) | 1071 self.__dict__.update(context.get_exported()) |
996 self.__name__ = template.name | 1072 self.__name__ = template.name |
997 | 1073 |
998 def __html__(self): | 1074 def __html__(self): |
999 return Markup(concat(self._body_stream)) | 1075 return Markup(concat(self._body_stream)) |
1000 | 1076 |
1001 def __str__(self): | 1077 def __str__(self): |
1002 return unicode(self).encode('utf-8') | |
1003 | |
1004 # unicode goes after __str__ because we configured 2to3 to rename | |
1005 # __unicode__ to __str__. because the 2to3 tree is not designed to | |
1006 # remove nodes from it, we leave the above __str__ around and let | |
1007 # it override at runtime. | |
1008 def __unicode__(self): | |
1009 return concat(self._body_stream) | 1078 return concat(self._body_stream) |
1010 | 1079 |
1011 def __repr__(self): | 1080 def __repr__(self): |
1012 if self.__name__ is None: | 1081 if self.__name__ is None: |
1013 name = 'memory:%x' % id(self) | 1082 name = 'memory:%x' % id(self) |
1014 else: | 1083 else: |
1015 name = repr(self.__name__) | 1084 name = repr(self.__name__) |
1016 return '<%s %s>' % (self.__class__.__name__, name) | 1085 return '<%s %s>' % (self.__class__.__name__, name) |
1017 | 1086 |
1018 | 1087 |
1019 class TemplateExpression(object): | 1088 class TemplateExpression(object): |
1020 """The :meth:`jinja2.Environment.compile_expression` method returns an | 1089 """The :meth:`jinja2.Environment.compile_expression` method returns an |
1021 instance of this object. It encapsulates the expression-like access | 1090 instance of this object. It encapsulates the expression-like access |
1022 to the template with an expression it wraps. | 1091 to the template with an expression it wraps. |
1023 """ | 1092 """ |
1024 | 1093 |
1025 def __init__(self, template, undefined_to_none): | 1094 def __init__(self, template, undefined_to_none): |
1026 self._template = template | 1095 self._template = template |
1027 self._undefined_to_none = undefined_to_none | 1096 self._undefined_to_none = undefined_to_none |
1028 | 1097 |
1029 def __call__(self, *args, **kwargs): | 1098 def __call__(self, *args, **kwargs): |
1030 context = self._template.new_context(dict(*args, **kwargs)) | 1099 context = self._template.new_context(dict(*args, **kwargs)) |
1031 consume(self._template.root_render_func(context)) | 1100 consume(self._template.root_render_func(context)) |
1032 rv = context.vars['result'] | 1101 rv = context.vars['result'] |
1033 if self._undefined_to_none and isinstance(rv, Undefined): | 1102 if self._undefined_to_none and isinstance(rv, Undefined): |
1034 rv = None | 1103 rv = None |
1035 return rv | 1104 return rv |
1036 | 1105 |
1037 | 1106 |
| 1107 @implements_iterator |
1038 class TemplateStream(object): | 1108 class TemplateStream(object): |
1039 """A template stream works pretty much like an ordinary python generator | 1109 """A template stream works pretty much like an ordinary python generator |
1040 but it can buffer multiple items to reduce the number of total iterations. | 1110 but it can buffer multiple items to reduce the number of total iterations. |
1041 Per default the output is unbuffered which means that for every unbuffered | 1111 Per default the output is unbuffered which means that for every unbuffered |
1042 instruction in the template one unicode string is yielded. | 1112 instruction in the template one unicode string is yielded. |
1043 | 1113 |
1044 If buffering is enabled with a buffer size of 5, five items are combined | 1114 If buffering is enabled with a buffer size of 5, five items are combined |
1045 into a new unicode string. This is mainly useful if you are streaming | 1115 into a new unicode string. This is mainly useful if you are streaming |
1046 big templates to a client via WSGI which flushes after each iteration. | 1116 big templates to a client via WSGI which flushes after each iteration. |
1047 """ | 1117 """ |
1048 | 1118 |
1049 def __init__(self, gen): | 1119 def __init__(self, gen): |
1050 self._gen = gen | 1120 self._gen = gen |
1051 self.disable_buffering() | 1121 self.disable_buffering() |
1052 | 1122 |
1053 def dump(self, fp, encoding=None, errors='strict'): | 1123 def dump(self, fp, encoding=None, errors='strict'): |
1054 """Dump the complete stream into a file or file-like object. | 1124 """Dump the complete stream into a file or file-like object. |
1055 Per default unicode strings are written, if you want to encode | 1125 Per default unicode strings are written, if you want to encode |
1056 before writing specifiy an `encoding`. | 1126 before writing specify an `encoding`. |
1057 | 1127 |
1058 Example usage:: | 1128 Example usage:: |
1059 | 1129 |
1060 Template('Hello {{ name }}!').stream(name='foo').dump('hello.html') | 1130 Template('Hello {{ name }}!').stream(name='foo').dump('hello.html') |
1061 """ | 1131 """ |
1062 close = False | 1132 close = False |
1063 if isinstance(fp, basestring): | 1133 if isinstance(fp, string_types): |
1064 fp = file(fp, 'w') | 1134 fp = open(fp, encoding is None and 'w' or 'wb') |
1065 close = True | 1135 close = True |
1066 try: | 1136 try: |
1067 if encoding is not None: | 1137 if encoding is not None: |
1068 iterable = (x.encode(encoding, errors) for x in self) | 1138 iterable = (x.encode(encoding, errors) for x in self) |
1069 else: | 1139 else: |
1070 iterable = self | 1140 iterable = self |
1071 if hasattr(fp, 'writelines'): | 1141 if hasattr(fp, 'writelines'): |
1072 fp.writelines(iterable) | 1142 fp.writelines(iterable) |
1073 else: | 1143 else: |
1074 for item in iterable: | 1144 for item in iterable: |
1075 fp.write(item) | 1145 fp.write(item) |
1076 finally: | 1146 finally: |
1077 if close: | 1147 if close: |
1078 fp.close() | 1148 fp.close() |
1079 | 1149 |
1080 def disable_buffering(self): | 1150 def disable_buffering(self): |
1081 """Disable the output buffering.""" | 1151 """Disable the output buffering.""" |
1082 self._next = self._gen.next | 1152 self._next = get_next(self._gen) |
1083 self.buffered = False | 1153 self.buffered = False |
1084 | 1154 |
1085 def enable_buffering(self, size=5): | 1155 def enable_buffering(self, size=5): |
1086 """Enable buffering. Buffer `size` items before yielding them.""" | 1156 """Enable buffering. Buffer `size` items before yielding them.""" |
1087 if size <= 1: | 1157 if size <= 1: |
1088 raise ValueError('buffer size too small') | 1158 raise ValueError('buffer size too small') |
1089 | 1159 |
1090 def generator(next): | 1160 def generator(next): |
1091 buf = [] | 1161 buf = [] |
1092 c_size = 0 | 1162 c_size = 0 |
1093 push = buf.append | 1163 push = buf.append |
1094 | 1164 |
1095 while 1: | 1165 while 1: |
1096 try: | 1166 try: |
1097 while c_size < size: | 1167 while c_size < size: |
1098 c = next() | 1168 c = next() |
1099 push(c) | 1169 push(c) |
1100 if c: | 1170 if c: |
1101 c_size += 1 | 1171 c_size += 1 |
1102 except StopIteration: | 1172 except StopIteration: |
1103 if not c_size: | 1173 if not c_size: |
1104 return | 1174 return |
1105 yield concat(buf) | 1175 yield concat(buf) |
1106 del buf[:] | 1176 del buf[:] |
1107 c_size = 0 | 1177 c_size = 0 |
1108 | 1178 |
1109 self.buffered = True | 1179 self.buffered = True |
1110 self._next = generator(self._gen.next).next | 1180 self._next = get_next(generator(get_next(self._gen))) |
1111 | 1181 |
1112 def __iter__(self): | 1182 def __iter__(self): |
1113 return self | 1183 return self |
1114 | 1184 |
1115 def next(self): | 1185 def __next__(self): |
1116 return self._next() | 1186 return self._next() |
1117 | 1187 |
1118 | 1188 |
1119 # hook in default template class. if anyone reads this comment: ignore that | 1189 # hook in default template class. if anyone reads this comment: ignore that |
1120 # it's possible to use custom templates ;-) | 1190 # it's possible to use custom templates ;-) |
1121 Environment.template_class = Template | 1191 Environment.template_class = Template |
OLD | NEW |