def call_filter(self, name, value, args=None, kwargs=None, context=None, eval_ctx=None): """Invokes a filter on a value the same way the compiler does it. Note that on Python 3 this might return a coroutine in case the filter is running from an environment in async mode and the filter supports async execution. It's your responsibility to await this if needed. .. versionadded:: 2.7 """ func = self.filters.get if func is None: fail_for_missing_callable('no filter named %r', name) args = [value] + list(args or ()) if getattr(func, 'contextfilter', False): if context is None: raise TemplateRuntimeError('Attempted to invoke context ' 'filter without context') args.insert(0, context) elif getattr(func, 'evalcontextfilter', False): if eval_ctx is None: if context is not None: eval_ctx = context.eval_ctx else: eval_ctx = EvalContext(self) args.insert(0, eval_ctx) elif getattr(func, 'environmentfilter', False): args.insert(0, self) return func(*args, **(kwargs or {}))
def call_filter(self, name, value, args=None, kwargs=None, context=None, eval_ctx=None): """Invokes a filter on a value the same way the compiler does it. .. versionadded:: 2.7 """ func = self.filters.get(name) if func is None: raise TemplateRuntimeError('no filter named %r' % name) args = [value] + list(args or ()) if getattr(func, 'contextfilter', False): if context is None: raise TemplateRuntimeError('Attempted to invoke context ' 'filter without context') args.insert(0, context) elif getattr(func, 'evalcontextfilter', False): if eval_ctx is None: if context is not None: eval_ctx = context.eval_ctx else: eval_ctx = EvalContext(self) args.insert(0, eval_ctx) elif getattr(func, 'environmentfilter', False): args.insert(0, self) return func(*args, **(kwargs or {}))
def flatten_const_node_list(environment, node_list): """ Try to flatten the given node list into a single string. :param environment: Jinja2 environment :type environment: jinja2.environment.Environment :param node_list: List of nodes :type node_list: list[jinja2.nodes.Node] :return: String of content :rtype: str :raise Unflattenable: Raised when the node list can't be flattened into a constant """ output = [] eval_ctx = EvalContext(environment) for node in node_list: if isinstance(node, Output): # pragma: no branch for node in node.nodes: try: const = node.as_const(eval_ctx=eval_ctx) if not isinstance(const, six.text_type): raise Unflattenable(const) output.append(const) except Impossible: raise Unflattenable(node) else: # Very unlikely, but you know. raise Unflattenable(node) # pragma: no cover return "".join(output)
def __init__(self, environment, parent, name, blocks): self.parent = parent self.vars = {} self.environment = environment self.eval_ctx = EvalContext(self.environment, name) self.exported_vars = set() self.name = name self.blocks = dict(((k, [v]) for k, v in blocks.iteritems()))
def _begin_column(self, cfg, arg): sizes = {} if arg is not None: try: sizes = arg.as_const(eval_ctx=EvalContext(self.environment)) except Impossible: raise ValueError("Invalid argument for `column`: %r" % arg) if not isinstance(sizes, dict): raise ValueError("Argument for `column` must be a dict: %r" % arg) cfg.begin_column(sizes)
def __init__(self, environment, parent, name, blocks): self.parent = parent self.vars = {} self.environment = environment self.eval_ctx = EvalContext(self.environment, name) self.exported_vars = set() self.name = name # create the initial mapping of blocks. Whenever template inheritance # takes place the runtime will update this mapping with the new blocks # from the template. self.blocks = dict((k, [v]) for k, v in iteritems(blocks))
def test_template_data(self, env): env = Environment(autoescape=True) t = env.from_string('{% macro say_hello(name) %}' '<p>Hello {{ name }}!</p>{% endmacro %}' '{{ say_hello("<blink>foo</blink>") }}') escaped_out = '<p>Hello <blink>foo</blink>!</p>' assert t.render() == escaped_out assert text_type(t.module) == escaped_out assert escape(t.module) == escaped_out assert t.module.say_hello('<blink>foo</blink>') == escaped_out assert escape( t.module.say_hello(EvalContext(env), '<blink>foo</blink>')) == escaped_out assert escape(t.module.say_hello('<blink>foo</blink>')) == escaped_out
def __init__(self, environment, parent, name, blocks): self.parent = parent self.vars = {} self.environment = environment self.eval_ctx = EvalContext(self.environment, name) self.exported_vars = set() self.name = name # create the initial mapping of blocks. Whenever template inheritance # takes place the runtime will update this mapping with the new blocks # from the template. self.blocks = dict((k, [v]) for k, v in iteritems(blocks)) # In case we detect the fast resolve mode we can set up an alias # here that bypasses the legacy code logic. if self._fast_resolve_mode: self.resolve_or_missing = MethodType(resolve_or_missing, self)
def parse_constantlike(environment, parser): """ Parse the next expression as a "constantlike" expression. Expression trees that fold into constants are constantlike, as are bare variable names. :param environment: Jinja2 environment :type environment: jinja2.environment.Environment :param parser: Template parser :type parser: jinja2.parser.Parser :return: constant value of any type :rtype: object """ expr = parser.parse_expression() if isinstance(expr, Name): # bare names are accepted return expr.name try: return expr.as_const(EvalContext(environment)) except Impossible: raise NonConstant("Not constant: %r" % expr)
def visit_Template(self, node, frame=None): eval_ctx = EvalContext(self.environment, self.name) from jinja2.runtime import __all__ as exported self.writeline('from __future__ import division') self.writeline('from jinja2.runtime import ' + ', '.join(exported)) if not unoptimize_before_dead_code: self.writeline('dummy = lambda *x: None') envenv = not self.defer_init and ', environment=environment' or '' have_extends = node.find(nodes.Extends) is not None for block in node.find_all(nodes.Block): if block.name in self.blocks: self.fail('block %r defined twice' % block.name, block.lineno) self.blocks[block.name] = block for import_ in node.find_all(nodes.ImportedName): if import_.importname not in self.import_aliases: imp = import_.importname self.import_aliases[imp] = alias = self.temporary_identifier() if '.' in imp: module, obj = imp.rsplit('.', 1) self.writeline('from %s import %s as %s' % (module, obj, alias)) else: self.writeline('import %s as %s' % (imp, alias)) self.writeline('name = %r' % self.name) self.writeline('def root(context%s):' % envenv, extra=1) frame = Frame(eval_ctx) frame.inspect(node.body) frame.toplevel = frame.rootlevel = True frame.require_output_check = have_extends and not self.has_known_extends self.indent() if have_extends: self.writeline('parent_template = None') if 'self' in find_undeclared(node.body, ('self', )): frame.identifiers.add_special('self') self.writeline('l_self = TemplateReference(context)') self.pull_locals(frame) self.pull_dependencies(node.body) self.blockvisit(node.body, frame) self.outdent() if have_extends: if not self.has_known_extends: self.indent() self.writeline('if parent_template is not None:') self.indent() self.writeline( 'for event in parent_template.root_render_func(context):') self.indent() self.writeline('yield event') self.outdent(2 + (not self.has_known_extends)) for name, block in self.blocks.iteritems(): block_frame = Frame(eval_ctx) block_frame.inspect(block.body) block_frame.block = name self.writeline('def block_%s(context%s):' % (name, envenv), block, 1) self.indent() undeclared = find_undeclared(block.body, ('self', 'super')) if 'self' in undeclared: block_frame.identifiers.add_special('self') self.writeline('l_self = TemplateReference(context)') if 'super' in undeclared: block_frame.identifiers.add_special('super') self.writeline('l_super = context.super(%r, block_%s)' % (name, name)) self.pull_locals(block_frame) self.pull_dependencies(block.body) self.blockvisit(block.body, block_frame) self.outdent() self.writeline('blocks = {%s}' % ', '.join( ('%r: block_%s' % (x, x) for x in self.blocks)), extra=1) self.writeline('debug_info = %r' % '&'.join( ('%s=%s' % x for x in self.debug_info)))