11cb0ef41Sopenharmony_ci# -*- coding: utf-8 -*- 21cb0ef41Sopenharmony_ci""" 31cb0ef41Sopenharmony_ci jinja2.environment 41cb0ef41Sopenharmony_ci ~~~~~~~~~~~~~~~~~~ 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ci Provides a class that holds runtime and parsing time options. 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci :copyright: (c) 2017 by the Jinja Team. 91cb0ef41Sopenharmony_ci :license: BSD, see LICENSE for more details. 101cb0ef41Sopenharmony_ci""" 111cb0ef41Sopenharmony_ciimport os 121cb0ef41Sopenharmony_ciimport sys 131cb0ef41Sopenharmony_ciimport weakref 141cb0ef41Sopenharmony_cifrom functools import reduce, partial 151cb0ef41Sopenharmony_cifrom jinja2 import nodes 161cb0ef41Sopenharmony_cifrom jinja2.defaults import BLOCK_START_STRING, \ 171cb0ef41Sopenharmony_ci BLOCK_END_STRING, VARIABLE_START_STRING, VARIABLE_END_STRING, \ 181cb0ef41Sopenharmony_ci COMMENT_START_STRING, COMMENT_END_STRING, LINE_STATEMENT_PREFIX, \ 191cb0ef41Sopenharmony_ci LINE_COMMENT_PREFIX, TRIM_BLOCKS, NEWLINE_SEQUENCE, \ 201cb0ef41Sopenharmony_ci DEFAULT_FILTERS, DEFAULT_TESTS, DEFAULT_NAMESPACE, \ 211cb0ef41Sopenharmony_ci DEFAULT_POLICIES, KEEP_TRAILING_NEWLINE, LSTRIP_BLOCKS 221cb0ef41Sopenharmony_cifrom jinja2.lexer import get_lexer, TokenStream 231cb0ef41Sopenharmony_cifrom jinja2.parser import Parser 241cb0ef41Sopenharmony_cifrom jinja2.nodes import EvalContext 251cb0ef41Sopenharmony_cifrom jinja2.compiler import generate, CodeGenerator 261cb0ef41Sopenharmony_cifrom jinja2.runtime import Undefined, new_context, Context 271cb0ef41Sopenharmony_cifrom jinja2.exceptions import TemplateSyntaxError, TemplateNotFound, \ 281cb0ef41Sopenharmony_ci TemplatesNotFound, TemplateRuntimeError 291cb0ef41Sopenharmony_cifrom jinja2.utils import import_string, LRUCache, Markup, missing, \ 301cb0ef41Sopenharmony_ci concat, consume, internalcode, have_async_gen 311cb0ef41Sopenharmony_cifrom jinja2._compat import imap, ifilter, string_types, iteritems, \ 321cb0ef41Sopenharmony_ci text_type, reraise, implements_iterator, implements_to_string, \ 331cb0ef41Sopenharmony_ci encode_filename, PY2, PYPY 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci# for direct template usage we have up to ten living environments 371cb0ef41Sopenharmony_ci_spontaneous_environments = LRUCache(10) 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci# the function to create jinja traceback objects. This is dynamically 401cb0ef41Sopenharmony_ci# imported on the first exception in the exception handler. 411cb0ef41Sopenharmony_ci_make_traceback = None 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_cidef get_spontaneous_environment(*args): 451cb0ef41Sopenharmony_ci """Return a new spontaneous environment. A spontaneous environment is an 461cb0ef41Sopenharmony_ci unnamed and unaccessible (in theory) environment that is used for 471cb0ef41Sopenharmony_ci templates generated from a string and not from the file system. 481cb0ef41Sopenharmony_ci """ 491cb0ef41Sopenharmony_ci try: 501cb0ef41Sopenharmony_ci env = _spontaneous_environments.get(args) 511cb0ef41Sopenharmony_ci except TypeError: 521cb0ef41Sopenharmony_ci return Environment(*args) 531cb0ef41Sopenharmony_ci if env is not None: 541cb0ef41Sopenharmony_ci return env 551cb0ef41Sopenharmony_ci _spontaneous_environments[args] = env = Environment(*args) 561cb0ef41Sopenharmony_ci env.shared = True 571cb0ef41Sopenharmony_ci return env 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_cidef create_cache(size): 611cb0ef41Sopenharmony_ci """Return the cache class for the given size.""" 621cb0ef41Sopenharmony_ci if size == 0: 631cb0ef41Sopenharmony_ci return None 641cb0ef41Sopenharmony_ci if size < 0: 651cb0ef41Sopenharmony_ci return {} 661cb0ef41Sopenharmony_ci return LRUCache(size) 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_cidef copy_cache(cache): 701cb0ef41Sopenharmony_ci """Create an empty copy of the given cache.""" 711cb0ef41Sopenharmony_ci if cache is None: 721cb0ef41Sopenharmony_ci return None 731cb0ef41Sopenharmony_ci elif type(cache) is dict: 741cb0ef41Sopenharmony_ci return {} 751cb0ef41Sopenharmony_ci return LRUCache(cache.capacity) 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_cidef load_extensions(environment, extensions): 791cb0ef41Sopenharmony_ci """Load the extensions from the list and bind it to the environment. 801cb0ef41Sopenharmony_ci Returns a dict of instantiated environments. 811cb0ef41Sopenharmony_ci """ 821cb0ef41Sopenharmony_ci result = {} 831cb0ef41Sopenharmony_ci for extension in extensions: 841cb0ef41Sopenharmony_ci if isinstance(extension, string_types): 851cb0ef41Sopenharmony_ci extension = import_string(extension) 861cb0ef41Sopenharmony_ci result[extension.identifier] = extension(environment) 871cb0ef41Sopenharmony_ci return result 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_cidef fail_for_missing_callable(string, name): 911cb0ef41Sopenharmony_ci msg = string % name 921cb0ef41Sopenharmony_ci if isinstance(name, Undefined): 931cb0ef41Sopenharmony_ci try: 941cb0ef41Sopenharmony_ci name._fail_with_undefined_error() 951cb0ef41Sopenharmony_ci except Exception as e: 961cb0ef41Sopenharmony_ci msg = '%s (%s; did you forget to quote the callable name?)' % (msg, e) 971cb0ef41Sopenharmony_ci raise TemplateRuntimeError(msg) 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_cidef _environment_sanity_check(environment): 1011cb0ef41Sopenharmony_ci """Perform a sanity check on the environment.""" 1021cb0ef41Sopenharmony_ci assert issubclass(environment.undefined, Undefined), 'undefined must ' \ 1031cb0ef41Sopenharmony_ci 'be a subclass of undefined because filters depend on it.' 1041cb0ef41Sopenharmony_ci assert environment.block_start_string != \ 1051cb0ef41Sopenharmony_ci environment.variable_start_string != \ 1061cb0ef41Sopenharmony_ci environment.comment_start_string, 'block, variable and comment ' \ 1071cb0ef41Sopenharmony_ci 'start strings must be different' 1081cb0ef41Sopenharmony_ci assert environment.newline_sequence in ('\r', '\r\n', '\n'), \ 1091cb0ef41Sopenharmony_ci 'newline_sequence set to unknown line ending string.' 1101cb0ef41Sopenharmony_ci return environment 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ciclass Environment(object): 1141cb0ef41Sopenharmony_ci r"""The core component of Jinja is the `Environment`. It contains 1151cb0ef41Sopenharmony_ci important shared variables like configuration, filters, tests, 1161cb0ef41Sopenharmony_ci globals and others. Instances of this class may be modified if 1171cb0ef41Sopenharmony_ci they are not shared and if no template was loaded so far. 1181cb0ef41Sopenharmony_ci Modifications on environments after the first template was loaded 1191cb0ef41Sopenharmony_ci will lead to surprising effects and undefined behavior. 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ci Here are the possible initialization parameters: 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci `block_start_string` 1241cb0ef41Sopenharmony_ci The string marking the beginning of a block. Defaults to ``'{%'``. 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci `block_end_string` 1271cb0ef41Sopenharmony_ci The string marking the end of a block. Defaults to ``'%}'``. 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci `variable_start_string` 1301cb0ef41Sopenharmony_ci The string marking the beginning of a print statement. 1311cb0ef41Sopenharmony_ci Defaults to ``'{{'``. 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci `variable_end_string` 1341cb0ef41Sopenharmony_ci The string marking the end of a print statement. Defaults to 1351cb0ef41Sopenharmony_ci ``'}}'``. 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_ci `comment_start_string` 1381cb0ef41Sopenharmony_ci The string marking the beginning of a comment. Defaults to ``'{#'``. 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci `comment_end_string` 1411cb0ef41Sopenharmony_ci The string marking the end of a comment. Defaults to ``'#}'``. 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci `line_statement_prefix` 1441cb0ef41Sopenharmony_ci If given and a string, this will be used as prefix for line based 1451cb0ef41Sopenharmony_ci statements. See also :ref:`line-statements`. 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_ci `line_comment_prefix` 1481cb0ef41Sopenharmony_ci If given and a string, this will be used as prefix for line based 1491cb0ef41Sopenharmony_ci comments. See also :ref:`line-statements`. 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci .. versionadded:: 2.2 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci `trim_blocks` 1541cb0ef41Sopenharmony_ci If this is set to ``True`` the first newline after a block is 1551cb0ef41Sopenharmony_ci removed (block, not variable tag!). Defaults to `False`. 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci `lstrip_blocks` 1581cb0ef41Sopenharmony_ci If this is set to ``True`` leading spaces and tabs are stripped 1591cb0ef41Sopenharmony_ci from the start of a line to a block. Defaults to `False`. 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_ci `newline_sequence` 1621cb0ef41Sopenharmony_ci The sequence that starts a newline. Must be one of ``'\r'``, 1631cb0ef41Sopenharmony_ci ``'\n'`` or ``'\r\n'``. The default is ``'\n'`` which is a 1641cb0ef41Sopenharmony_ci useful default for Linux and OS X systems as well as web 1651cb0ef41Sopenharmony_ci applications. 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci `keep_trailing_newline` 1681cb0ef41Sopenharmony_ci Preserve the trailing newline when rendering templates. 1691cb0ef41Sopenharmony_ci The default is ``False``, which causes a single newline, 1701cb0ef41Sopenharmony_ci if present, to be stripped from the end of the template. 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci .. versionadded:: 2.7 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_ci `extensions` 1751cb0ef41Sopenharmony_ci List of Jinja extensions to use. This can either be import paths 1761cb0ef41Sopenharmony_ci as strings or extension classes. For more information have a 1771cb0ef41Sopenharmony_ci look at :ref:`the extensions documentation <jinja-extensions>`. 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ci `optimized` 1801cb0ef41Sopenharmony_ci should the optimizer be enabled? Default is ``True``. 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci `undefined` 1831cb0ef41Sopenharmony_ci :class:`Undefined` or a subclass of it that is used to represent 1841cb0ef41Sopenharmony_ci undefined values in the template. 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ci `finalize` 1871cb0ef41Sopenharmony_ci A callable that can be used to process the result of a variable 1881cb0ef41Sopenharmony_ci expression before it is output. For example one can convert 1891cb0ef41Sopenharmony_ci ``None`` implicitly into an empty string here. 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ci `autoescape` 1921cb0ef41Sopenharmony_ci If set to ``True`` the XML/HTML autoescaping feature is enabled by 1931cb0ef41Sopenharmony_ci default. For more details about autoescaping see 1941cb0ef41Sopenharmony_ci :class:`~jinja2.utils.Markup`. As of Jinja 2.4 this can also 1951cb0ef41Sopenharmony_ci be a callable that is passed the template name and has to 1961cb0ef41Sopenharmony_ci return ``True`` or ``False`` depending on autoescape should be 1971cb0ef41Sopenharmony_ci enabled by default. 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ci .. versionchanged:: 2.4 2001cb0ef41Sopenharmony_ci `autoescape` can now be a function 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci `loader` 2031cb0ef41Sopenharmony_ci The template loader for this environment. 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ci `cache_size` 2061cb0ef41Sopenharmony_ci The size of the cache. Per default this is ``400`` which means 2071cb0ef41Sopenharmony_ci that if more than 400 templates are loaded the loader will clean 2081cb0ef41Sopenharmony_ci out the least recently used template. If the cache size is set to 2091cb0ef41Sopenharmony_ci ``0`` templates are recompiled all the time, if the cache size is 2101cb0ef41Sopenharmony_ci ``-1`` the cache will not be cleaned. 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_ci .. versionchanged:: 2.8 2131cb0ef41Sopenharmony_ci The cache size was increased to 400 from a low 50. 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_ci `auto_reload` 2161cb0ef41Sopenharmony_ci Some loaders load templates from locations where the template 2171cb0ef41Sopenharmony_ci sources may change (ie: file system or database). If 2181cb0ef41Sopenharmony_ci ``auto_reload`` is set to ``True`` (default) every time a template is 2191cb0ef41Sopenharmony_ci requested the loader checks if the source changed and if yes, it 2201cb0ef41Sopenharmony_ci will reload the template. For higher performance it's possible to 2211cb0ef41Sopenharmony_ci disable that. 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ci `bytecode_cache` 2241cb0ef41Sopenharmony_ci If set to a bytecode cache object, this object will provide a 2251cb0ef41Sopenharmony_ci cache for the internal Jinja bytecode so that templates don't 2261cb0ef41Sopenharmony_ci have to be parsed if they were not changed. 2271cb0ef41Sopenharmony_ci 2281cb0ef41Sopenharmony_ci See :ref:`bytecode-cache` for more information. 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ci `enable_async` 2311cb0ef41Sopenharmony_ci If set to true this enables async template execution which allows 2321cb0ef41Sopenharmony_ci you to take advantage of newer Python features. This requires 2331cb0ef41Sopenharmony_ci Python 3.6 or later. 2341cb0ef41Sopenharmony_ci """ 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ci #: if this environment is sandboxed. Modifying this variable won't make 2371cb0ef41Sopenharmony_ci #: the environment sandboxed though. For a real sandboxed environment 2381cb0ef41Sopenharmony_ci #: have a look at jinja2.sandbox. This flag alone controls the code 2391cb0ef41Sopenharmony_ci #: generation by the compiler. 2401cb0ef41Sopenharmony_ci sandboxed = False 2411cb0ef41Sopenharmony_ci 2421cb0ef41Sopenharmony_ci #: True if the environment is just an overlay 2431cb0ef41Sopenharmony_ci overlayed = False 2441cb0ef41Sopenharmony_ci 2451cb0ef41Sopenharmony_ci #: the environment this environment is linked to if it is an overlay 2461cb0ef41Sopenharmony_ci linked_to = None 2471cb0ef41Sopenharmony_ci 2481cb0ef41Sopenharmony_ci #: shared environments have this set to `True`. A shared environment 2491cb0ef41Sopenharmony_ci #: must not be modified 2501cb0ef41Sopenharmony_ci shared = False 2511cb0ef41Sopenharmony_ci 2521cb0ef41Sopenharmony_ci #: these are currently EXPERIMENTAL undocumented features. 2531cb0ef41Sopenharmony_ci exception_handler = None 2541cb0ef41Sopenharmony_ci exception_formatter = None 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci #: the class that is used for code generation. See 2571cb0ef41Sopenharmony_ci #: :class:`~jinja2.compiler.CodeGenerator` for more information. 2581cb0ef41Sopenharmony_ci code_generator_class = CodeGenerator 2591cb0ef41Sopenharmony_ci 2601cb0ef41Sopenharmony_ci #: the context class thatis used for templates. See 2611cb0ef41Sopenharmony_ci #: :class:`~jinja2.runtime.Context` for more information. 2621cb0ef41Sopenharmony_ci context_class = Context 2631cb0ef41Sopenharmony_ci 2641cb0ef41Sopenharmony_ci def __init__(self, 2651cb0ef41Sopenharmony_ci block_start_string=BLOCK_START_STRING, 2661cb0ef41Sopenharmony_ci block_end_string=BLOCK_END_STRING, 2671cb0ef41Sopenharmony_ci variable_start_string=VARIABLE_START_STRING, 2681cb0ef41Sopenharmony_ci variable_end_string=VARIABLE_END_STRING, 2691cb0ef41Sopenharmony_ci comment_start_string=COMMENT_START_STRING, 2701cb0ef41Sopenharmony_ci comment_end_string=COMMENT_END_STRING, 2711cb0ef41Sopenharmony_ci line_statement_prefix=LINE_STATEMENT_PREFIX, 2721cb0ef41Sopenharmony_ci line_comment_prefix=LINE_COMMENT_PREFIX, 2731cb0ef41Sopenharmony_ci trim_blocks=TRIM_BLOCKS, 2741cb0ef41Sopenharmony_ci lstrip_blocks=LSTRIP_BLOCKS, 2751cb0ef41Sopenharmony_ci newline_sequence=NEWLINE_SEQUENCE, 2761cb0ef41Sopenharmony_ci keep_trailing_newline=KEEP_TRAILING_NEWLINE, 2771cb0ef41Sopenharmony_ci extensions=(), 2781cb0ef41Sopenharmony_ci optimized=True, 2791cb0ef41Sopenharmony_ci undefined=Undefined, 2801cb0ef41Sopenharmony_ci finalize=None, 2811cb0ef41Sopenharmony_ci autoescape=False, 2821cb0ef41Sopenharmony_ci loader=None, 2831cb0ef41Sopenharmony_ci cache_size=400, 2841cb0ef41Sopenharmony_ci auto_reload=True, 2851cb0ef41Sopenharmony_ci bytecode_cache=None, 2861cb0ef41Sopenharmony_ci enable_async=False): 2871cb0ef41Sopenharmony_ci # !!Important notice!! 2881cb0ef41Sopenharmony_ci # The constructor accepts quite a few arguments that should be 2891cb0ef41Sopenharmony_ci # passed by keyword rather than position. However it's important to 2901cb0ef41Sopenharmony_ci # not change the order of arguments because it's used at least 2911cb0ef41Sopenharmony_ci # internally in those cases: 2921cb0ef41Sopenharmony_ci # - spontaneous environments (i18n extension and Template) 2931cb0ef41Sopenharmony_ci # - unittests 2941cb0ef41Sopenharmony_ci # If parameter changes are required only add parameters at the end 2951cb0ef41Sopenharmony_ci # and don't change the arguments (or the defaults!) of the arguments 2961cb0ef41Sopenharmony_ci # existing already. 2971cb0ef41Sopenharmony_ci 2981cb0ef41Sopenharmony_ci # lexer / parser information 2991cb0ef41Sopenharmony_ci self.block_start_string = block_start_string 3001cb0ef41Sopenharmony_ci self.block_end_string = block_end_string 3011cb0ef41Sopenharmony_ci self.variable_start_string = variable_start_string 3021cb0ef41Sopenharmony_ci self.variable_end_string = variable_end_string 3031cb0ef41Sopenharmony_ci self.comment_start_string = comment_start_string 3041cb0ef41Sopenharmony_ci self.comment_end_string = comment_end_string 3051cb0ef41Sopenharmony_ci self.line_statement_prefix = line_statement_prefix 3061cb0ef41Sopenharmony_ci self.line_comment_prefix = line_comment_prefix 3071cb0ef41Sopenharmony_ci self.trim_blocks = trim_blocks 3081cb0ef41Sopenharmony_ci self.lstrip_blocks = lstrip_blocks 3091cb0ef41Sopenharmony_ci self.newline_sequence = newline_sequence 3101cb0ef41Sopenharmony_ci self.keep_trailing_newline = keep_trailing_newline 3111cb0ef41Sopenharmony_ci 3121cb0ef41Sopenharmony_ci # runtime information 3131cb0ef41Sopenharmony_ci self.undefined = undefined 3141cb0ef41Sopenharmony_ci self.optimized = optimized 3151cb0ef41Sopenharmony_ci self.finalize = finalize 3161cb0ef41Sopenharmony_ci self.autoescape = autoescape 3171cb0ef41Sopenharmony_ci 3181cb0ef41Sopenharmony_ci # defaults 3191cb0ef41Sopenharmony_ci self.filters = DEFAULT_FILTERS.copy() 3201cb0ef41Sopenharmony_ci self.tests = DEFAULT_TESTS.copy() 3211cb0ef41Sopenharmony_ci self.globals = DEFAULT_NAMESPACE.copy() 3221cb0ef41Sopenharmony_ci 3231cb0ef41Sopenharmony_ci # set the loader provided 3241cb0ef41Sopenharmony_ci self.loader = loader 3251cb0ef41Sopenharmony_ci self.cache = create_cache(cache_size) 3261cb0ef41Sopenharmony_ci self.bytecode_cache = bytecode_cache 3271cb0ef41Sopenharmony_ci self.auto_reload = auto_reload 3281cb0ef41Sopenharmony_ci 3291cb0ef41Sopenharmony_ci # configurable policies 3301cb0ef41Sopenharmony_ci self.policies = DEFAULT_POLICIES.copy() 3311cb0ef41Sopenharmony_ci 3321cb0ef41Sopenharmony_ci # load extensions 3331cb0ef41Sopenharmony_ci self.extensions = load_extensions(self, extensions) 3341cb0ef41Sopenharmony_ci 3351cb0ef41Sopenharmony_ci self.enable_async = enable_async 3361cb0ef41Sopenharmony_ci self.is_async = self.enable_async and have_async_gen 3371cb0ef41Sopenharmony_ci 3381cb0ef41Sopenharmony_ci _environment_sanity_check(self) 3391cb0ef41Sopenharmony_ci 3401cb0ef41Sopenharmony_ci def add_extension(self, extension): 3411cb0ef41Sopenharmony_ci """Adds an extension after the environment was created. 3421cb0ef41Sopenharmony_ci 3431cb0ef41Sopenharmony_ci .. versionadded:: 2.5 3441cb0ef41Sopenharmony_ci """ 3451cb0ef41Sopenharmony_ci self.extensions.update(load_extensions(self, [extension])) 3461cb0ef41Sopenharmony_ci 3471cb0ef41Sopenharmony_ci def extend(self, **attributes): 3481cb0ef41Sopenharmony_ci """Add the items to the instance of the environment if they do not exist 3491cb0ef41Sopenharmony_ci yet. This is used by :ref:`extensions <writing-extensions>` to register 3501cb0ef41Sopenharmony_ci callbacks and configuration values without breaking inheritance. 3511cb0ef41Sopenharmony_ci """ 3521cb0ef41Sopenharmony_ci for key, value in iteritems(attributes): 3531cb0ef41Sopenharmony_ci if not hasattr(self, key): 3541cb0ef41Sopenharmony_ci setattr(self, key, value) 3551cb0ef41Sopenharmony_ci 3561cb0ef41Sopenharmony_ci def overlay(self, block_start_string=missing, block_end_string=missing, 3571cb0ef41Sopenharmony_ci variable_start_string=missing, variable_end_string=missing, 3581cb0ef41Sopenharmony_ci comment_start_string=missing, comment_end_string=missing, 3591cb0ef41Sopenharmony_ci line_statement_prefix=missing, line_comment_prefix=missing, 3601cb0ef41Sopenharmony_ci trim_blocks=missing, lstrip_blocks=missing, 3611cb0ef41Sopenharmony_ci extensions=missing, optimized=missing, 3621cb0ef41Sopenharmony_ci undefined=missing, finalize=missing, autoescape=missing, 3631cb0ef41Sopenharmony_ci loader=missing, cache_size=missing, auto_reload=missing, 3641cb0ef41Sopenharmony_ci bytecode_cache=missing): 3651cb0ef41Sopenharmony_ci """Create a new overlay environment that shares all the data with the 3661cb0ef41Sopenharmony_ci current environment except for cache and the overridden attributes. 3671cb0ef41Sopenharmony_ci Extensions cannot be removed for an overlayed environment. An overlayed 3681cb0ef41Sopenharmony_ci environment automatically gets all the extensions of the environment it 3691cb0ef41Sopenharmony_ci is linked to plus optional extra extensions. 3701cb0ef41Sopenharmony_ci 3711cb0ef41Sopenharmony_ci Creating overlays should happen after the initial environment was set 3721cb0ef41Sopenharmony_ci up completely. Not all attributes are truly linked, some are just 3731cb0ef41Sopenharmony_ci copied over so modifications on the original environment may not shine 3741cb0ef41Sopenharmony_ci through. 3751cb0ef41Sopenharmony_ci """ 3761cb0ef41Sopenharmony_ci args = dict(locals()) 3771cb0ef41Sopenharmony_ci del args['self'], args['cache_size'], args['extensions'] 3781cb0ef41Sopenharmony_ci 3791cb0ef41Sopenharmony_ci rv = object.__new__(self.__class__) 3801cb0ef41Sopenharmony_ci rv.__dict__.update(self.__dict__) 3811cb0ef41Sopenharmony_ci rv.overlayed = True 3821cb0ef41Sopenharmony_ci rv.linked_to = self 3831cb0ef41Sopenharmony_ci 3841cb0ef41Sopenharmony_ci for key, value in iteritems(args): 3851cb0ef41Sopenharmony_ci if value is not missing: 3861cb0ef41Sopenharmony_ci setattr(rv, key, value) 3871cb0ef41Sopenharmony_ci 3881cb0ef41Sopenharmony_ci if cache_size is not missing: 3891cb0ef41Sopenharmony_ci rv.cache = create_cache(cache_size) 3901cb0ef41Sopenharmony_ci else: 3911cb0ef41Sopenharmony_ci rv.cache = copy_cache(self.cache) 3921cb0ef41Sopenharmony_ci 3931cb0ef41Sopenharmony_ci rv.extensions = {} 3941cb0ef41Sopenharmony_ci for key, value in iteritems(self.extensions): 3951cb0ef41Sopenharmony_ci rv.extensions[key] = value.bind(rv) 3961cb0ef41Sopenharmony_ci if extensions is not missing: 3971cb0ef41Sopenharmony_ci rv.extensions.update(load_extensions(rv, extensions)) 3981cb0ef41Sopenharmony_ci 3991cb0ef41Sopenharmony_ci return _environment_sanity_check(rv) 4001cb0ef41Sopenharmony_ci 4011cb0ef41Sopenharmony_ci lexer = property(get_lexer, doc="The lexer for this environment.") 4021cb0ef41Sopenharmony_ci 4031cb0ef41Sopenharmony_ci def iter_extensions(self): 4041cb0ef41Sopenharmony_ci """Iterates over the extensions by priority.""" 4051cb0ef41Sopenharmony_ci return iter(sorted(self.extensions.values(), 4061cb0ef41Sopenharmony_ci key=lambda x: x.priority)) 4071cb0ef41Sopenharmony_ci 4081cb0ef41Sopenharmony_ci def getitem(self, obj, argument): 4091cb0ef41Sopenharmony_ci """Get an item or attribute of an object but prefer the item.""" 4101cb0ef41Sopenharmony_ci try: 4111cb0ef41Sopenharmony_ci return obj[argument] 4121cb0ef41Sopenharmony_ci except (AttributeError, TypeError, LookupError): 4131cb0ef41Sopenharmony_ci if isinstance(argument, string_types): 4141cb0ef41Sopenharmony_ci try: 4151cb0ef41Sopenharmony_ci attr = str(argument) 4161cb0ef41Sopenharmony_ci except Exception: 4171cb0ef41Sopenharmony_ci pass 4181cb0ef41Sopenharmony_ci else: 4191cb0ef41Sopenharmony_ci try: 4201cb0ef41Sopenharmony_ci return getattr(obj, attr) 4211cb0ef41Sopenharmony_ci except AttributeError: 4221cb0ef41Sopenharmony_ci pass 4231cb0ef41Sopenharmony_ci return self.undefined(obj=obj, name=argument) 4241cb0ef41Sopenharmony_ci 4251cb0ef41Sopenharmony_ci def getattr(self, obj, attribute): 4261cb0ef41Sopenharmony_ci """Get an item or attribute of an object but prefer the attribute. 4271cb0ef41Sopenharmony_ci Unlike :meth:`getitem` the attribute *must* be a bytestring. 4281cb0ef41Sopenharmony_ci """ 4291cb0ef41Sopenharmony_ci try: 4301cb0ef41Sopenharmony_ci return getattr(obj, attribute) 4311cb0ef41Sopenharmony_ci except AttributeError: 4321cb0ef41Sopenharmony_ci pass 4331cb0ef41Sopenharmony_ci try: 4341cb0ef41Sopenharmony_ci return obj[attribute] 4351cb0ef41Sopenharmony_ci except (TypeError, LookupError, AttributeError): 4361cb0ef41Sopenharmony_ci return self.undefined(obj=obj, name=attribute) 4371cb0ef41Sopenharmony_ci 4381cb0ef41Sopenharmony_ci def call_filter(self, name, value, args=None, kwargs=None, 4391cb0ef41Sopenharmony_ci context=None, eval_ctx=None): 4401cb0ef41Sopenharmony_ci """Invokes a filter on a value the same way the compiler does it. 4411cb0ef41Sopenharmony_ci 4421cb0ef41Sopenharmony_ci Note that on Python 3 this might return a coroutine in case the 4431cb0ef41Sopenharmony_ci filter is running from an environment in async mode and the filter 4441cb0ef41Sopenharmony_ci supports async execution. It's your responsibility to await this 4451cb0ef41Sopenharmony_ci if needed. 4461cb0ef41Sopenharmony_ci 4471cb0ef41Sopenharmony_ci .. versionadded:: 2.7 4481cb0ef41Sopenharmony_ci """ 4491cb0ef41Sopenharmony_ci func = self.filters.get(name) 4501cb0ef41Sopenharmony_ci if func is None: 4511cb0ef41Sopenharmony_ci fail_for_missing_callable('no filter named %r', name) 4521cb0ef41Sopenharmony_ci args = [value] + list(args or ()) 4531cb0ef41Sopenharmony_ci if getattr(func, 'contextfilter', False): 4541cb0ef41Sopenharmony_ci if context is None: 4551cb0ef41Sopenharmony_ci raise TemplateRuntimeError('Attempted to invoke context ' 4561cb0ef41Sopenharmony_ci 'filter without context') 4571cb0ef41Sopenharmony_ci args.insert(0, context) 4581cb0ef41Sopenharmony_ci elif getattr(func, 'evalcontextfilter', False): 4591cb0ef41Sopenharmony_ci if eval_ctx is None: 4601cb0ef41Sopenharmony_ci if context is not None: 4611cb0ef41Sopenharmony_ci eval_ctx = context.eval_ctx 4621cb0ef41Sopenharmony_ci else: 4631cb0ef41Sopenharmony_ci eval_ctx = EvalContext(self) 4641cb0ef41Sopenharmony_ci args.insert(0, eval_ctx) 4651cb0ef41Sopenharmony_ci elif getattr(func, 'environmentfilter', False): 4661cb0ef41Sopenharmony_ci args.insert(0, self) 4671cb0ef41Sopenharmony_ci return func(*args, **(kwargs or {})) 4681cb0ef41Sopenharmony_ci 4691cb0ef41Sopenharmony_ci def call_test(self, name, value, args=None, kwargs=None): 4701cb0ef41Sopenharmony_ci """Invokes a test on a value the same way the compiler does it. 4711cb0ef41Sopenharmony_ci 4721cb0ef41Sopenharmony_ci .. versionadded:: 2.7 4731cb0ef41Sopenharmony_ci """ 4741cb0ef41Sopenharmony_ci func = self.tests.get(name) 4751cb0ef41Sopenharmony_ci if func is None: 4761cb0ef41Sopenharmony_ci fail_for_missing_callable('no test named %r', name) 4771cb0ef41Sopenharmony_ci return func(value, *(args or ()), **(kwargs or {})) 4781cb0ef41Sopenharmony_ci 4791cb0ef41Sopenharmony_ci @internalcode 4801cb0ef41Sopenharmony_ci def parse(self, source, name=None, filename=None): 4811cb0ef41Sopenharmony_ci """Parse the sourcecode and return the abstract syntax tree. This 4821cb0ef41Sopenharmony_ci tree of nodes is used by the compiler to convert the template into 4831cb0ef41Sopenharmony_ci executable source- or bytecode. This is useful for debugging or to 4841cb0ef41Sopenharmony_ci extract information from templates. 4851cb0ef41Sopenharmony_ci 4861cb0ef41Sopenharmony_ci If you are :ref:`developing Jinja2 extensions <writing-extensions>` 4871cb0ef41Sopenharmony_ci this gives you a good overview of the node tree generated. 4881cb0ef41Sopenharmony_ci """ 4891cb0ef41Sopenharmony_ci try: 4901cb0ef41Sopenharmony_ci return self._parse(source, name, filename) 4911cb0ef41Sopenharmony_ci except TemplateSyntaxError: 4921cb0ef41Sopenharmony_ci exc_info = sys.exc_info() 4931cb0ef41Sopenharmony_ci self.handle_exception(exc_info, source_hint=source) 4941cb0ef41Sopenharmony_ci 4951cb0ef41Sopenharmony_ci def _parse(self, source, name, filename): 4961cb0ef41Sopenharmony_ci """Internal parsing function used by `parse` and `compile`.""" 4971cb0ef41Sopenharmony_ci return Parser(self, source, name, encode_filename(filename)).parse() 4981cb0ef41Sopenharmony_ci 4991cb0ef41Sopenharmony_ci def lex(self, source, name=None, filename=None): 5001cb0ef41Sopenharmony_ci """Lex the given sourcecode and return a generator that yields 5011cb0ef41Sopenharmony_ci tokens as tuples in the form ``(lineno, token_type, value)``. 5021cb0ef41Sopenharmony_ci This can be useful for :ref:`extension development <writing-extensions>` 5031cb0ef41Sopenharmony_ci and debugging templates. 5041cb0ef41Sopenharmony_ci 5051cb0ef41Sopenharmony_ci This does not perform preprocessing. If you want the preprocessing 5061cb0ef41Sopenharmony_ci of the extensions to be applied you have to filter source through 5071cb0ef41Sopenharmony_ci the :meth:`preprocess` method. 5081cb0ef41Sopenharmony_ci """ 5091cb0ef41Sopenharmony_ci source = text_type(source) 5101cb0ef41Sopenharmony_ci try: 5111cb0ef41Sopenharmony_ci return self.lexer.tokeniter(source, name, filename) 5121cb0ef41Sopenharmony_ci except TemplateSyntaxError: 5131cb0ef41Sopenharmony_ci exc_info = sys.exc_info() 5141cb0ef41Sopenharmony_ci self.handle_exception(exc_info, source_hint=source) 5151cb0ef41Sopenharmony_ci 5161cb0ef41Sopenharmony_ci def preprocess(self, source, name=None, filename=None): 5171cb0ef41Sopenharmony_ci """Preprocesses the source with all extensions. This is automatically 5181cb0ef41Sopenharmony_ci called for all parsing and compiling methods but *not* for :meth:`lex` 5191cb0ef41Sopenharmony_ci because there you usually only want the actual source tokenized. 5201cb0ef41Sopenharmony_ci """ 5211cb0ef41Sopenharmony_ci return reduce(lambda s, e: e.preprocess(s, name, filename), 5221cb0ef41Sopenharmony_ci self.iter_extensions(), text_type(source)) 5231cb0ef41Sopenharmony_ci 5241cb0ef41Sopenharmony_ci def _tokenize(self, source, name, filename=None, state=None): 5251cb0ef41Sopenharmony_ci """Called by the parser to do the preprocessing and filtering 5261cb0ef41Sopenharmony_ci for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`. 5271cb0ef41Sopenharmony_ci """ 5281cb0ef41Sopenharmony_ci source = self.preprocess(source, name, filename) 5291cb0ef41Sopenharmony_ci stream = self.lexer.tokenize(source, name, filename, state) 5301cb0ef41Sopenharmony_ci for ext in self.iter_extensions(): 5311cb0ef41Sopenharmony_ci stream = ext.filter_stream(stream) 5321cb0ef41Sopenharmony_ci if not isinstance(stream, TokenStream): 5331cb0ef41Sopenharmony_ci stream = TokenStream(stream, name, filename) 5341cb0ef41Sopenharmony_ci return stream 5351cb0ef41Sopenharmony_ci 5361cb0ef41Sopenharmony_ci def _generate(self, source, name, filename, defer_init=False): 5371cb0ef41Sopenharmony_ci """Internal hook that can be overridden to hook a different generate 5381cb0ef41Sopenharmony_ci method in. 5391cb0ef41Sopenharmony_ci 5401cb0ef41Sopenharmony_ci .. versionadded:: 2.5 5411cb0ef41Sopenharmony_ci """ 5421cb0ef41Sopenharmony_ci return generate(source, self, name, filename, defer_init=defer_init, 5431cb0ef41Sopenharmony_ci optimized=self.optimized) 5441cb0ef41Sopenharmony_ci 5451cb0ef41Sopenharmony_ci def _compile(self, source, filename): 5461cb0ef41Sopenharmony_ci """Internal hook that can be overridden to hook a different compile 5471cb0ef41Sopenharmony_ci method in. 5481cb0ef41Sopenharmony_ci 5491cb0ef41Sopenharmony_ci .. versionadded:: 2.5 5501cb0ef41Sopenharmony_ci """ 5511cb0ef41Sopenharmony_ci return compile(source, filename, 'exec') 5521cb0ef41Sopenharmony_ci 5531cb0ef41Sopenharmony_ci @internalcode 5541cb0ef41Sopenharmony_ci def compile(self, source, name=None, filename=None, raw=False, 5551cb0ef41Sopenharmony_ci defer_init=False): 5561cb0ef41Sopenharmony_ci """Compile a node or template source code. The `name` parameter is 5571cb0ef41Sopenharmony_ci the load name of the template after it was joined using 5581cb0ef41Sopenharmony_ci :meth:`join_path` if necessary, not the filename on the file system. 5591cb0ef41Sopenharmony_ci the `filename` parameter is the estimated filename of the template on 5601cb0ef41Sopenharmony_ci the file system. If the template came from a database or memory this 5611cb0ef41Sopenharmony_ci can be omitted. 5621cb0ef41Sopenharmony_ci 5631cb0ef41Sopenharmony_ci The return value of this method is a python code object. If the `raw` 5641cb0ef41Sopenharmony_ci parameter is `True` the return value will be a string with python 5651cb0ef41Sopenharmony_ci code equivalent to the bytecode returned otherwise. This method is 5661cb0ef41Sopenharmony_ci mainly used internally. 5671cb0ef41Sopenharmony_ci 5681cb0ef41Sopenharmony_ci `defer_init` is use internally to aid the module code generator. This 5691cb0ef41Sopenharmony_ci causes the generated code to be able to import without the global 5701cb0ef41Sopenharmony_ci environment variable to be set. 5711cb0ef41Sopenharmony_ci 5721cb0ef41Sopenharmony_ci .. versionadded:: 2.4 5731cb0ef41Sopenharmony_ci `defer_init` parameter added. 5741cb0ef41Sopenharmony_ci """ 5751cb0ef41Sopenharmony_ci source_hint = None 5761cb0ef41Sopenharmony_ci try: 5771cb0ef41Sopenharmony_ci if isinstance(source, string_types): 5781cb0ef41Sopenharmony_ci source_hint = source 5791cb0ef41Sopenharmony_ci source = self._parse(source, name, filename) 5801cb0ef41Sopenharmony_ci source = self._generate(source, name, filename, 5811cb0ef41Sopenharmony_ci defer_init=defer_init) 5821cb0ef41Sopenharmony_ci if raw: 5831cb0ef41Sopenharmony_ci return source 5841cb0ef41Sopenharmony_ci if filename is None: 5851cb0ef41Sopenharmony_ci filename = '<template>' 5861cb0ef41Sopenharmony_ci else: 5871cb0ef41Sopenharmony_ci filename = encode_filename(filename) 5881cb0ef41Sopenharmony_ci return self._compile(source, filename) 5891cb0ef41Sopenharmony_ci except TemplateSyntaxError: 5901cb0ef41Sopenharmony_ci exc_info = sys.exc_info() 5911cb0ef41Sopenharmony_ci self.handle_exception(exc_info, source_hint=source_hint) 5921cb0ef41Sopenharmony_ci 5931cb0ef41Sopenharmony_ci def compile_expression(self, source, undefined_to_none=True): 5941cb0ef41Sopenharmony_ci """A handy helper method that returns a callable that accepts keyword 5951cb0ef41Sopenharmony_ci arguments that appear as variables in the expression. If called it 5961cb0ef41Sopenharmony_ci returns the result of the expression. 5971cb0ef41Sopenharmony_ci 5981cb0ef41Sopenharmony_ci This is useful if applications want to use the same rules as Jinja 5991cb0ef41Sopenharmony_ci in template "configuration files" or similar situations. 6001cb0ef41Sopenharmony_ci 6011cb0ef41Sopenharmony_ci Example usage: 6021cb0ef41Sopenharmony_ci 6031cb0ef41Sopenharmony_ci >>> env = Environment() 6041cb0ef41Sopenharmony_ci >>> expr = env.compile_expression('foo == 42') 6051cb0ef41Sopenharmony_ci >>> expr(foo=23) 6061cb0ef41Sopenharmony_ci False 6071cb0ef41Sopenharmony_ci >>> expr(foo=42) 6081cb0ef41Sopenharmony_ci True 6091cb0ef41Sopenharmony_ci 6101cb0ef41Sopenharmony_ci Per default the return value is converted to `None` if the 6111cb0ef41Sopenharmony_ci expression returns an undefined value. This can be changed 6121cb0ef41Sopenharmony_ci by setting `undefined_to_none` to `False`. 6131cb0ef41Sopenharmony_ci 6141cb0ef41Sopenharmony_ci >>> env.compile_expression('var')() is None 6151cb0ef41Sopenharmony_ci True 6161cb0ef41Sopenharmony_ci >>> env.compile_expression('var', undefined_to_none=False)() 6171cb0ef41Sopenharmony_ci Undefined 6181cb0ef41Sopenharmony_ci 6191cb0ef41Sopenharmony_ci .. versionadded:: 2.1 6201cb0ef41Sopenharmony_ci """ 6211cb0ef41Sopenharmony_ci parser = Parser(self, source, state='variable') 6221cb0ef41Sopenharmony_ci exc_info = None 6231cb0ef41Sopenharmony_ci try: 6241cb0ef41Sopenharmony_ci expr = parser.parse_expression() 6251cb0ef41Sopenharmony_ci if not parser.stream.eos: 6261cb0ef41Sopenharmony_ci raise TemplateSyntaxError('chunk after expression', 6271cb0ef41Sopenharmony_ci parser.stream.current.lineno, 6281cb0ef41Sopenharmony_ci None, None) 6291cb0ef41Sopenharmony_ci expr.set_environment(self) 6301cb0ef41Sopenharmony_ci except TemplateSyntaxError: 6311cb0ef41Sopenharmony_ci exc_info = sys.exc_info() 6321cb0ef41Sopenharmony_ci if exc_info is not None: 6331cb0ef41Sopenharmony_ci self.handle_exception(exc_info, source_hint=source) 6341cb0ef41Sopenharmony_ci body = [nodes.Assign(nodes.Name('result', 'store'), expr, lineno=1)] 6351cb0ef41Sopenharmony_ci template = self.from_string(nodes.Template(body, lineno=1)) 6361cb0ef41Sopenharmony_ci return TemplateExpression(template, undefined_to_none) 6371cb0ef41Sopenharmony_ci 6381cb0ef41Sopenharmony_ci def compile_templates(self, target, extensions=None, filter_func=None, 6391cb0ef41Sopenharmony_ci zip='deflated', log_function=None, 6401cb0ef41Sopenharmony_ci ignore_errors=True, py_compile=False): 6411cb0ef41Sopenharmony_ci """Finds all the templates the loader can find, compiles them 6421cb0ef41Sopenharmony_ci and stores them in `target`. If `zip` is `None`, instead of in a 6431cb0ef41Sopenharmony_ci zipfile, the templates will be stored in a directory. 6441cb0ef41Sopenharmony_ci By default a deflate zip algorithm is used. To switch to 6451cb0ef41Sopenharmony_ci the stored algorithm, `zip` can be set to ``'stored'``. 6461cb0ef41Sopenharmony_ci 6471cb0ef41Sopenharmony_ci `extensions` and `filter_func` are passed to :meth:`list_templates`. 6481cb0ef41Sopenharmony_ci Each template returned will be compiled to the target folder or 6491cb0ef41Sopenharmony_ci zipfile. 6501cb0ef41Sopenharmony_ci 6511cb0ef41Sopenharmony_ci By default template compilation errors are ignored. In case a 6521cb0ef41Sopenharmony_ci log function is provided, errors are logged. If you want template 6531cb0ef41Sopenharmony_ci syntax errors to abort the compilation you can set `ignore_errors` 6541cb0ef41Sopenharmony_ci to `False` and you will get an exception on syntax errors. 6551cb0ef41Sopenharmony_ci 6561cb0ef41Sopenharmony_ci If `py_compile` is set to `True` .pyc files will be written to the 6571cb0ef41Sopenharmony_ci target instead of standard .py files. This flag does not do anything 6581cb0ef41Sopenharmony_ci on pypy and Python 3 where pyc files are not picked up by itself and 6591cb0ef41Sopenharmony_ci don't give much benefit. 6601cb0ef41Sopenharmony_ci 6611cb0ef41Sopenharmony_ci .. versionadded:: 2.4 6621cb0ef41Sopenharmony_ci """ 6631cb0ef41Sopenharmony_ci from jinja2.loaders import ModuleLoader 6641cb0ef41Sopenharmony_ci 6651cb0ef41Sopenharmony_ci if log_function is None: 6661cb0ef41Sopenharmony_ci log_function = lambda x: None 6671cb0ef41Sopenharmony_ci 6681cb0ef41Sopenharmony_ci if py_compile: 6691cb0ef41Sopenharmony_ci if not PY2 or PYPY: 6701cb0ef41Sopenharmony_ci from warnings import warn 6711cb0ef41Sopenharmony_ci warn(Warning('py_compile has no effect on pypy or Python 3')) 6721cb0ef41Sopenharmony_ci py_compile = False 6731cb0ef41Sopenharmony_ci else: 6741cb0ef41Sopenharmony_ci import imp 6751cb0ef41Sopenharmony_ci import marshal 6761cb0ef41Sopenharmony_ci py_header = imp.get_magic() + \ 6771cb0ef41Sopenharmony_ci u'\xff\xff\xff\xff'.encode('iso-8859-15') 6781cb0ef41Sopenharmony_ci 6791cb0ef41Sopenharmony_ci # Python 3.3 added a source filesize to the header 6801cb0ef41Sopenharmony_ci if sys.version_info >= (3, 3): 6811cb0ef41Sopenharmony_ci py_header += u'\x00\x00\x00\x00'.encode('iso-8859-15') 6821cb0ef41Sopenharmony_ci 6831cb0ef41Sopenharmony_ci def write_file(filename, data, mode): 6841cb0ef41Sopenharmony_ci if zip: 6851cb0ef41Sopenharmony_ci info = ZipInfo(filename) 6861cb0ef41Sopenharmony_ci info.external_attr = 0o755 << 16 6871cb0ef41Sopenharmony_ci zip_file.writestr(info, data) 6881cb0ef41Sopenharmony_ci else: 6891cb0ef41Sopenharmony_ci f = open(os.path.join(target, filename), mode) 6901cb0ef41Sopenharmony_ci try: 6911cb0ef41Sopenharmony_ci f.write(data) 6921cb0ef41Sopenharmony_ci finally: 6931cb0ef41Sopenharmony_ci f.close() 6941cb0ef41Sopenharmony_ci 6951cb0ef41Sopenharmony_ci if zip is not None: 6961cb0ef41Sopenharmony_ci from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED, ZIP_STORED 6971cb0ef41Sopenharmony_ci zip_file = ZipFile(target, 'w', dict(deflated=ZIP_DEFLATED, 6981cb0ef41Sopenharmony_ci stored=ZIP_STORED)[zip]) 6991cb0ef41Sopenharmony_ci log_function('Compiling into Zip archive "%s"' % target) 7001cb0ef41Sopenharmony_ci else: 7011cb0ef41Sopenharmony_ci if not os.path.isdir(target): 7021cb0ef41Sopenharmony_ci os.makedirs(target) 7031cb0ef41Sopenharmony_ci log_function('Compiling into folder "%s"' % target) 7041cb0ef41Sopenharmony_ci 7051cb0ef41Sopenharmony_ci try: 7061cb0ef41Sopenharmony_ci for name in self.list_templates(extensions, filter_func): 7071cb0ef41Sopenharmony_ci source, filename, _ = self.loader.get_source(self, name) 7081cb0ef41Sopenharmony_ci try: 7091cb0ef41Sopenharmony_ci code = self.compile(source, name, filename, True, True) 7101cb0ef41Sopenharmony_ci except TemplateSyntaxError as e: 7111cb0ef41Sopenharmony_ci if not ignore_errors: 7121cb0ef41Sopenharmony_ci raise 7131cb0ef41Sopenharmony_ci log_function('Could not compile "%s": %s' % (name, e)) 7141cb0ef41Sopenharmony_ci continue 7151cb0ef41Sopenharmony_ci 7161cb0ef41Sopenharmony_ci filename = ModuleLoader.get_module_filename(name) 7171cb0ef41Sopenharmony_ci 7181cb0ef41Sopenharmony_ci if py_compile: 7191cb0ef41Sopenharmony_ci c = self._compile(code, encode_filename(filename)) 7201cb0ef41Sopenharmony_ci write_file(filename + 'c', py_header + 7211cb0ef41Sopenharmony_ci marshal.dumps(c), 'wb') 7221cb0ef41Sopenharmony_ci log_function('Byte-compiled "%s" as %s' % 7231cb0ef41Sopenharmony_ci (name, filename + 'c')) 7241cb0ef41Sopenharmony_ci else: 7251cb0ef41Sopenharmony_ci write_file(filename, code, 'w') 7261cb0ef41Sopenharmony_ci log_function('Compiled "%s" as %s' % (name, filename)) 7271cb0ef41Sopenharmony_ci finally: 7281cb0ef41Sopenharmony_ci if zip: 7291cb0ef41Sopenharmony_ci zip_file.close() 7301cb0ef41Sopenharmony_ci 7311cb0ef41Sopenharmony_ci log_function('Finished compiling templates') 7321cb0ef41Sopenharmony_ci 7331cb0ef41Sopenharmony_ci def list_templates(self, extensions=None, filter_func=None): 7341cb0ef41Sopenharmony_ci """Returns a list of templates for this environment. This requires 7351cb0ef41Sopenharmony_ci that the loader supports the loader's 7361cb0ef41Sopenharmony_ci :meth:`~BaseLoader.list_templates` method. 7371cb0ef41Sopenharmony_ci 7381cb0ef41Sopenharmony_ci If there are other files in the template folder besides the 7391cb0ef41Sopenharmony_ci actual templates, the returned list can be filtered. There are two 7401cb0ef41Sopenharmony_ci ways: either `extensions` is set to a list of file extensions for 7411cb0ef41Sopenharmony_ci templates, or a `filter_func` can be provided which is a callable that 7421cb0ef41Sopenharmony_ci is passed a template name and should return `True` if it should end up 7431cb0ef41Sopenharmony_ci in the result list. 7441cb0ef41Sopenharmony_ci 7451cb0ef41Sopenharmony_ci If the loader does not support that, a :exc:`TypeError` is raised. 7461cb0ef41Sopenharmony_ci 7471cb0ef41Sopenharmony_ci .. versionadded:: 2.4 7481cb0ef41Sopenharmony_ci """ 7491cb0ef41Sopenharmony_ci x = self.loader.list_templates() 7501cb0ef41Sopenharmony_ci if extensions is not None: 7511cb0ef41Sopenharmony_ci if filter_func is not None: 7521cb0ef41Sopenharmony_ci raise TypeError('either extensions or filter_func ' 7531cb0ef41Sopenharmony_ci 'can be passed, but not both') 7541cb0ef41Sopenharmony_ci filter_func = lambda x: '.' in x and \ 7551cb0ef41Sopenharmony_ci x.rsplit('.', 1)[1] in extensions 7561cb0ef41Sopenharmony_ci if filter_func is not None: 7571cb0ef41Sopenharmony_ci x = list(ifilter(filter_func, x)) 7581cb0ef41Sopenharmony_ci return x 7591cb0ef41Sopenharmony_ci 7601cb0ef41Sopenharmony_ci def handle_exception(self, exc_info=None, rendered=False, source_hint=None): 7611cb0ef41Sopenharmony_ci """Exception handling helper. This is used internally to either raise 7621cb0ef41Sopenharmony_ci rewritten exceptions or return a rendered traceback for the template. 7631cb0ef41Sopenharmony_ci """ 7641cb0ef41Sopenharmony_ci global _make_traceback 7651cb0ef41Sopenharmony_ci if exc_info is None: 7661cb0ef41Sopenharmony_ci exc_info = sys.exc_info() 7671cb0ef41Sopenharmony_ci 7681cb0ef41Sopenharmony_ci # the debugging module is imported when it's used for the first time. 7691cb0ef41Sopenharmony_ci # we're doing a lot of stuff there and for applications that do not 7701cb0ef41Sopenharmony_ci # get any exceptions in template rendering there is no need to load 7711cb0ef41Sopenharmony_ci # all of that. 7721cb0ef41Sopenharmony_ci if _make_traceback is None: 7731cb0ef41Sopenharmony_ci from jinja2.debug import make_traceback as _make_traceback 7741cb0ef41Sopenharmony_ci traceback = _make_traceback(exc_info, source_hint) 7751cb0ef41Sopenharmony_ci if rendered and self.exception_formatter is not None: 7761cb0ef41Sopenharmony_ci return self.exception_formatter(traceback) 7771cb0ef41Sopenharmony_ci if self.exception_handler is not None: 7781cb0ef41Sopenharmony_ci self.exception_handler(traceback) 7791cb0ef41Sopenharmony_ci exc_type, exc_value, tb = traceback.standard_exc_info 7801cb0ef41Sopenharmony_ci reraise(exc_type, exc_value, tb) 7811cb0ef41Sopenharmony_ci 7821cb0ef41Sopenharmony_ci def join_path(self, template, parent): 7831cb0ef41Sopenharmony_ci """Join a template with the parent. By default all the lookups are 7841cb0ef41Sopenharmony_ci relative to the loader root so this method returns the `template` 7851cb0ef41Sopenharmony_ci parameter unchanged, but if the paths should be relative to the 7861cb0ef41Sopenharmony_ci parent template, this function can be used to calculate the real 7871cb0ef41Sopenharmony_ci template name. 7881cb0ef41Sopenharmony_ci 7891cb0ef41Sopenharmony_ci Subclasses may override this method and implement template path 7901cb0ef41Sopenharmony_ci joining here. 7911cb0ef41Sopenharmony_ci """ 7921cb0ef41Sopenharmony_ci return template 7931cb0ef41Sopenharmony_ci 7941cb0ef41Sopenharmony_ci @internalcode 7951cb0ef41Sopenharmony_ci def _load_template(self, name, globals): 7961cb0ef41Sopenharmony_ci if self.loader is None: 7971cb0ef41Sopenharmony_ci raise TypeError('no loader for this environment specified') 7981cb0ef41Sopenharmony_ci cache_key = (weakref.ref(self.loader), name) 7991cb0ef41Sopenharmony_ci if self.cache is not None: 8001cb0ef41Sopenharmony_ci template = self.cache.get(cache_key) 8011cb0ef41Sopenharmony_ci if template is not None and (not self.auto_reload or 8021cb0ef41Sopenharmony_ci template.is_up_to_date): 8031cb0ef41Sopenharmony_ci return template 8041cb0ef41Sopenharmony_ci template = self.loader.load(self, name, globals) 8051cb0ef41Sopenharmony_ci if self.cache is not None: 8061cb0ef41Sopenharmony_ci self.cache[cache_key] = template 8071cb0ef41Sopenharmony_ci return template 8081cb0ef41Sopenharmony_ci 8091cb0ef41Sopenharmony_ci @internalcode 8101cb0ef41Sopenharmony_ci def get_template(self, name, parent=None, globals=None): 8111cb0ef41Sopenharmony_ci """Load a template from the loader. If a loader is configured this 8121cb0ef41Sopenharmony_ci method asks the loader for the template and returns a :class:`Template`. 8131cb0ef41Sopenharmony_ci If the `parent` parameter is not `None`, :meth:`join_path` is called 8141cb0ef41Sopenharmony_ci to get the real template name before loading. 8151cb0ef41Sopenharmony_ci 8161cb0ef41Sopenharmony_ci The `globals` parameter can be used to provide template wide globals. 8171cb0ef41Sopenharmony_ci These variables are available in the context at render time. 8181cb0ef41Sopenharmony_ci 8191cb0ef41Sopenharmony_ci If the template does not exist a :exc:`TemplateNotFound` exception is 8201cb0ef41Sopenharmony_ci raised. 8211cb0ef41Sopenharmony_ci 8221cb0ef41Sopenharmony_ci .. versionchanged:: 2.4 8231cb0ef41Sopenharmony_ci If `name` is a :class:`Template` object it is returned from the 8241cb0ef41Sopenharmony_ci function unchanged. 8251cb0ef41Sopenharmony_ci """ 8261cb0ef41Sopenharmony_ci if isinstance(name, Template): 8271cb0ef41Sopenharmony_ci return name 8281cb0ef41Sopenharmony_ci if parent is not None: 8291cb0ef41Sopenharmony_ci name = self.join_path(name, parent) 8301cb0ef41Sopenharmony_ci return self._load_template(name, self.make_globals(globals)) 8311cb0ef41Sopenharmony_ci 8321cb0ef41Sopenharmony_ci @internalcode 8331cb0ef41Sopenharmony_ci def select_template(self, names, parent=None, globals=None): 8341cb0ef41Sopenharmony_ci """Works like :meth:`get_template` but tries a number of templates 8351cb0ef41Sopenharmony_ci before it fails. If it cannot find any of the templates, it will 8361cb0ef41Sopenharmony_ci raise a :exc:`TemplatesNotFound` exception. 8371cb0ef41Sopenharmony_ci 8381cb0ef41Sopenharmony_ci .. versionadded:: 2.3 8391cb0ef41Sopenharmony_ci 8401cb0ef41Sopenharmony_ci .. versionchanged:: 2.4 8411cb0ef41Sopenharmony_ci If `names` contains a :class:`Template` object it is returned 8421cb0ef41Sopenharmony_ci from the function unchanged. 8431cb0ef41Sopenharmony_ci """ 8441cb0ef41Sopenharmony_ci if not names: 8451cb0ef41Sopenharmony_ci raise TemplatesNotFound(message=u'Tried to select from an empty list ' 8461cb0ef41Sopenharmony_ci u'of templates.') 8471cb0ef41Sopenharmony_ci globals = self.make_globals(globals) 8481cb0ef41Sopenharmony_ci for name in names: 8491cb0ef41Sopenharmony_ci if isinstance(name, Template): 8501cb0ef41Sopenharmony_ci return name 8511cb0ef41Sopenharmony_ci if parent is not None: 8521cb0ef41Sopenharmony_ci name = self.join_path(name, parent) 8531cb0ef41Sopenharmony_ci try: 8541cb0ef41Sopenharmony_ci return self._load_template(name, globals) 8551cb0ef41Sopenharmony_ci except TemplateNotFound: 8561cb0ef41Sopenharmony_ci pass 8571cb0ef41Sopenharmony_ci raise TemplatesNotFound(names) 8581cb0ef41Sopenharmony_ci 8591cb0ef41Sopenharmony_ci @internalcode 8601cb0ef41Sopenharmony_ci def get_or_select_template(self, template_name_or_list, 8611cb0ef41Sopenharmony_ci parent=None, globals=None): 8621cb0ef41Sopenharmony_ci """Does a typecheck and dispatches to :meth:`select_template` 8631cb0ef41Sopenharmony_ci if an iterable of template names is given, otherwise to 8641cb0ef41Sopenharmony_ci :meth:`get_template`. 8651cb0ef41Sopenharmony_ci 8661cb0ef41Sopenharmony_ci .. versionadded:: 2.3 8671cb0ef41Sopenharmony_ci """ 8681cb0ef41Sopenharmony_ci if isinstance(template_name_or_list, string_types): 8691cb0ef41Sopenharmony_ci return self.get_template(template_name_or_list, parent, globals) 8701cb0ef41Sopenharmony_ci elif isinstance(template_name_or_list, Template): 8711cb0ef41Sopenharmony_ci return template_name_or_list 8721cb0ef41Sopenharmony_ci return self.select_template(template_name_or_list, parent, globals) 8731cb0ef41Sopenharmony_ci 8741cb0ef41Sopenharmony_ci def from_string(self, source, globals=None, template_class=None): 8751cb0ef41Sopenharmony_ci """Load a template from a string. This parses the source given and 8761cb0ef41Sopenharmony_ci returns a :class:`Template` object. 8771cb0ef41Sopenharmony_ci """ 8781cb0ef41Sopenharmony_ci globals = self.make_globals(globals) 8791cb0ef41Sopenharmony_ci cls = template_class or self.template_class 8801cb0ef41Sopenharmony_ci return cls.from_code(self, self.compile(source), globals, None) 8811cb0ef41Sopenharmony_ci 8821cb0ef41Sopenharmony_ci def make_globals(self, d): 8831cb0ef41Sopenharmony_ci """Return a dict for the globals.""" 8841cb0ef41Sopenharmony_ci if not d: 8851cb0ef41Sopenharmony_ci return self.globals 8861cb0ef41Sopenharmony_ci return dict(self.globals, **d) 8871cb0ef41Sopenharmony_ci 8881cb0ef41Sopenharmony_ci 8891cb0ef41Sopenharmony_ciclass Template(object): 8901cb0ef41Sopenharmony_ci """The central template object. This class represents a compiled template 8911cb0ef41Sopenharmony_ci and is used to evaluate it. 8921cb0ef41Sopenharmony_ci 8931cb0ef41Sopenharmony_ci Normally the template object is generated from an :class:`Environment` but 8941cb0ef41Sopenharmony_ci it also has a constructor that makes it possible to create a template 8951cb0ef41Sopenharmony_ci instance directly using the constructor. It takes the same arguments as 8961cb0ef41Sopenharmony_ci the environment constructor but it's not possible to specify a loader. 8971cb0ef41Sopenharmony_ci 8981cb0ef41Sopenharmony_ci Every template object has a few methods and members that are guaranteed 8991cb0ef41Sopenharmony_ci to exist. However it's important that a template object should be 9001cb0ef41Sopenharmony_ci considered immutable. Modifications on the object are not supported. 9011cb0ef41Sopenharmony_ci 9021cb0ef41Sopenharmony_ci Template objects created from the constructor rather than an environment 9031cb0ef41Sopenharmony_ci do have an `environment` attribute that points to a temporary environment 9041cb0ef41Sopenharmony_ci that is probably shared with other templates created with the constructor 9051cb0ef41Sopenharmony_ci and compatible settings. 9061cb0ef41Sopenharmony_ci 9071cb0ef41Sopenharmony_ci >>> template = Template('Hello {{ name }}!') 9081cb0ef41Sopenharmony_ci >>> template.render(name='John Doe') == u'Hello John Doe!' 9091cb0ef41Sopenharmony_ci True 9101cb0ef41Sopenharmony_ci >>> stream = template.stream(name='John Doe') 9111cb0ef41Sopenharmony_ci >>> next(stream) == u'Hello John Doe!' 9121cb0ef41Sopenharmony_ci True 9131cb0ef41Sopenharmony_ci >>> next(stream) 9141cb0ef41Sopenharmony_ci Traceback (most recent call last): 9151cb0ef41Sopenharmony_ci ... 9161cb0ef41Sopenharmony_ci StopIteration 9171cb0ef41Sopenharmony_ci """ 9181cb0ef41Sopenharmony_ci 9191cb0ef41Sopenharmony_ci def __new__(cls, source, 9201cb0ef41Sopenharmony_ci block_start_string=BLOCK_START_STRING, 9211cb0ef41Sopenharmony_ci block_end_string=BLOCK_END_STRING, 9221cb0ef41Sopenharmony_ci variable_start_string=VARIABLE_START_STRING, 9231cb0ef41Sopenharmony_ci variable_end_string=VARIABLE_END_STRING, 9241cb0ef41Sopenharmony_ci comment_start_string=COMMENT_START_STRING, 9251cb0ef41Sopenharmony_ci comment_end_string=COMMENT_END_STRING, 9261cb0ef41Sopenharmony_ci line_statement_prefix=LINE_STATEMENT_PREFIX, 9271cb0ef41Sopenharmony_ci line_comment_prefix=LINE_COMMENT_PREFIX, 9281cb0ef41Sopenharmony_ci trim_blocks=TRIM_BLOCKS, 9291cb0ef41Sopenharmony_ci lstrip_blocks=LSTRIP_BLOCKS, 9301cb0ef41Sopenharmony_ci newline_sequence=NEWLINE_SEQUENCE, 9311cb0ef41Sopenharmony_ci keep_trailing_newline=KEEP_TRAILING_NEWLINE, 9321cb0ef41Sopenharmony_ci extensions=(), 9331cb0ef41Sopenharmony_ci optimized=True, 9341cb0ef41Sopenharmony_ci undefined=Undefined, 9351cb0ef41Sopenharmony_ci finalize=None, 9361cb0ef41Sopenharmony_ci autoescape=False, 9371cb0ef41Sopenharmony_ci enable_async=False): 9381cb0ef41Sopenharmony_ci env = get_spontaneous_environment( 9391cb0ef41Sopenharmony_ci block_start_string, block_end_string, variable_start_string, 9401cb0ef41Sopenharmony_ci variable_end_string, comment_start_string, comment_end_string, 9411cb0ef41Sopenharmony_ci line_statement_prefix, line_comment_prefix, trim_blocks, 9421cb0ef41Sopenharmony_ci lstrip_blocks, newline_sequence, keep_trailing_newline, 9431cb0ef41Sopenharmony_ci frozenset(extensions), optimized, undefined, finalize, autoescape, 9441cb0ef41Sopenharmony_ci None, 0, False, None, enable_async) 9451cb0ef41Sopenharmony_ci return env.from_string(source, template_class=cls) 9461cb0ef41Sopenharmony_ci 9471cb0ef41Sopenharmony_ci @classmethod 9481cb0ef41Sopenharmony_ci def from_code(cls, environment, code, globals, uptodate=None): 9491cb0ef41Sopenharmony_ci """Creates a template object from compiled code and the globals. This 9501cb0ef41Sopenharmony_ci is used by the loaders and environment to create a template object. 9511cb0ef41Sopenharmony_ci """ 9521cb0ef41Sopenharmony_ci namespace = { 9531cb0ef41Sopenharmony_ci 'environment': environment, 9541cb0ef41Sopenharmony_ci '__file__': code.co_filename 9551cb0ef41Sopenharmony_ci } 9561cb0ef41Sopenharmony_ci exec(code, namespace) 9571cb0ef41Sopenharmony_ci rv = cls._from_namespace(environment, namespace, globals) 9581cb0ef41Sopenharmony_ci rv._uptodate = uptodate 9591cb0ef41Sopenharmony_ci return rv 9601cb0ef41Sopenharmony_ci 9611cb0ef41Sopenharmony_ci @classmethod 9621cb0ef41Sopenharmony_ci def from_module_dict(cls, environment, module_dict, globals): 9631cb0ef41Sopenharmony_ci """Creates a template object from a module. This is used by the 9641cb0ef41Sopenharmony_ci module loader to create a template object. 9651cb0ef41Sopenharmony_ci 9661cb0ef41Sopenharmony_ci .. versionadded:: 2.4 9671cb0ef41Sopenharmony_ci """ 9681cb0ef41Sopenharmony_ci return cls._from_namespace(environment, module_dict, globals) 9691cb0ef41Sopenharmony_ci 9701cb0ef41Sopenharmony_ci @classmethod 9711cb0ef41Sopenharmony_ci def _from_namespace(cls, environment, namespace, globals): 9721cb0ef41Sopenharmony_ci t = object.__new__(cls) 9731cb0ef41Sopenharmony_ci t.environment = environment 9741cb0ef41Sopenharmony_ci t.globals = globals 9751cb0ef41Sopenharmony_ci t.name = namespace['name'] 9761cb0ef41Sopenharmony_ci t.filename = namespace['__file__'] 9771cb0ef41Sopenharmony_ci t.blocks = namespace['blocks'] 9781cb0ef41Sopenharmony_ci 9791cb0ef41Sopenharmony_ci # render function and module 9801cb0ef41Sopenharmony_ci t.root_render_func = namespace['root'] 9811cb0ef41Sopenharmony_ci t._module = None 9821cb0ef41Sopenharmony_ci 9831cb0ef41Sopenharmony_ci # debug and loader helpers 9841cb0ef41Sopenharmony_ci t._debug_info = namespace['debug_info'] 9851cb0ef41Sopenharmony_ci t._uptodate = None 9861cb0ef41Sopenharmony_ci 9871cb0ef41Sopenharmony_ci # store the reference 9881cb0ef41Sopenharmony_ci namespace['environment'] = environment 9891cb0ef41Sopenharmony_ci namespace['__jinja_template__'] = t 9901cb0ef41Sopenharmony_ci 9911cb0ef41Sopenharmony_ci return t 9921cb0ef41Sopenharmony_ci 9931cb0ef41Sopenharmony_ci def render(self, *args, **kwargs): 9941cb0ef41Sopenharmony_ci """This method accepts the same arguments as the `dict` constructor: 9951cb0ef41Sopenharmony_ci A dict, a dict subclass or some keyword arguments. If no arguments 9961cb0ef41Sopenharmony_ci are given the context will be empty. These two calls do the same:: 9971cb0ef41Sopenharmony_ci 9981cb0ef41Sopenharmony_ci template.render(knights='that say nih') 9991cb0ef41Sopenharmony_ci template.render({'knights': 'that say nih'}) 10001cb0ef41Sopenharmony_ci 10011cb0ef41Sopenharmony_ci This will return the rendered template as unicode string. 10021cb0ef41Sopenharmony_ci """ 10031cb0ef41Sopenharmony_ci vars = dict(*args, **kwargs) 10041cb0ef41Sopenharmony_ci try: 10051cb0ef41Sopenharmony_ci return concat(self.root_render_func(self.new_context(vars))) 10061cb0ef41Sopenharmony_ci except Exception: 10071cb0ef41Sopenharmony_ci exc_info = sys.exc_info() 10081cb0ef41Sopenharmony_ci return self.environment.handle_exception(exc_info, True) 10091cb0ef41Sopenharmony_ci 10101cb0ef41Sopenharmony_ci def render_async(self, *args, **kwargs): 10111cb0ef41Sopenharmony_ci """This works similar to :meth:`render` but returns a coroutine 10121cb0ef41Sopenharmony_ci that when awaited returns the entire rendered template string. This 10131cb0ef41Sopenharmony_ci requires the async feature to be enabled. 10141cb0ef41Sopenharmony_ci 10151cb0ef41Sopenharmony_ci Example usage:: 10161cb0ef41Sopenharmony_ci 10171cb0ef41Sopenharmony_ci await template.render_async(knights='that say nih; asynchronously') 10181cb0ef41Sopenharmony_ci """ 10191cb0ef41Sopenharmony_ci # see asyncsupport for the actual implementation 10201cb0ef41Sopenharmony_ci raise NotImplementedError('This feature is not available for this ' 10211cb0ef41Sopenharmony_ci 'version of Python') 10221cb0ef41Sopenharmony_ci 10231cb0ef41Sopenharmony_ci def stream(self, *args, **kwargs): 10241cb0ef41Sopenharmony_ci """Works exactly like :meth:`generate` but returns a 10251cb0ef41Sopenharmony_ci :class:`TemplateStream`. 10261cb0ef41Sopenharmony_ci """ 10271cb0ef41Sopenharmony_ci return TemplateStream(self.generate(*args, **kwargs)) 10281cb0ef41Sopenharmony_ci 10291cb0ef41Sopenharmony_ci def generate(self, *args, **kwargs): 10301cb0ef41Sopenharmony_ci """For very large templates it can be useful to not render the whole 10311cb0ef41Sopenharmony_ci template at once but evaluate each statement after another and yield 10321cb0ef41Sopenharmony_ci piece for piece. This method basically does exactly that and returns 10331cb0ef41Sopenharmony_ci a generator that yields one item after another as unicode strings. 10341cb0ef41Sopenharmony_ci 10351cb0ef41Sopenharmony_ci It accepts the same arguments as :meth:`render`. 10361cb0ef41Sopenharmony_ci """ 10371cb0ef41Sopenharmony_ci vars = dict(*args, **kwargs) 10381cb0ef41Sopenharmony_ci try: 10391cb0ef41Sopenharmony_ci for event in self.root_render_func(self.new_context(vars)): 10401cb0ef41Sopenharmony_ci yield event 10411cb0ef41Sopenharmony_ci except Exception: 10421cb0ef41Sopenharmony_ci exc_info = sys.exc_info() 10431cb0ef41Sopenharmony_ci else: 10441cb0ef41Sopenharmony_ci return 10451cb0ef41Sopenharmony_ci yield self.environment.handle_exception(exc_info, True) 10461cb0ef41Sopenharmony_ci 10471cb0ef41Sopenharmony_ci def generate_async(self, *args, **kwargs): 10481cb0ef41Sopenharmony_ci """An async version of :meth:`generate`. Works very similarly but 10491cb0ef41Sopenharmony_ci returns an async iterator instead. 10501cb0ef41Sopenharmony_ci """ 10511cb0ef41Sopenharmony_ci # see asyncsupport for the actual implementation 10521cb0ef41Sopenharmony_ci raise NotImplementedError('This feature is not available for this ' 10531cb0ef41Sopenharmony_ci 'version of Python') 10541cb0ef41Sopenharmony_ci 10551cb0ef41Sopenharmony_ci def new_context(self, vars=None, shared=False, locals=None): 10561cb0ef41Sopenharmony_ci """Create a new :class:`Context` for this template. The vars 10571cb0ef41Sopenharmony_ci provided will be passed to the template. Per default the globals 10581cb0ef41Sopenharmony_ci are added to the context. If shared is set to `True` the data 10591cb0ef41Sopenharmony_ci is passed as it to the context without adding the globals. 10601cb0ef41Sopenharmony_ci 10611cb0ef41Sopenharmony_ci `locals` can be a dict of local variables for internal usage. 10621cb0ef41Sopenharmony_ci """ 10631cb0ef41Sopenharmony_ci return new_context(self.environment, self.name, self.blocks, 10641cb0ef41Sopenharmony_ci vars, shared, self.globals, locals) 10651cb0ef41Sopenharmony_ci 10661cb0ef41Sopenharmony_ci def make_module(self, vars=None, shared=False, locals=None): 10671cb0ef41Sopenharmony_ci """This method works like the :attr:`module` attribute when called 10681cb0ef41Sopenharmony_ci without arguments but it will evaluate the template on every call 10691cb0ef41Sopenharmony_ci rather than caching it. It's also possible to provide 10701cb0ef41Sopenharmony_ci a dict which is then used as context. The arguments are the same 10711cb0ef41Sopenharmony_ci as for the :meth:`new_context` method. 10721cb0ef41Sopenharmony_ci """ 10731cb0ef41Sopenharmony_ci return TemplateModule(self, self.new_context(vars, shared, locals)) 10741cb0ef41Sopenharmony_ci 10751cb0ef41Sopenharmony_ci def make_module_async(self, vars=None, shared=False, locals=None): 10761cb0ef41Sopenharmony_ci """As template module creation can invoke template code for 10771cb0ef41Sopenharmony_ci asynchronous exections this method must be used instead of the 10781cb0ef41Sopenharmony_ci normal :meth:`make_module` one. Likewise the module attribute 10791cb0ef41Sopenharmony_ci becomes unavailable in async mode. 10801cb0ef41Sopenharmony_ci """ 10811cb0ef41Sopenharmony_ci # see asyncsupport for the actual implementation 10821cb0ef41Sopenharmony_ci raise NotImplementedError('This feature is not available for this ' 10831cb0ef41Sopenharmony_ci 'version of Python') 10841cb0ef41Sopenharmony_ci 10851cb0ef41Sopenharmony_ci @internalcode 10861cb0ef41Sopenharmony_ci def _get_default_module(self): 10871cb0ef41Sopenharmony_ci if self._module is not None: 10881cb0ef41Sopenharmony_ci return self._module 10891cb0ef41Sopenharmony_ci self._module = rv = self.make_module() 10901cb0ef41Sopenharmony_ci return rv 10911cb0ef41Sopenharmony_ci 10921cb0ef41Sopenharmony_ci @property 10931cb0ef41Sopenharmony_ci def module(self): 10941cb0ef41Sopenharmony_ci """The template as module. This is used for imports in the 10951cb0ef41Sopenharmony_ci template runtime but is also useful if one wants to access 10961cb0ef41Sopenharmony_ci exported template variables from the Python layer: 10971cb0ef41Sopenharmony_ci 10981cb0ef41Sopenharmony_ci >>> t = Template('{% macro foo() %}42{% endmacro %}23') 10991cb0ef41Sopenharmony_ci >>> str(t.module) 11001cb0ef41Sopenharmony_ci '23' 11011cb0ef41Sopenharmony_ci >>> t.module.foo() == u'42' 11021cb0ef41Sopenharmony_ci True 11031cb0ef41Sopenharmony_ci 11041cb0ef41Sopenharmony_ci This attribute is not available if async mode is enabled. 11051cb0ef41Sopenharmony_ci """ 11061cb0ef41Sopenharmony_ci return self._get_default_module() 11071cb0ef41Sopenharmony_ci 11081cb0ef41Sopenharmony_ci def get_corresponding_lineno(self, lineno): 11091cb0ef41Sopenharmony_ci """Return the source line number of a line number in the 11101cb0ef41Sopenharmony_ci generated bytecode as they are not in sync. 11111cb0ef41Sopenharmony_ci """ 11121cb0ef41Sopenharmony_ci for template_line, code_line in reversed(self.debug_info): 11131cb0ef41Sopenharmony_ci if code_line <= lineno: 11141cb0ef41Sopenharmony_ci return template_line 11151cb0ef41Sopenharmony_ci return 1 11161cb0ef41Sopenharmony_ci 11171cb0ef41Sopenharmony_ci @property 11181cb0ef41Sopenharmony_ci def is_up_to_date(self): 11191cb0ef41Sopenharmony_ci """If this variable is `False` there is a newer version available.""" 11201cb0ef41Sopenharmony_ci if self._uptodate is None: 11211cb0ef41Sopenharmony_ci return True 11221cb0ef41Sopenharmony_ci return self._uptodate() 11231cb0ef41Sopenharmony_ci 11241cb0ef41Sopenharmony_ci @property 11251cb0ef41Sopenharmony_ci def debug_info(self): 11261cb0ef41Sopenharmony_ci """The debug info mapping.""" 11271cb0ef41Sopenharmony_ci return [tuple(imap(int, x.split('='))) for x in 11281cb0ef41Sopenharmony_ci self._debug_info.split('&')] 11291cb0ef41Sopenharmony_ci 11301cb0ef41Sopenharmony_ci def __repr__(self): 11311cb0ef41Sopenharmony_ci if self.name is None: 11321cb0ef41Sopenharmony_ci name = 'memory:%x' % id(self) 11331cb0ef41Sopenharmony_ci else: 11341cb0ef41Sopenharmony_ci name = repr(self.name) 11351cb0ef41Sopenharmony_ci return '<%s %s>' % (self.__class__.__name__, name) 11361cb0ef41Sopenharmony_ci 11371cb0ef41Sopenharmony_ci 11381cb0ef41Sopenharmony_ci@implements_to_string 11391cb0ef41Sopenharmony_ciclass TemplateModule(object): 11401cb0ef41Sopenharmony_ci """Represents an imported template. All the exported names of the 11411cb0ef41Sopenharmony_ci template are available as attributes on this object. Additionally 11421cb0ef41Sopenharmony_ci converting it into an unicode- or bytestrings renders the contents. 11431cb0ef41Sopenharmony_ci """ 11441cb0ef41Sopenharmony_ci 11451cb0ef41Sopenharmony_ci def __init__(self, template, context, body_stream=None): 11461cb0ef41Sopenharmony_ci if body_stream is None: 11471cb0ef41Sopenharmony_ci if context.environment.is_async: 11481cb0ef41Sopenharmony_ci raise RuntimeError('Async mode requires a body stream ' 11491cb0ef41Sopenharmony_ci 'to be passed to a template module. Use ' 11501cb0ef41Sopenharmony_ci 'the async methods of the API you are ' 11511cb0ef41Sopenharmony_ci 'using.') 11521cb0ef41Sopenharmony_ci body_stream = list(template.root_render_func(context)) 11531cb0ef41Sopenharmony_ci self._body_stream = body_stream 11541cb0ef41Sopenharmony_ci self.__dict__.update(context.get_exported()) 11551cb0ef41Sopenharmony_ci self.__name__ = template.name 11561cb0ef41Sopenharmony_ci 11571cb0ef41Sopenharmony_ci def __html__(self): 11581cb0ef41Sopenharmony_ci return Markup(concat(self._body_stream)) 11591cb0ef41Sopenharmony_ci 11601cb0ef41Sopenharmony_ci def __str__(self): 11611cb0ef41Sopenharmony_ci return concat(self._body_stream) 11621cb0ef41Sopenharmony_ci 11631cb0ef41Sopenharmony_ci def __repr__(self): 11641cb0ef41Sopenharmony_ci if self.__name__ is None: 11651cb0ef41Sopenharmony_ci name = 'memory:%x' % id(self) 11661cb0ef41Sopenharmony_ci else: 11671cb0ef41Sopenharmony_ci name = repr(self.__name__) 11681cb0ef41Sopenharmony_ci return '<%s %s>' % (self.__class__.__name__, name) 11691cb0ef41Sopenharmony_ci 11701cb0ef41Sopenharmony_ci 11711cb0ef41Sopenharmony_ciclass TemplateExpression(object): 11721cb0ef41Sopenharmony_ci """The :meth:`jinja2.Environment.compile_expression` method returns an 11731cb0ef41Sopenharmony_ci instance of this object. It encapsulates the expression-like access 11741cb0ef41Sopenharmony_ci to the template with an expression it wraps. 11751cb0ef41Sopenharmony_ci """ 11761cb0ef41Sopenharmony_ci 11771cb0ef41Sopenharmony_ci def __init__(self, template, undefined_to_none): 11781cb0ef41Sopenharmony_ci self._template = template 11791cb0ef41Sopenharmony_ci self._undefined_to_none = undefined_to_none 11801cb0ef41Sopenharmony_ci 11811cb0ef41Sopenharmony_ci def __call__(self, *args, **kwargs): 11821cb0ef41Sopenharmony_ci context = self._template.new_context(dict(*args, **kwargs)) 11831cb0ef41Sopenharmony_ci consume(self._template.root_render_func(context)) 11841cb0ef41Sopenharmony_ci rv = context.vars['result'] 11851cb0ef41Sopenharmony_ci if self._undefined_to_none and isinstance(rv, Undefined): 11861cb0ef41Sopenharmony_ci rv = None 11871cb0ef41Sopenharmony_ci return rv 11881cb0ef41Sopenharmony_ci 11891cb0ef41Sopenharmony_ci 11901cb0ef41Sopenharmony_ci@implements_iterator 11911cb0ef41Sopenharmony_ciclass TemplateStream(object): 11921cb0ef41Sopenharmony_ci """A template stream works pretty much like an ordinary python generator 11931cb0ef41Sopenharmony_ci but it can buffer multiple items to reduce the number of total iterations. 11941cb0ef41Sopenharmony_ci Per default the output is unbuffered which means that for every unbuffered 11951cb0ef41Sopenharmony_ci instruction in the template one unicode string is yielded. 11961cb0ef41Sopenharmony_ci 11971cb0ef41Sopenharmony_ci If buffering is enabled with a buffer size of 5, five items are combined 11981cb0ef41Sopenharmony_ci into a new unicode string. This is mainly useful if you are streaming 11991cb0ef41Sopenharmony_ci big templates to a client via WSGI which flushes after each iteration. 12001cb0ef41Sopenharmony_ci """ 12011cb0ef41Sopenharmony_ci 12021cb0ef41Sopenharmony_ci def __init__(self, gen): 12031cb0ef41Sopenharmony_ci self._gen = gen 12041cb0ef41Sopenharmony_ci self.disable_buffering() 12051cb0ef41Sopenharmony_ci 12061cb0ef41Sopenharmony_ci def dump(self, fp, encoding=None, errors='strict'): 12071cb0ef41Sopenharmony_ci """Dump the complete stream into a file or file-like object. 12081cb0ef41Sopenharmony_ci Per default unicode strings are written, if you want to encode 12091cb0ef41Sopenharmony_ci before writing specify an `encoding`. 12101cb0ef41Sopenharmony_ci 12111cb0ef41Sopenharmony_ci Example usage:: 12121cb0ef41Sopenharmony_ci 12131cb0ef41Sopenharmony_ci Template('Hello {{ name }}!').stream(name='foo').dump('hello.html') 12141cb0ef41Sopenharmony_ci """ 12151cb0ef41Sopenharmony_ci close = False 12161cb0ef41Sopenharmony_ci if isinstance(fp, string_types): 12171cb0ef41Sopenharmony_ci if encoding is None: 12181cb0ef41Sopenharmony_ci encoding = 'utf-8' 12191cb0ef41Sopenharmony_ci fp = open(fp, 'wb') 12201cb0ef41Sopenharmony_ci close = True 12211cb0ef41Sopenharmony_ci try: 12221cb0ef41Sopenharmony_ci if encoding is not None: 12231cb0ef41Sopenharmony_ci iterable = (x.encode(encoding, errors) for x in self) 12241cb0ef41Sopenharmony_ci else: 12251cb0ef41Sopenharmony_ci iterable = self 12261cb0ef41Sopenharmony_ci if hasattr(fp, 'writelines'): 12271cb0ef41Sopenharmony_ci fp.writelines(iterable) 12281cb0ef41Sopenharmony_ci else: 12291cb0ef41Sopenharmony_ci for item in iterable: 12301cb0ef41Sopenharmony_ci fp.write(item) 12311cb0ef41Sopenharmony_ci finally: 12321cb0ef41Sopenharmony_ci if close: 12331cb0ef41Sopenharmony_ci fp.close() 12341cb0ef41Sopenharmony_ci 12351cb0ef41Sopenharmony_ci def disable_buffering(self): 12361cb0ef41Sopenharmony_ci """Disable the output buffering.""" 12371cb0ef41Sopenharmony_ci self._next = partial(next, self._gen) 12381cb0ef41Sopenharmony_ci self.buffered = False 12391cb0ef41Sopenharmony_ci 12401cb0ef41Sopenharmony_ci def _buffered_generator(self, size): 12411cb0ef41Sopenharmony_ci buf = [] 12421cb0ef41Sopenharmony_ci c_size = 0 12431cb0ef41Sopenharmony_ci push = buf.append 12441cb0ef41Sopenharmony_ci 12451cb0ef41Sopenharmony_ci while 1: 12461cb0ef41Sopenharmony_ci try: 12471cb0ef41Sopenharmony_ci while c_size < size: 12481cb0ef41Sopenharmony_ci c = next(self._gen) 12491cb0ef41Sopenharmony_ci push(c) 12501cb0ef41Sopenharmony_ci if c: 12511cb0ef41Sopenharmony_ci c_size += 1 12521cb0ef41Sopenharmony_ci except StopIteration: 12531cb0ef41Sopenharmony_ci if not c_size: 12541cb0ef41Sopenharmony_ci return 12551cb0ef41Sopenharmony_ci yield concat(buf) 12561cb0ef41Sopenharmony_ci del buf[:] 12571cb0ef41Sopenharmony_ci c_size = 0 12581cb0ef41Sopenharmony_ci 12591cb0ef41Sopenharmony_ci def enable_buffering(self, size=5): 12601cb0ef41Sopenharmony_ci """Enable buffering. Buffer `size` items before yielding them.""" 12611cb0ef41Sopenharmony_ci if size <= 1: 12621cb0ef41Sopenharmony_ci raise ValueError('buffer size too small') 12631cb0ef41Sopenharmony_ci 12641cb0ef41Sopenharmony_ci self.buffered = True 12651cb0ef41Sopenharmony_ci self._next = partial(next, self._buffered_generator(size)) 12661cb0ef41Sopenharmony_ci 12671cb0ef41Sopenharmony_ci def __iter__(self): 12681cb0ef41Sopenharmony_ci return self 12691cb0ef41Sopenharmony_ci 12701cb0ef41Sopenharmony_ci def __next__(self): 12711cb0ef41Sopenharmony_ci return self._next() 12721cb0ef41Sopenharmony_ci 12731cb0ef41Sopenharmony_ci 12741cb0ef41Sopenharmony_ci# hook in default template class. if anyone reads this comment: ignore that 12751cb0ef41Sopenharmony_ci# it's possible to use custom templates ;-) 12761cb0ef41Sopenharmony_ciEnvironment.template_class = Template 1277