OLD | NEW |
(Empty) | |
| 1 # -*- coding: utf-8 -*- |
| 2 """ |
| 3 jinja2.environment |
| 4 ~~~~~~~~~~~~~~~~~~ |
| 5 |
| 6 Provides a class that holds runtime and parsing time options. |
| 7 |
| 8 :copyright: (c) 2010 by the Jinja Team. |
| 9 :license: BSD, see LICENSE for more details. |
| 10 """ |
| 11 import os |
| 12 import sys |
| 13 from jinja2 import nodes |
| 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 |
| 20 from jinja2.lexer import get_lexer, TokenStream |
| 21 from jinja2.parser import Parser |
| 22 from jinja2.nodes import EvalContext |
| 23 from jinja2.optimizer import optimize |
| 24 from jinja2.compiler import generate, CodeGenerator |
| 25 from jinja2.runtime import Undefined, new_context, Context |
| 26 from jinja2.exceptions import TemplateSyntaxError, TemplateNotFound, \ |
| 27 TemplatesNotFound, TemplateRuntimeError |
| 28 from jinja2.utils import import_string, LRUCache, Markup, missing, \ |
| 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 |
| 34 |
| 35 |
| 36 # for direct template usage we have up to ten living environments |
| 37 _spontaneous_environments = LRUCache(10) |
| 38 |
| 39 # the function to create jinja traceback objects. This is dynamically |
| 40 # imported on the first exception in the exception handler. |
| 41 _make_traceback = None |
| 42 |
| 43 |
| 44 def get_spontaneous_environment(*args): |
| 45 """Return a new spontaneous environment. A spontaneous environment is an |
| 46 unnamed and unaccessible (in theory) environment that is used for |
| 47 templates generated from a string and not from the file system. |
| 48 """ |
| 49 try: |
| 50 env = _spontaneous_environments.get(args) |
| 51 except TypeError: |
| 52 return Environment(*args) |
| 53 if env is not None: |
| 54 return env |
| 55 _spontaneous_environments[args] = env = Environment(*args) |
| 56 env.shared = True |
| 57 return env |
| 58 |
| 59 |
| 60 def create_cache(size): |
| 61 """Return the cache class for the given size.""" |
| 62 if size == 0: |
| 63 return None |
| 64 if size < 0: |
| 65 return {} |
| 66 return LRUCache(size) |
| 67 |
| 68 |
| 69 def copy_cache(cache): |
| 70 """Create an empty copy of the given cache.""" |
| 71 if cache is None: |
| 72 return None |
| 73 elif type(cache) is dict: |
| 74 return {} |
| 75 return LRUCache(cache.capacity) |
| 76 |
| 77 |
| 78 def load_extensions(environment, extensions): |
| 79 """Load the extensions from the list and bind it to the environment. |
| 80 Returns a dict of instantiated environments. |
| 81 """ |
| 82 result = {} |
| 83 for extension in extensions: |
| 84 if isinstance(extension, string_types): |
| 85 extension = import_string(extension) |
| 86 result[extension.identifier] = extension(environment) |
| 87 return result |
| 88 |
| 89 |
| 90 def _environment_sanity_check(environment): |
| 91 """Perform a sanity check on the environment.""" |
| 92 assert issubclass(environment.undefined, Undefined), 'undefined must ' \ |
| 93 'be a subclass of undefined because filters depend on it.' |
| 94 assert environment.block_start_string != \ |
| 95 environment.variable_start_string != \ |
| 96 environment.comment_start_string, 'block, variable and comment ' \ |
| 97 'start strings must be different' |
| 98 assert environment.newline_sequence in ('\r', '\r\n', '\n'), \ |
| 99 'newline_sequence set to unknown line ending string.' |
| 100 return environment |
| 101 |
| 102 |
| 103 class Environment(object): |
| 104 r"""The core component of Jinja is the `Environment`. It contains |
| 105 important shared variables like configuration, filters, tests, |
| 106 globals and others. Instances of this class may be modified if |
| 107 they are not shared and if no template was loaded so far. |
| 108 Modifications on environments after the first template was loaded |
| 109 will lead to surprising effects and undefined behavior. |
| 110 |
| 111 Here are the possible initialization parameters: |
| 112 |
| 113 `block_start_string` |
| 114 The string marking the beginning of a block. Defaults to ``'{%'``. |
| 115 |
| 116 `block_end_string` |
| 117 The string marking the end of a block. Defaults to ``'%}'``. |
| 118 |
| 119 `variable_start_string` |
| 120 The string marking the beginning of a print statement. |
| 121 Defaults to ``'{{'``. |
| 122 |
| 123 `variable_end_string` |
| 124 The string marking the end of a print statement. Defaults to |
| 125 ``'}}'``. |
| 126 |
| 127 `comment_start_string` |
| 128 The string marking the beginning of a comment. Defaults to ``'{#'``
. |
| 129 |
| 130 `comment_end_string` |
| 131 The string marking the end of a comment. Defaults to ``'#}'``. |
| 132 |
| 133 `line_statement_prefix` |
| 134 If given and a string, this will be used as prefix for line based |
| 135 statements. See also :ref:`line-statements`. |
| 136 |
| 137 `line_comment_prefix` |
| 138 If given and a string, this will be used as prefix for line based |
| 139 comments. See also :ref:`line-statements`. |
| 140 |
| 141 .. versionadded:: 2.2 |
| 142 |
| 143 `trim_blocks` |
| 144 If this is set to ``True`` the first newline after a block is |
| 145 removed (block, not variable tag!). Defaults to `False`. |
| 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 |
| 151 `newline_sequence` |
| 152 The sequence that starts a newline. Must be one of ``'\r'``, |
| 153 ``'\n'`` or ``'\r\n'``. The default is ``'\n'`` which is a |
| 154 useful default for Linux and OS X systems as well as web |
| 155 applications. |
| 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 |
| 164 `extensions` |
| 165 List of Jinja extensions to use. This can either be import paths |
| 166 as strings or extension classes. For more information have a |
| 167 look at :ref:`the extensions documentation <jinja-extensions>`. |
| 168 |
| 169 `optimized` |
| 170 should the optimizer be enabled? Default is `True`. |
| 171 |
| 172 `undefined` |
| 173 :class:`Undefined` or a subclass of it that is used to represent |
| 174 undefined values in the template. |
| 175 |
| 176 `finalize` |
| 177 A callable that can be used to process the result of a variable |
| 178 expression before it is output. For example one can convert |
| 179 `None` implicitly into an empty string here. |
| 180 |
| 181 `autoescape` |
| 182 If set to true the XML/HTML autoescaping feature is enabled by |
| 183 default. For more details about autoescaping see |
| 184 :class:`~jinja2.utils.Markup`. As of Jinja 2.4 this can also |
| 185 be a callable that is passed the template name and has to |
| 186 return `True` or `False` depending on autoescape should be |
| 187 enabled by default. |
| 188 |
| 189 .. versionchanged:: 2.4 |
| 190 `autoescape` can now be a function |
| 191 |
| 192 `loader` |
| 193 The template loader for this environment. |
| 194 |
| 195 `cache_size` |
| 196 The size of the cache. Per default this is ``400`` which means |
| 197 that if more than 400 templates are loaded the loader will clean |
| 198 out the least recently used template. If the cache size is set to |
| 199 ``0`` templates are recompiled all the time, if the cache size is |
| 200 ``-1`` the cache will not be cleaned. |
| 201 |
| 202 .. versionchanged:: 2.8 |
| 203 The cache size was increased to 400 from a low 50. |
| 204 |
| 205 `auto_reload` |
| 206 Some loaders load templates from locations where the template |
| 207 sources may change (ie: file system or database). If |
| 208 `auto_reload` is set to `True` (default) every time a template is |
| 209 requested the loader checks if the source changed and if yes, it |
| 210 will reload the template. For higher performance it's possible to |
| 211 disable that. |
| 212 |
| 213 `bytecode_cache` |
| 214 If set to a bytecode cache object, this object will provide a |
| 215 cache for the internal Jinja bytecode so that templates don't |
| 216 have to be parsed if they were not changed. |
| 217 |
| 218 See :ref:`bytecode-cache` for more information. |
| 219 """ |
| 220 |
| 221 #: if this environment is sandboxed. Modifying this variable won't make |
| 222 #: the environment sandboxed though. For a real sandboxed environment |
| 223 #: have a look at jinja2.sandbox. This flag alone controls the code |
| 224 #: generation by the compiler. |
| 225 sandboxed = False |
| 226 |
| 227 #: True if the environment is just an overlay |
| 228 overlayed = False |
| 229 |
| 230 #: the environment this environment is linked to if it is an overlay |
| 231 linked_to = None |
| 232 |
| 233 #: shared environments have this set to `True`. A shared environment |
| 234 #: must not be modified |
| 235 shared = False |
| 236 |
| 237 #: these are currently EXPERIMENTAL undocumented features. |
| 238 exception_handler = None |
| 239 exception_formatter = None |
| 240 |
| 241 #: the class that is used for code generation. See |
| 242 #: :class:`~jinja2.compiler.CodeGenerator` for more information. |
| 243 code_generator_class = CodeGenerator |
| 244 |
| 245 #: the context class thatis used for templates. See |
| 246 #: :class:`~jinja2.runtime.Context` for more information. |
| 247 context_class = Context |
| 248 |
| 249 def __init__(self, |
| 250 block_start_string=BLOCK_START_STRING, |
| 251 block_end_string=BLOCK_END_STRING, |
| 252 variable_start_string=VARIABLE_START_STRING, |
| 253 variable_end_string=VARIABLE_END_STRING, |
| 254 comment_start_string=COMMENT_START_STRING, |
| 255 comment_end_string=COMMENT_END_STRING, |
| 256 line_statement_prefix=LINE_STATEMENT_PREFIX, |
| 257 line_comment_prefix=LINE_COMMENT_PREFIX, |
| 258 trim_blocks=TRIM_BLOCKS, |
| 259 lstrip_blocks=LSTRIP_BLOCKS, |
| 260 newline_sequence=NEWLINE_SEQUENCE, |
| 261 keep_trailing_newline=KEEP_TRAILING_NEWLINE, |
| 262 extensions=(), |
| 263 optimized=True, |
| 264 undefined=Undefined, |
| 265 finalize=None, |
| 266 autoescape=False, |
| 267 loader=None, |
| 268 cache_size=400, |
| 269 auto_reload=True, |
| 270 bytecode_cache=None): |
| 271 # !!Important notice!! |
| 272 # The constructor accepts quite a few arguments that should be |
| 273 # passed by keyword rather than position. However it's important to |
| 274 # not change the order of arguments because it's used at least |
| 275 # internally in those cases: |
| 276 # - spontaneous environments (i18n extension and Template) |
| 277 # - unittests |
| 278 # If parameter changes are required only add parameters at the end |
| 279 # and don't change the arguments (or the defaults!) of the arguments |
| 280 # existing already. |
| 281 |
| 282 # lexer / parser information |
| 283 self.block_start_string = block_start_string |
| 284 self.block_end_string = block_end_string |
| 285 self.variable_start_string = variable_start_string |
| 286 self.variable_end_string = variable_end_string |
| 287 self.comment_start_string = comment_start_string |
| 288 self.comment_end_string = comment_end_string |
| 289 self.line_statement_prefix = line_statement_prefix |
| 290 self.line_comment_prefix = line_comment_prefix |
| 291 self.trim_blocks = trim_blocks |
| 292 self.lstrip_blocks = lstrip_blocks |
| 293 self.newline_sequence = newline_sequence |
| 294 self.keep_trailing_newline = keep_trailing_newline |
| 295 |
| 296 # runtime information |
| 297 self.undefined = undefined |
| 298 self.optimized = optimized |
| 299 self.finalize = finalize |
| 300 self.autoescape = autoescape |
| 301 |
| 302 # defaults |
| 303 self.filters = DEFAULT_FILTERS.copy() |
| 304 self.tests = DEFAULT_TESTS.copy() |
| 305 self.globals = DEFAULT_NAMESPACE.copy() |
| 306 |
| 307 # set the loader provided |
| 308 self.loader = loader |
| 309 self.cache = create_cache(cache_size) |
| 310 self.bytecode_cache = bytecode_cache |
| 311 self.auto_reload = auto_reload |
| 312 |
| 313 # load extensions |
| 314 self.extensions = load_extensions(self, extensions) |
| 315 |
| 316 _environment_sanity_check(self) |
| 317 |
| 318 def add_extension(self, extension): |
| 319 """Adds an extension after the environment was created. |
| 320 |
| 321 .. versionadded:: 2.5 |
| 322 """ |
| 323 self.extensions.update(load_extensions(self, [extension])) |
| 324 |
| 325 def extend(self, **attributes): |
| 326 """Add the items to the instance of the environment if they do not exist |
| 327 yet. This is used by :ref:`extensions <writing-extensions>` to register |
| 328 callbacks and configuration values without breaking inheritance. |
| 329 """ |
| 330 for key, value in iteritems(attributes): |
| 331 if not hasattr(self, key): |
| 332 setattr(self, key, value) |
| 333 |
| 334 def overlay(self, block_start_string=missing, block_end_string=missing, |
| 335 variable_start_string=missing, variable_end_string=missing, |
| 336 comment_start_string=missing, comment_end_string=missing, |
| 337 line_statement_prefix=missing, line_comment_prefix=missing, |
| 338 trim_blocks=missing, lstrip_blocks=missing, |
| 339 extensions=missing, optimized=missing, |
| 340 undefined=missing, finalize=missing, autoescape=missing, |
| 341 loader=missing, cache_size=missing, auto_reload=missing, |
| 342 bytecode_cache=missing): |
| 343 """Create a new overlay environment that shares all the data with the |
| 344 current environment except for cache and the overridden attributes. |
| 345 Extensions cannot be removed for an overlayed environment. An overlayed |
| 346 environment automatically gets all the extensions of the environment it |
| 347 is linked to plus optional extra extensions. |
| 348 |
| 349 Creating overlays should happen after the initial environment was set |
| 350 up completely. Not all attributes are truly linked, some are just |
| 351 copied over so modifications on the original environment may not shine |
| 352 through. |
| 353 """ |
| 354 args = dict(locals()) |
| 355 del args['self'], args['cache_size'], args['extensions'] |
| 356 |
| 357 rv = object.__new__(self.__class__) |
| 358 rv.__dict__.update(self.__dict__) |
| 359 rv.overlayed = True |
| 360 rv.linked_to = self |
| 361 |
| 362 for key, value in iteritems(args): |
| 363 if value is not missing: |
| 364 setattr(rv, key, value) |
| 365 |
| 366 if cache_size is not missing: |
| 367 rv.cache = create_cache(cache_size) |
| 368 else: |
| 369 rv.cache = copy_cache(self.cache) |
| 370 |
| 371 rv.extensions = {} |
| 372 for key, value in iteritems(self.extensions): |
| 373 rv.extensions[key] = value.bind(rv) |
| 374 if extensions is not missing: |
| 375 rv.extensions.update(load_extensions(rv, extensions)) |
| 376 |
| 377 return _environment_sanity_check(rv) |
| 378 |
| 379 lexer = property(get_lexer, doc="The lexer for this environment.") |
| 380 |
| 381 def iter_extensions(self): |
| 382 """Iterates over the extensions by priority.""" |
| 383 return iter(sorted(self.extensions.values(), |
| 384 key=lambda x: x.priority)) |
| 385 |
| 386 def getitem(self, obj, argument): |
| 387 """Get an item or attribute of an object but prefer the item.""" |
| 388 try: |
| 389 return obj[argument] |
| 390 except (TypeError, LookupError): |
| 391 if isinstance(argument, string_types): |
| 392 try: |
| 393 attr = str(argument) |
| 394 except Exception: |
| 395 pass |
| 396 else: |
| 397 try: |
| 398 return getattr(obj, attr) |
| 399 except AttributeError: |
| 400 pass |
| 401 return self.undefined(obj=obj, name=argument) |
| 402 |
| 403 def getattr(self, obj, attribute): |
| 404 """Get an item or attribute of an object but prefer the attribute. |
| 405 Unlike :meth:`getitem` the attribute *must* be a bytestring. |
| 406 """ |
| 407 try: |
| 408 return getattr(obj, attribute) |
| 409 except AttributeError: |
| 410 pass |
| 411 try: |
| 412 return obj[attribute] |
| 413 except (TypeError, LookupError, AttributeError): |
| 414 return self.undefined(obj=obj, name=attribute) |
| 415 |
| 416 def call_filter(self, name, value, args=None, kwargs=None, |
| 417 context=None, eval_ctx=None): |
| 418 """Invokes a filter on a value the same way the compiler does it. |
| 419 |
| 420 .. versionadded:: 2.7 |
| 421 """ |
| 422 func = self.filters.get(name) |
| 423 if func is None: |
| 424 raise TemplateRuntimeError('no filter named %r' % name) |
| 425 args = [value] + list(args or ()) |
| 426 if getattr(func, 'contextfilter', False): |
| 427 if context is None: |
| 428 raise TemplateRuntimeError('Attempted to invoke context ' |
| 429 'filter without context') |
| 430 args.insert(0, context) |
| 431 elif getattr(func, 'evalcontextfilter', False): |
| 432 if eval_ctx is None: |
| 433 if context is not None: |
| 434 eval_ctx = context.eval_ctx |
| 435 else: |
| 436 eval_ctx = EvalContext(self) |
| 437 args.insert(0, eval_ctx) |
| 438 elif getattr(func, 'environmentfilter', False): |
| 439 args.insert(0, self) |
| 440 return func(*args, **(kwargs or {})) |
| 441 |
| 442 def call_test(self, name, value, args=None, kwargs=None): |
| 443 """Invokes a test on a value the same way the compiler does it. |
| 444 |
| 445 .. versionadded:: 2.7 |
| 446 """ |
| 447 func = self.tests.get(name) |
| 448 if func is None: |
| 449 raise TemplateRuntimeError('no test named %r' % name) |
| 450 return func(value, *(args or ()), **(kwargs or {})) |
| 451 |
| 452 @internalcode |
| 453 def parse(self, source, name=None, filename=None): |
| 454 """Parse the sourcecode and return the abstract syntax tree. This |
| 455 tree of nodes is used by the compiler to convert the template into |
| 456 executable source- or bytecode. This is useful for debugging or to |
| 457 extract information from templates. |
| 458 |
| 459 If you are :ref:`developing Jinja2 extensions <writing-extensions>` |
| 460 this gives you a good overview of the node tree generated. |
| 461 """ |
| 462 try: |
| 463 return self._parse(source, name, filename) |
| 464 except TemplateSyntaxError: |
| 465 exc_info = sys.exc_info() |
| 466 self.handle_exception(exc_info, source_hint=source) |
| 467 |
| 468 def _parse(self, source, name, filename): |
| 469 """Internal parsing function used by `parse` and `compile`.""" |
| 470 return Parser(self, source, name, encode_filename(filename)).parse() |
| 471 |
| 472 def lex(self, source, name=None, filename=None): |
| 473 """Lex the given sourcecode and return a generator that yields |
| 474 tokens as tuples in the form ``(lineno, token_type, value)``. |
| 475 This can be useful for :ref:`extension development <writing-extensions>` |
| 476 and debugging templates. |
| 477 |
| 478 This does not perform preprocessing. If you want the preprocessing |
| 479 of the extensions to be applied you have to filter source through |
| 480 the :meth:`preprocess` method. |
| 481 """ |
| 482 source = text_type(source) |
| 483 try: |
| 484 return self.lexer.tokeniter(source, name, filename) |
| 485 except TemplateSyntaxError: |
| 486 exc_info = sys.exc_info() |
| 487 self.handle_exception(exc_info, source_hint=source) |
| 488 |
| 489 def preprocess(self, source, name=None, filename=None): |
| 490 """Preprocesses the source with all extensions. This is automatically |
| 491 called for all parsing and compiling methods but *not* for :meth:`lex` |
| 492 because there you usually only want the actual source tokenized. |
| 493 """ |
| 494 return reduce(lambda s, e: e.preprocess(s, name, filename), |
| 495 self.iter_extensions(), text_type(source)) |
| 496 |
| 497 def _tokenize(self, source, name, filename=None, state=None): |
| 498 """Called by the parser to do the preprocessing and filtering |
| 499 for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`. |
| 500 """ |
| 501 source = self.preprocess(source, name, filename) |
| 502 stream = self.lexer.tokenize(source, name, filename, state) |
| 503 for ext in self.iter_extensions(): |
| 504 stream = ext.filter_stream(stream) |
| 505 if not isinstance(stream, TokenStream): |
| 506 stream = TokenStream(stream, name, filename) |
| 507 return stream |
| 508 |
| 509 def _generate(self, source, name, filename, defer_init=False): |
| 510 """Internal hook that can be overridden to hook a different generate |
| 511 method in. |
| 512 |
| 513 .. versionadded:: 2.5 |
| 514 """ |
| 515 return generate(source, self, name, filename, defer_init=defer_init) |
| 516 |
| 517 def _compile(self, source, filename): |
| 518 """Internal hook that can be overridden to hook a different compile |
| 519 method in. |
| 520 |
| 521 .. versionadded:: 2.5 |
| 522 """ |
| 523 return compile(source, filename, 'exec') |
| 524 |
| 525 @internalcode |
| 526 def compile(self, source, name=None, filename=None, raw=False, |
| 527 defer_init=False): |
| 528 """Compile a node or template source code. The `name` parameter is |
| 529 the load name of the template after it was joined using |
| 530 :meth:`join_path` if necessary, not the filename on the file system. |
| 531 the `filename` parameter is the estimated filename of the template on |
| 532 the file system. If the template came from a database or memory this |
| 533 can be omitted. |
| 534 |
| 535 The return value of this method is a python code object. If the `raw` |
| 536 parameter is `True` the return value will be a string with python |
| 537 code equivalent to the bytecode returned otherwise. This method is |
| 538 mainly used internally. |
| 539 |
| 540 `defer_init` is use internally to aid the module code generator. This |
| 541 causes the generated code to be able to import without the global |
| 542 environment variable to be set. |
| 543 |
| 544 .. versionadded:: 2.4 |
| 545 `defer_init` parameter added. |
| 546 """ |
| 547 source_hint = None |
| 548 try: |
| 549 if isinstance(source, string_types): |
| 550 source_hint = source |
| 551 source = self._parse(source, name, filename) |
| 552 if self.optimized: |
| 553 source = optimize(source, self) |
| 554 source = self._generate(source, name, filename, |
| 555 defer_init=defer_init) |
| 556 if raw: |
| 557 return source |
| 558 if filename is None: |
| 559 filename = '<template>' |
| 560 else: |
| 561 filename = encode_filename(filename) |
| 562 return self._compile(source, filename) |
| 563 except TemplateSyntaxError: |
| 564 exc_info = sys.exc_info() |
| 565 self.handle_exception(exc_info, source_hint=source_hint) |
| 566 |
| 567 def compile_expression(self, source, undefined_to_none=True): |
| 568 """A handy helper method that returns a callable that accepts keyword |
| 569 arguments that appear as variables in the expression. If called it |
| 570 returns the result of the expression. |
| 571 |
| 572 This is useful if applications want to use the same rules as Jinja |
| 573 in template "configuration files" or similar situations. |
| 574 |
| 575 Example usage: |
| 576 |
| 577 >>> env = Environment() |
| 578 >>> expr = env.compile_expression('foo == 42') |
| 579 >>> expr(foo=23) |
| 580 False |
| 581 >>> expr(foo=42) |
| 582 True |
| 583 |
| 584 Per default the return value is converted to `None` if the |
| 585 expression returns an undefined value. This can be changed |
| 586 by setting `undefined_to_none` to `False`. |
| 587 |
| 588 >>> env.compile_expression('var')() is None |
| 589 True |
| 590 >>> env.compile_expression('var', undefined_to_none=False)() |
| 591 Undefined |
| 592 |
| 593 .. versionadded:: 2.1 |
| 594 """ |
| 595 parser = Parser(self, source, state='variable') |
| 596 exc_info = None |
| 597 try: |
| 598 expr = parser.parse_expression() |
| 599 if not parser.stream.eos: |
| 600 raise TemplateSyntaxError('chunk after expression', |
| 601 parser.stream.current.lineno, |
| 602 None, None) |
| 603 expr.set_environment(self) |
| 604 except TemplateSyntaxError: |
| 605 exc_info = sys.exc_info() |
| 606 if exc_info is not None: |
| 607 self.handle_exception(exc_info, source_hint=source) |
| 608 body = [nodes.Assign(nodes.Name('result', 'store'), expr, lineno=1)] |
| 609 template = self.from_string(nodes.Template(body, lineno=1)) |
| 610 return TemplateExpression(template, undefined_to_none) |
| 611 |
| 612 def compile_templates(self, target, extensions=None, filter_func=None, |
| 613 zip='deflated', log_function=None, |
| 614 ignore_errors=True, py_compile=False): |
| 615 """Finds all the templates the loader can find, compiles them |
| 616 and stores them in `target`. If `zip` is `None`, instead of in a |
| 617 zipfile, the templates will be stored in a directory. |
| 618 By default a deflate zip algorithm is used. To switch to |
| 619 the stored algorithm, `zip` can be set to ``'stored'``. |
| 620 |
| 621 `extensions` and `filter_func` are passed to :meth:`list_templates`. |
| 622 Each template returned will be compiled to the target folder or |
| 623 zipfile. |
| 624 |
| 625 By default template compilation errors are ignored. In case a |
| 626 log function is provided, errors are logged. If you want template |
| 627 syntax errors to abort the compilation you can set `ignore_errors` |
| 628 to `False` and you will get an exception on syntax errors. |
| 629 |
| 630 If `py_compile` is set to `True` .pyc files will be written to the |
| 631 target instead of standard .py files. This flag does not do anything |
| 632 on pypy and Python 3 where pyc files are not picked up by itself and |
| 633 don't give much benefit. |
| 634 |
| 635 .. versionadded:: 2.4 |
| 636 """ |
| 637 from jinja2.loaders import ModuleLoader |
| 638 |
| 639 if log_function is None: |
| 640 log_function = lambda x: None |
| 641 |
| 642 if py_compile: |
| 643 if not PY2 or PYPY: |
| 644 from warnings import warn |
| 645 warn(Warning('py_compile has no effect on pypy or Python 3')) |
| 646 py_compile = False |
| 647 else: |
| 648 import imp |
| 649 import marshal |
| 650 py_header = imp.get_magic() + \ |
| 651 u'\xff\xff\xff\xff'.encode('iso-8859-15') |
| 652 |
| 653 # Python 3.3 added a source filesize to the header |
| 654 if sys.version_info >= (3, 3): |
| 655 py_header += u'\x00\x00\x00\x00'.encode('iso-8859-15') |
| 656 |
| 657 def write_file(filename, data, mode): |
| 658 if zip: |
| 659 info = ZipInfo(filename) |
| 660 info.external_attr = 0o755 << 16 |
| 661 zip_file.writestr(info, data) |
| 662 else: |
| 663 f = open(os.path.join(target, filename), mode) |
| 664 try: |
| 665 f.write(data) |
| 666 finally: |
| 667 f.close() |
| 668 |
| 669 if zip is not None: |
| 670 from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED, ZIP_STORED |
| 671 zip_file = ZipFile(target, 'w', dict(deflated=ZIP_DEFLATED, |
| 672 stored=ZIP_STORED)[zip]) |
| 673 log_function('Compiling into Zip archive "%s"' % target) |
| 674 else: |
| 675 if not os.path.isdir(target): |
| 676 os.makedirs(target) |
| 677 log_function('Compiling into folder "%s"' % target) |
| 678 |
| 679 try: |
| 680 for name in self.list_templates(extensions, filter_func): |
| 681 source, filename, _ = self.loader.get_source(self, name) |
| 682 try: |
| 683 code = self.compile(source, name, filename, True, True) |
| 684 except TemplateSyntaxError as e: |
| 685 if not ignore_errors: |
| 686 raise |
| 687 log_function('Could not compile "%s": %s' % (name, e)) |
| 688 continue |
| 689 |
| 690 filename = ModuleLoader.get_module_filename(name) |
| 691 |
| 692 if py_compile: |
| 693 c = self._compile(code, encode_filename(filename)) |
| 694 write_file(filename + 'c', py_header + |
| 695 marshal.dumps(c), 'wb') |
| 696 log_function('Byte-compiled "%s" as %s' % |
| 697 (name, filename + 'c')) |
| 698 else: |
| 699 write_file(filename, code, 'w') |
| 700 log_function('Compiled "%s" as %s' % (name, filename)) |
| 701 finally: |
| 702 if zip: |
| 703 zip_file.close() |
| 704 |
| 705 log_function('Finished compiling templates') |
| 706 |
| 707 def list_templates(self, extensions=None, filter_func=None): |
| 708 """Returns a list of templates for this environment. This requires |
| 709 that the loader supports the loader's |
| 710 :meth:`~BaseLoader.list_templates` method. |
| 711 |
| 712 If there are other files in the template folder besides the |
| 713 actual templates, the returned list can be filtered. There are two |
| 714 ways: either `extensions` is set to a list of file extensions for |
| 715 templates, or a `filter_func` can be provided which is a callable that |
| 716 is passed a template name and should return `True` if it should end up |
| 717 in the result list. |
| 718 |
| 719 If the loader does not support that, a :exc:`TypeError` is raised. |
| 720 |
| 721 .. versionadded:: 2.4 |
| 722 """ |
| 723 x = self.loader.list_templates() |
| 724 if extensions is not None: |
| 725 if filter_func is not None: |
| 726 raise TypeError('either extensions or filter_func ' |
| 727 'can be passed, but not both') |
| 728 filter_func = lambda x: '.' in x and \ |
| 729 x.rsplit('.', 1)[1] in extensions |
| 730 if filter_func is not None: |
| 731 x = list(ifilter(filter_func, x)) |
| 732 return x |
| 733 |
| 734 def handle_exception(self, exc_info=None, rendered=False, source_hint=None): |
| 735 """Exception handling helper. This is used internally to either raise |
| 736 rewritten exceptions or return a rendered traceback for the template. |
| 737 """ |
| 738 global _make_traceback |
| 739 if exc_info is None: |
| 740 exc_info = sys.exc_info() |
| 741 |
| 742 # the debugging module is imported when it's used for the first time. |
| 743 # we're doing a lot of stuff there and for applications that do not |
| 744 # get any exceptions in template rendering there is no need to load |
| 745 # all of that. |
| 746 if _make_traceback is None: |
| 747 from jinja2.debug import make_traceback as _make_traceback |
| 748 traceback = _make_traceback(exc_info, source_hint) |
| 749 if rendered and self.exception_formatter is not None: |
| 750 return self.exception_formatter(traceback) |
| 751 if self.exception_handler is not None: |
| 752 self.exception_handler(traceback) |
| 753 exc_type, exc_value, tb = traceback.standard_exc_info |
| 754 reraise(exc_type, exc_value, tb) |
| 755 |
| 756 def join_path(self, template, parent): |
| 757 """Join a template with the parent. By default all the lookups are |
| 758 relative to the loader root so this method returns the `template` |
| 759 parameter unchanged, but if the paths should be relative to the |
| 760 parent template, this function can be used to calculate the real |
| 761 template name. |
| 762 |
| 763 Subclasses may override this method and implement template path |
| 764 joining here. |
| 765 """ |
| 766 return template |
| 767 |
| 768 @internalcode |
| 769 def _load_template(self, name, globals): |
| 770 if self.loader is None: |
| 771 raise TypeError('no loader for this environment specified') |
| 772 try: |
| 773 # use abs path for cache key |
| 774 cache_key = self.loader.get_source(self, name)[1] |
| 775 except RuntimeError: |
| 776 # if loader does not implement get_source() |
| 777 cache_key = None |
| 778 # if template is not file, use name for cache key |
| 779 if cache_key is None: |
| 780 cache_key = name |
| 781 if self.cache is not None: |
| 782 template = self.cache.get(cache_key) |
| 783 if template is not None and (not self.auto_reload or |
| 784 template.is_up_to_date): |
| 785 return template |
| 786 template = self.loader.load(self, name, globals) |
| 787 if self.cache is not None: |
| 788 self.cache[cache_key] = template |
| 789 return template |
| 790 |
| 791 @internalcode |
| 792 def get_template(self, name, parent=None, globals=None): |
| 793 """Load a template from the loader. If a loader is configured this |
| 794 method ask the loader for the template and returns a :class:`Template`. |
| 795 If the `parent` parameter is not `None`, :meth:`join_path` is called |
| 796 to get the real template name before loading. |
| 797 |
| 798 The `globals` parameter can be used to provide template wide globals. |
| 799 These variables are available in the context at render time. |
| 800 |
| 801 If the template does not exist a :exc:`TemplateNotFound` exception is |
| 802 raised. |
| 803 |
| 804 .. versionchanged:: 2.4 |
| 805 If `name` is a :class:`Template` object it is returned from the |
| 806 function unchanged. |
| 807 """ |
| 808 if isinstance(name, Template): |
| 809 return name |
| 810 if parent is not None: |
| 811 name = self.join_path(name, parent) |
| 812 return self._load_template(name, self.make_globals(globals)) |
| 813 |
| 814 @internalcode |
| 815 def select_template(self, names, parent=None, globals=None): |
| 816 """Works like :meth:`get_template` but tries a number of templates |
| 817 before it fails. If it cannot find any of the templates, it will |
| 818 raise a :exc:`TemplatesNotFound` exception. |
| 819 |
| 820 .. versionadded:: 2.3 |
| 821 |
| 822 .. versionchanged:: 2.4 |
| 823 If `names` contains a :class:`Template` object it is returned |
| 824 from the function unchanged. |
| 825 """ |
| 826 if not names: |
| 827 raise TemplatesNotFound(message=u'Tried to select from an empty list
' |
| 828 u'of templates.') |
| 829 globals = self.make_globals(globals) |
| 830 for name in names: |
| 831 if isinstance(name, Template): |
| 832 return name |
| 833 if parent is not None: |
| 834 name = self.join_path(name, parent) |
| 835 try: |
| 836 return self._load_template(name, globals) |
| 837 except TemplateNotFound: |
| 838 pass |
| 839 raise TemplatesNotFound(names) |
| 840 |
| 841 @internalcode |
| 842 def get_or_select_template(self, template_name_or_list, |
| 843 parent=None, globals=None): |
| 844 """Does a typecheck and dispatches to :meth:`select_template` |
| 845 if an iterable of template names is given, otherwise to |
| 846 :meth:`get_template`. |
| 847 |
| 848 .. versionadded:: 2.3 |
| 849 """ |
| 850 if isinstance(template_name_or_list, string_types): |
| 851 return self.get_template(template_name_or_list, parent, globals) |
| 852 elif isinstance(template_name_or_list, Template): |
| 853 return template_name_or_list |
| 854 return self.select_template(template_name_or_list, parent, globals) |
| 855 |
| 856 def from_string(self, source, globals=None, template_class=None): |
| 857 """Load a template from a string. This parses the source given and |
| 858 returns a :class:`Template` object. |
| 859 """ |
| 860 globals = self.make_globals(globals) |
| 861 cls = template_class or self.template_class |
| 862 return cls.from_code(self, self.compile(source), globals, None) |
| 863 |
| 864 def make_globals(self, d): |
| 865 """Return a dict for the globals.""" |
| 866 if not d: |
| 867 return self.globals |
| 868 return dict(self.globals, **d) |
| 869 |
| 870 |
| 871 class Template(object): |
| 872 """The central template object. This class represents a compiled template |
| 873 and is used to evaluate it. |
| 874 |
| 875 Normally the template object is generated from an :class:`Environment` but |
| 876 it also has a constructor that makes it possible to create a template |
| 877 instance directly using the constructor. It takes the same arguments as |
| 878 the environment constructor but it's not possible to specify a loader. |
| 879 |
| 880 Every template object has a few methods and members that are guaranteed |
| 881 to exist. However it's important that a template object should be |
| 882 considered immutable. Modifications on the object are not supported. |
| 883 |
| 884 Template objects created from the constructor rather than an environment |
| 885 do have an `environment` attribute that points to a temporary environment |
| 886 that is probably shared with other templates created with the constructor |
| 887 and compatible settings. |
| 888 |
| 889 >>> template = Template('Hello {{ name }}!') |
| 890 >>> template.render(name='John Doe') == u'Hello John Doe!' |
| 891 True |
| 892 >>> stream = template.stream(name='John Doe') |
| 893 >>> next(stream) == u'Hello John Doe!' |
| 894 True |
| 895 >>> next(stream) |
| 896 Traceback (most recent call last): |
| 897 ... |
| 898 StopIteration |
| 899 """ |
| 900 |
| 901 def __new__(cls, source, |
| 902 block_start_string=BLOCK_START_STRING, |
| 903 block_end_string=BLOCK_END_STRING, |
| 904 variable_start_string=VARIABLE_START_STRING, |
| 905 variable_end_string=VARIABLE_END_STRING, |
| 906 comment_start_string=COMMENT_START_STRING, |
| 907 comment_end_string=COMMENT_END_STRING, |
| 908 line_statement_prefix=LINE_STATEMENT_PREFIX, |
| 909 line_comment_prefix=LINE_COMMENT_PREFIX, |
| 910 trim_blocks=TRIM_BLOCKS, |
| 911 lstrip_blocks=LSTRIP_BLOCKS, |
| 912 newline_sequence=NEWLINE_SEQUENCE, |
| 913 keep_trailing_newline=KEEP_TRAILING_NEWLINE, |
| 914 extensions=(), |
| 915 optimized=True, |
| 916 undefined=Undefined, |
| 917 finalize=None, |
| 918 autoescape=False): |
| 919 env = get_spontaneous_environment( |
| 920 block_start_string, block_end_string, variable_start_string, |
| 921 variable_end_string, comment_start_string, comment_end_string, |
| 922 line_statement_prefix, line_comment_prefix, trim_blocks, |
| 923 lstrip_blocks, newline_sequence, keep_trailing_newline, |
| 924 frozenset(extensions), optimized, undefined, finalize, autoescape, |
| 925 None, 0, False, None) |
| 926 return env.from_string(source, template_class=cls) |
| 927 |
| 928 @classmethod |
| 929 def from_code(cls, environment, code, globals, uptodate=None): |
| 930 """Creates a template object from compiled code and the globals. This |
| 931 is used by the loaders and environment to create a template object. |
| 932 """ |
| 933 namespace = { |
| 934 'environment': environment, |
| 935 '__file__': code.co_filename |
| 936 } |
| 937 exec(code, namespace) |
| 938 rv = cls._from_namespace(environment, namespace, globals) |
| 939 rv._uptodate = uptodate |
| 940 return rv |
| 941 |
| 942 @classmethod |
| 943 def from_module_dict(cls, environment, module_dict, globals): |
| 944 """Creates a template object from a module. This is used by the |
| 945 module loader to create a template object. |
| 946 |
| 947 .. versionadded:: 2.4 |
| 948 """ |
| 949 return cls._from_namespace(environment, module_dict, globals) |
| 950 |
| 951 @classmethod |
| 952 def _from_namespace(cls, environment, namespace, globals): |
| 953 t = object.__new__(cls) |
| 954 t.environment = environment |
| 955 t.globals = globals |
| 956 t.name = namespace['name'] |
| 957 t.filename = namespace['__file__'] |
| 958 t.blocks = namespace['blocks'] |
| 959 |
| 960 # render function and module |
| 961 t.root_render_func = namespace['root'] |
| 962 t._module = None |
| 963 |
| 964 # debug and loader helpers |
| 965 t._debug_info = namespace['debug_info'] |
| 966 t._uptodate = None |
| 967 |
| 968 # store the reference |
| 969 namespace['environment'] = environment |
| 970 namespace['__jinja_template__'] = t |
| 971 |
| 972 return t |
| 973 |
| 974 def render(self, *args, **kwargs): |
| 975 """This method accepts the same arguments as the `dict` constructor: |
| 976 A dict, a dict subclass or some keyword arguments. If no arguments |
| 977 are given the context will be empty. These two calls do the same:: |
| 978 |
| 979 template.render(knights='that say nih') |
| 980 template.render({'knights': 'that say nih'}) |
| 981 |
| 982 This will return the rendered template as unicode string. |
| 983 """ |
| 984 vars = dict(*args, **kwargs) |
| 985 try: |
| 986 return concat(self.root_render_func(self.new_context(vars))) |
| 987 except Exception: |
| 988 exc_info = sys.exc_info() |
| 989 return self.environment.handle_exception(exc_info, True) |
| 990 |
| 991 def stream(self, *args, **kwargs): |
| 992 """Works exactly like :meth:`generate` but returns a |
| 993 :class:`TemplateStream`. |
| 994 """ |
| 995 return TemplateStream(self.generate(*args, **kwargs)) |
| 996 |
| 997 def generate(self, *args, **kwargs): |
| 998 """For very large templates it can be useful to not render the whole |
| 999 template at once but evaluate each statement after another and yield |
| 1000 piece for piece. This method basically does exactly that and returns |
| 1001 a generator that yields one item after another as unicode strings. |
| 1002 |
| 1003 It accepts the same arguments as :meth:`render`. |
| 1004 """ |
| 1005 vars = dict(*args, **kwargs) |
| 1006 try: |
| 1007 for event in self.root_render_func(self.new_context(vars)): |
| 1008 yield event |
| 1009 except Exception: |
| 1010 exc_info = sys.exc_info() |
| 1011 else: |
| 1012 return |
| 1013 yield self.environment.handle_exception(exc_info, True) |
| 1014 |
| 1015 def new_context(self, vars=None, shared=False, locals=None): |
| 1016 """Create a new :class:`Context` for this template. The vars |
| 1017 provided will be passed to the template. Per default the globals |
| 1018 are added to the context. If shared is set to `True` the data |
| 1019 is passed as it to the context without adding the globals. |
| 1020 |
| 1021 `locals` can be a dict of local variables for internal usage. |
| 1022 """ |
| 1023 return new_context(self.environment, self.name, self.blocks, |
| 1024 vars, shared, self.globals, locals) |
| 1025 |
| 1026 def make_module(self, vars=None, shared=False, locals=None): |
| 1027 """This method works like the :attr:`module` attribute when called |
| 1028 without arguments but it will evaluate the template on every call |
| 1029 rather than caching it. It's also possible to provide |
| 1030 a dict which is then used as context. The arguments are the same |
| 1031 as for the :meth:`new_context` method. |
| 1032 """ |
| 1033 return TemplateModule(self, self.new_context(vars, shared, locals)) |
| 1034 |
| 1035 @property |
| 1036 def module(self): |
| 1037 """The template as module. This is used for imports in the |
| 1038 template runtime but is also useful if one wants to access |
| 1039 exported template variables from the Python layer: |
| 1040 |
| 1041 >>> t = Template('{% macro foo() %}42{% endmacro %}23') |
| 1042 >>> str(t.module) |
| 1043 '23' |
| 1044 >>> t.module.foo() == u'42' |
| 1045 True |
| 1046 """ |
| 1047 if self._module is not None: |
| 1048 return self._module |
| 1049 self._module = rv = self.make_module() |
| 1050 return rv |
| 1051 |
| 1052 def get_corresponding_lineno(self, lineno): |
| 1053 """Return the source line number of a line number in the |
| 1054 generated bytecode as they are not in sync. |
| 1055 """ |
| 1056 for template_line, code_line in reversed(self.debug_info): |
| 1057 if code_line <= lineno: |
| 1058 return template_line |
| 1059 return 1 |
| 1060 |
| 1061 @property |
| 1062 def is_up_to_date(self): |
| 1063 """If this variable is `False` there is a newer version available.""" |
| 1064 if self._uptodate is None: |
| 1065 return True |
| 1066 return self._uptodate() |
| 1067 |
| 1068 @property |
| 1069 def debug_info(self): |
| 1070 """The debug info mapping.""" |
| 1071 return [tuple(imap(int, x.split('='))) for x in |
| 1072 self._debug_info.split('&')] |
| 1073 |
| 1074 def __repr__(self): |
| 1075 if self.name is None: |
| 1076 name = 'memory:%x' % id(self) |
| 1077 else: |
| 1078 name = repr(self.name) |
| 1079 return '<%s %s>' % (self.__class__.__name__, name) |
| 1080 |
| 1081 |
| 1082 @implements_to_string |
| 1083 class TemplateModule(object): |
| 1084 """Represents an imported template. All the exported names of the |
| 1085 template are available as attributes on this object. Additionally |
| 1086 converting it into an unicode- or bytestrings renders the contents. |
| 1087 """ |
| 1088 |
| 1089 def __init__(self, template, context): |
| 1090 self._body_stream = list(template.root_render_func(context)) |
| 1091 self.__dict__.update(context.get_exported()) |
| 1092 self.__name__ = template.name |
| 1093 |
| 1094 def __html__(self): |
| 1095 return Markup(concat(self._body_stream)) |
| 1096 |
| 1097 def __str__(self): |
| 1098 return concat(self._body_stream) |
| 1099 |
| 1100 def __repr__(self): |
| 1101 if self.__name__ is None: |
| 1102 name = 'memory:%x' % id(self) |
| 1103 else: |
| 1104 name = repr(self.__name__) |
| 1105 return '<%s %s>' % (self.__class__.__name__, name) |
| 1106 |
| 1107 |
| 1108 class TemplateExpression(object): |
| 1109 """The :meth:`jinja2.Environment.compile_expression` method returns an |
| 1110 instance of this object. It encapsulates the expression-like access |
| 1111 to the template with an expression it wraps. |
| 1112 """ |
| 1113 |
| 1114 def __init__(self, template, undefined_to_none): |
| 1115 self._template = template |
| 1116 self._undefined_to_none = undefined_to_none |
| 1117 |
| 1118 def __call__(self, *args, **kwargs): |
| 1119 context = self._template.new_context(dict(*args, **kwargs)) |
| 1120 consume(self._template.root_render_func(context)) |
| 1121 rv = context.vars['result'] |
| 1122 if self._undefined_to_none and isinstance(rv, Undefined): |
| 1123 rv = None |
| 1124 return rv |
| 1125 |
| 1126 |
| 1127 @implements_iterator |
| 1128 class TemplateStream(object): |
| 1129 """A template stream works pretty much like an ordinary python generator |
| 1130 but it can buffer multiple items to reduce the number of total iterations. |
| 1131 Per default the output is unbuffered which means that for every unbuffered |
| 1132 instruction in the template one unicode string is yielded. |
| 1133 |
| 1134 If buffering is enabled with a buffer size of 5, five items are combined |
| 1135 into a new unicode string. This is mainly useful if you are streaming |
| 1136 big templates to a client via WSGI which flushes after each iteration. |
| 1137 """ |
| 1138 |
| 1139 def __init__(self, gen): |
| 1140 self._gen = gen |
| 1141 self.disable_buffering() |
| 1142 |
| 1143 def dump(self, fp, encoding=None, errors='strict'): |
| 1144 """Dump the complete stream into a file or file-like object. |
| 1145 Per default unicode strings are written, if you want to encode |
| 1146 before writing specify an `encoding`. |
| 1147 |
| 1148 Example usage:: |
| 1149 |
| 1150 Template('Hello {{ name }}!').stream(name='foo').dump('hello.html') |
| 1151 """ |
| 1152 close = False |
| 1153 if isinstance(fp, string_types): |
| 1154 if encoding is None: |
| 1155 encoding = 'utf-8' |
| 1156 fp = open(fp, 'wb') |
| 1157 close = True |
| 1158 try: |
| 1159 if encoding is not None: |
| 1160 iterable = (x.encode(encoding, errors) for x in self) |
| 1161 else: |
| 1162 iterable = self |
| 1163 if hasattr(fp, 'writelines'): |
| 1164 fp.writelines(iterable) |
| 1165 else: |
| 1166 for item in iterable: |
| 1167 fp.write(item) |
| 1168 finally: |
| 1169 if close: |
| 1170 fp.close() |
| 1171 |
| 1172 def disable_buffering(self): |
| 1173 """Disable the output buffering.""" |
| 1174 self._next = get_next(self._gen) |
| 1175 self.buffered = False |
| 1176 |
| 1177 def enable_buffering(self, size=5): |
| 1178 """Enable buffering. Buffer `size` items before yielding them.""" |
| 1179 if size <= 1: |
| 1180 raise ValueError('buffer size too small') |
| 1181 |
| 1182 def generator(next): |
| 1183 buf = [] |
| 1184 c_size = 0 |
| 1185 push = buf.append |
| 1186 |
| 1187 while 1: |
| 1188 try: |
| 1189 while c_size < size: |
| 1190 c = next() |
| 1191 push(c) |
| 1192 if c: |
| 1193 c_size += 1 |
| 1194 except StopIteration: |
| 1195 if not c_size: |
| 1196 return |
| 1197 yield concat(buf) |
| 1198 del buf[:] |
| 1199 c_size = 0 |
| 1200 |
| 1201 self.buffered = True |
| 1202 self._next = get_next(generator(get_next(self._gen))) |
| 1203 |
| 1204 def __iter__(self): |
| 1205 return self |
| 1206 |
| 1207 def __next__(self): |
| 1208 return self._next() |
| 1209 |
| 1210 |
| 1211 # hook in default template class. if anyone reads this comment: ignore that |
| 1212 # it's possible to use custom templates ;-) |
| 1213 Environment.template_class = Template |
OLD | NEW |