Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: mojo/public/third_party/jinja2/environment.py

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

Powered by Google App Engine
This is Rietveld 408576698