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

Side by Side Diff: mojo/public/third_party/jinja2/nodes.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
« no previous file with comments | « mojo/public/third_party/jinja2/meta.py ('k') | mojo/public/third_party/jinja2/optimizer.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # -*- coding: utf-8 -*-
2 """
3 jinja2.nodes
4 ~~~~~~~~~~~~
5
6 This module implements additional nodes derived from the ast base node.
7
8 It also provides some node tree helper functions like `in_lineno` and
9 `get_nodes` used by the parser and translator in order to normalize
10 python and jinja nodes.
11
12 :copyright: (c) 2010 by the Jinja Team.
13 :license: BSD, see LICENSE for more details.
14 """
15 import operator
16
17 from collections import deque
18 from jinja2.utils import Markup
19 from jinja2._compat import next, izip, with_metaclass, text_type, \
20 method_type, function_type
21
22
23 #: the types we support for context functions
24 _context_function_types = (function_type, method_type)
25
26
27 _binop_to_func = {
28 '*': operator.mul,
29 '/': operator.truediv,
30 '//': operator.floordiv,
31 '**': operator.pow,
32 '%': operator.mod,
33 '+': operator.add,
34 '-': operator.sub
35 }
36
37 _uaop_to_func = {
38 'not': operator.not_,
39 '+': operator.pos,
40 '-': operator.neg
41 }
42
43 _cmpop_to_func = {
44 'eq': operator.eq,
45 'ne': operator.ne,
46 'gt': operator.gt,
47 'gteq': operator.ge,
48 'lt': operator.lt,
49 'lteq': operator.le,
50 'in': lambda a, b: a in b,
51 'notin': lambda a, b: a not in b
52 }
53
54
55 class Impossible(Exception):
56 """Raised if the node could not perform a requested action."""
57
58
59 class NodeType(type):
60 """A metaclass for nodes that handles the field and attribute
61 inheritance. fields and attributes from the parent class are
62 automatically forwarded to the child."""
63
64 def __new__(cls, name, bases, d):
65 for attr in 'fields', 'attributes':
66 storage = []
67 storage.extend(getattr(bases[0], attr, ()))
68 storage.extend(d.get(attr, ()))
69 assert len(bases) == 1, 'multiple inheritance not allowed'
70 assert len(storage) == len(set(storage)), 'layout conflict'
71 d[attr] = tuple(storage)
72 d.setdefault('abstract', False)
73 return type.__new__(cls, name, bases, d)
74
75
76 class EvalContext(object):
77 """Holds evaluation time information. Custom attributes can be attached
78 to it in extensions.
79 """
80
81 def __init__(self, environment, template_name=None):
82 self.environment = environment
83 if callable(environment.autoescape):
84 self.autoescape = environment.autoescape(template_name)
85 else:
86 self.autoescape = environment.autoescape
87 self.volatile = False
88
89 def save(self):
90 return self.__dict__.copy()
91
92 def revert(self, old):
93 self.__dict__.clear()
94 self.__dict__.update(old)
95
96
97 def get_eval_context(node, ctx):
98 if ctx is None:
99 if node.environment is None:
100 raise RuntimeError('if no eval context is passed, the '
101 'node must have an attached '
102 'environment.')
103 return EvalContext(node.environment)
104 return ctx
105
106
107 class Node(with_metaclass(NodeType, object)):
108 """Baseclass for all Jinja2 nodes. There are a number of nodes available
109 of different types. There are four major types:
110
111 - :class:`Stmt`: statements
112 - :class:`Expr`: expressions
113 - :class:`Helper`: helper nodes
114 - :class:`Template`: the outermost wrapper node
115
116 All nodes have fields and attributes. Fields may be other nodes, lists,
117 or arbitrary values. Fields are passed to the constructor as regular
118 positional arguments, attributes as keyword arguments. Each node has
119 two attributes: `lineno` (the line number of the node) and `environment`.
120 The `environment` attribute is set at the end of the parsing process for
121 all nodes automatically.
122 """
123 fields = ()
124 attributes = ('lineno', 'environment')
125 abstract = True
126
127 def __init__(self, *fields, **attributes):
128 if self.abstract:
129 raise TypeError('abstract nodes are not instanciable')
130 if fields:
131 if len(fields) != len(self.fields):
132 if not self.fields:
133 raise TypeError('%r takes 0 arguments' %
134 self.__class__.__name__)
135 raise TypeError('%r takes 0 or %d argument%s' % (
136 self.__class__.__name__,
137 len(self.fields),
138 len(self.fields) != 1 and 's' or ''
139 ))
140 for name, arg in izip(self.fields, fields):
141 setattr(self, name, arg)
142 for attr in self.attributes:
143 setattr(self, attr, attributes.pop(attr, None))
144 if attributes:
145 raise TypeError('unknown attribute %r' %
146 next(iter(attributes)))
147
148 def iter_fields(self, exclude=None, only=None):
149 """This method iterates over all fields that are defined and yields
150 ``(key, value)`` tuples. Per default all fields are returned, but
151 it's possible to limit that to some fields by providing the `only`
152 parameter or to exclude some using the `exclude` parameter. Both
153 should be sets or tuples of field names.
154 """
155 for name in self.fields:
156 if (exclude is only is None) or \
157 (exclude is not None and name not in exclude) or \
158 (only is not None and name in only):
159 try:
160 yield name, getattr(self, name)
161 except AttributeError:
162 pass
163
164 def iter_child_nodes(self, exclude=None, only=None):
165 """Iterates over all direct child nodes of the node. This iterates
166 over all fields and yields the values of they are nodes. If the value
167 of a field is a list all the nodes in that list are returned.
168 """
169 for field, item in self.iter_fields(exclude, only):
170 if isinstance(item, list):
171 for n in item:
172 if isinstance(n, Node):
173 yield n
174 elif isinstance(item, Node):
175 yield item
176
177 def find(self, node_type):
178 """Find the first node of a given type. If no such node exists the
179 return value is `None`.
180 """
181 for result in self.find_all(node_type):
182 return result
183
184 def find_all(self, node_type):
185 """Find all the nodes of a given type. If the type is a tuple,
186 the check is performed for any of the tuple items.
187 """
188 for child in self.iter_child_nodes():
189 if isinstance(child, node_type):
190 yield child
191 for result in child.find_all(node_type):
192 yield result
193
194 def set_ctx(self, ctx):
195 """Reset the context of a node and all child nodes. Per default the
196 parser will all generate nodes that have a 'load' context as it's the
197 most common one. This method is used in the parser to set assignment
198 targets and other nodes to a store context.
199 """
200 todo = deque([self])
201 while todo:
202 node = todo.popleft()
203 if 'ctx' in node.fields:
204 node.ctx = ctx
205 todo.extend(node.iter_child_nodes())
206 return self
207
208 def set_lineno(self, lineno, override=False):
209 """Set the line numbers of the node and children."""
210 todo = deque([self])
211 while todo:
212 node = todo.popleft()
213 if 'lineno' in node.attributes:
214 if node.lineno is None or override:
215 node.lineno = lineno
216 todo.extend(node.iter_child_nodes())
217 return self
218
219 def set_environment(self, environment):
220 """Set the environment for all nodes."""
221 todo = deque([self])
222 while todo:
223 node = todo.popleft()
224 node.environment = environment
225 todo.extend(node.iter_child_nodes())
226 return self
227
228 def __eq__(self, other):
229 return type(self) is type(other) and \
230 tuple(self.iter_fields()) == tuple(other.iter_fields())
231
232 def __ne__(self, other):
233 return not self.__eq__(other)
234
235 # Restore Python 2 hashing behavior on Python 3
236 __hash__ = object.__hash__
237
238 def __repr__(self):
239 return '%s(%s)' % (
240 self.__class__.__name__,
241 ', '.join('%s=%r' % (arg, getattr(self, arg, None)) for
242 arg in self.fields)
243 )
244
245
246 class Stmt(Node):
247 """Base node for all statements."""
248 abstract = True
249
250
251 class Helper(Node):
252 """Nodes that exist in a specific context only."""
253 abstract = True
254
255
256 class Template(Node):
257 """Node that represents a template. This must be the outermost node that
258 is passed to the compiler.
259 """
260 fields = ('body',)
261
262
263 class Output(Stmt):
264 """A node that holds multiple expressions which are then printed out.
265 This is used both for the `print` statement and the regular template data.
266 """
267 fields = ('nodes',)
268
269
270 class Extends(Stmt):
271 """Represents an extends statement."""
272 fields = ('template',)
273
274
275 class For(Stmt):
276 """The for loop. `target` is the target for the iteration (usually a
277 :class:`Name` or :class:`Tuple`), `iter` the iterable. `body` is a list
278 of nodes that are used as loop-body, and `else_` a list of nodes for the
279 `else` block. If no else node exists it has to be an empty list.
280
281 For filtered nodes an expression can be stored as `test`, otherwise `None`.
282 """
283 fields = ('target', 'iter', 'body', 'else_', 'test', 'recursive')
284
285
286 class If(Stmt):
287 """If `test` is true, `body` is rendered, else `else_`."""
288 fields = ('test', 'body', 'else_')
289
290
291 class Macro(Stmt):
292 """A macro definition. `name` is the name of the macro, `args` a list of
293 arguments and `defaults` a list of defaults if there are any. `body` is
294 a list of nodes for the macro body.
295 """
296 fields = ('name', 'args', 'defaults', 'body')
297
298
299 class CallBlock(Stmt):
300 """Like a macro without a name but a call instead. `call` is called with
301 the unnamed macro as `caller` argument this node holds.
302 """
303 fields = ('call', 'args', 'defaults', 'body')
304
305
306 class FilterBlock(Stmt):
307 """Node for filter sections."""
308 fields = ('body', 'filter')
309
310
311 class Block(Stmt):
312 """A node that represents a block."""
313 fields = ('name', 'body', 'scoped')
314
315
316 class Include(Stmt):
317 """A node that represents the include tag."""
318 fields = ('template', 'with_context', 'ignore_missing')
319
320
321 class Import(Stmt):
322 """A node that represents the import tag."""
323 fields = ('template', 'target', 'with_context')
324
325
326 class FromImport(Stmt):
327 """A node that represents the from import tag. It's important to not
328 pass unsafe names to the name attribute. The compiler translates the
329 attribute lookups directly into getattr calls and does *not* use the
330 subscript callback of the interface. As exported variables may not
331 start with double underscores (which the parser asserts) this is not a
332 problem for regular Jinja code, but if this node is used in an extension
333 extra care must be taken.
334
335 The list of names may contain tuples if aliases are wanted.
336 """
337 fields = ('template', 'names', 'with_context')
338
339
340 class ExprStmt(Stmt):
341 """A statement that evaluates an expression and discards the result."""
342 fields = ('node',)
343
344
345 class Assign(Stmt):
346 """Assigns an expression to a target."""
347 fields = ('target', 'node')
348
349
350 class Expr(Node):
351 """Baseclass for all expressions."""
352 abstract = True
353
354 def as_const(self, eval_ctx=None):
355 """Return the value of the expression as constant or raise
356 :exc:`Impossible` if this was not possible.
357
358 An :class:`EvalContext` can be provided, if none is given
359 a default context is created which requires the nodes to have
360 an attached environment.
361
362 .. versionchanged:: 2.4
363 the `eval_ctx` parameter was added.
364 """
365 raise Impossible()
366
367 def can_assign(self):
368 """Check if it's possible to assign something to this node."""
369 return False
370
371
372 class BinExpr(Expr):
373 """Baseclass for all binary expressions."""
374 fields = ('left', 'right')
375 operator = None
376 abstract = True
377
378 def as_const(self, eval_ctx=None):
379 eval_ctx = get_eval_context(self, eval_ctx)
380 # intercepted operators cannot be folded at compile time
381 if self.environment.sandboxed and \
382 self.operator in self.environment.intercepted_binops:
383 raise Impossible()
384 f = _binop_to_func[self.operator]
385 try:
386 return f(self.left.as_const(eval_ctx), self.right.as_const(eval_ctx) )
387 except Exception:
388 raise Impossible()
389
390
391 class UnaryExpr(Expr):
392 """Baseclass for all unary expressions."""
393 fields = ('node',)
394 operator = None
395 abstract = True
396
397 def as_const(self, eval_ctx=None):
398 eval_ctx = get_eval_context(self, eval_ctx)
399 # intercepted operators cannot be folded at compile time
400 if self.environment.sandboxed and \
401 self.operator in self.environment.intercepted_unops:
402 raise Impossible()
403 f = _uaop_to_func[self.operator]
404 try:
405 return f(self.node.as_const(eval_ctx))
406 except Exception:
407 raise Impossible()
408
409
410 class Name(Expr):
411 """Looks up a name or stores a value in a name.
412 The `ctx` of the node can be one of the following values:
413
414 - `store`: store a value in the name
415 - `load`: load that name
416 - `param`: like `store` but if the name was defined as function parameter.
417 """
418 fields = ('name', 'ctx')
419
420 def can_assign(self):
421 return self.name not in ('true', 'false', 'none',
422 'True', 'False', 'None')
423
424
425 class Literal(Expr):
426 """Baseclass for literals."""
427 abstract = True
428
429
430 class Const(Literal):
431 """All constant values. The parser will return this node for simple
432 constants such as ``42`` or ``"foo"`` but it can be used to store more
433 complex values such as lists too. Only constants with a safe
434 representation (objects where ``eval(repr(x)) == x`` is true).
435 """
436 fields = ('value',)
437
438 def as_const(self, eval_ctx=None):
439 return self.value
440
441 @classmethod
442 def from_untrusted(cls, value, lineno=None, environment=None):
443 """Return a const object if the value is representable as
444 constant value in the generated code, otherwise it will raise
445 an `Impossible` exception.
446 """
447 from .compiler import has_safe_repr
448 if not has_safe_repr(value):
449 raise Impossible()
450 return cls(value, lineno=lineno, environment=environment)
451
452
453 class TemplateData(Literal):
454 """A constant template string."""
455 fields = ('data',)
456
457 def as_const(self, eval_ctx=None):
458 eval_ctx = get_eval_context(self, eval_ctx)
459 if eval_ctx.volatile:
460 raise Impossible()
461 if eval_ctx.autoescape:
462 return Markup(self.data)
463 return self.data
464
465
466 class Tuple(Literal):
467 """For loop unpacking and some other things like multiple arguments
468 for subscripts. Like for :class:`Name` `ctx` specifies if the tuple
469 is used for loading the names or storing.
470 """
471 fields = ('items', 'ctx')
472
473 def as_const(self, eval_ctx=None):
474 eval_ctx = get_eval_context(self, eval_ctx)
475 return tuple(x.as_const(eval_ctx) for x in self.items)
476
477 def can_assign(self):
478 for item in self.items:
479 if not item.can_assign():
480 return False
481 return True
482
483
484 class List(Literal):
485 """Any list literal such as ``[1, 2, 3]``"""
486 fields = ('items',)
487
488 def as_const(self, eval_ctx=None):
489 eval_ctx = get_eval_context(self, eval_ctx)
490 return [x.as_const(eval_ctx) for x in self.items]
491
492
493 class Dict(Literal):
494 """Any dict literal such as ``{1: 2, 3: 4}``. The items must be a list of
495 :class:`Pair` nodes.
496 """
497 fields = ('items',)
498
499 def as_const(self, eval_ctx=None):
500 eval_ctx = get_eval_context(self, eval_ctx)
501 return dict(x.as_const(eval_ctx) for x in self.items)
502
503
504 class Pair(Helper):
505 """A key, value pair for dicts."""
506 fields = ('key', 'value')
507
508 def as_const(self, eval_ctx=None):
509 eval_ctx = get_eval_context(self, eval_ctx)
510 return self.key.as_const(eval_ctx), self.value.as_const(eval_ctx)
511
512
513 class Keyword(Helper):
514 """A key, value pair for keyword arguments where key is a string."""
515 fields = ('key', 'value')
516
517 def as_const(self, eval_ctx=None):
518 eval_ctx = get_eval_context(self, eval_ctx)
519 return self.key, self.value.as_const(eval_ctx)
520
521
522 class CondExpr(Expr):
523 """A conditional expression (inline if expression). (``{{
524 foo if bar else baz }}``)
525 """
526 fields = ('test', 'expr1', 'expr2')
527
528 def as_const(self, eval_ctx=None):
529 eval_ctx = get_eval_context(self, eval_ctx)
530 if self.test.as_const(eval_ctx):
531 return self.expr1.as_const(eval_ctx)
532
533 # if we evaluate to an undefined object, we better do that at runtime
534 if self.expr2 is None:
535 raise Impossible()
536
537 return self.expr2.as_const(eval_ctx)
538
539
540 class Filter(Expr):
541 """This node applies a filter on an expression. `name` is the name of
542 the filter, the rest of the fields are the same as for :class:`Call`.
543
544 If the `node` of a filter is `None` the contents of the last buffer are
545 filtered. Buffers are created by macros and filter blocks.
546 """
547 fields = ('node', 'name', 'args', 'kwargs', 'dyn_args', 'dyn_kwargs')
548
549 def as_const(self, eval_ctx=None):
550 eval_ctx = get_eval_context(self, eval_ctx)
551 if eval_ctx.volatile or self.node is None:
552 raise Impossible()
553 # we have to be careful here because we call filter_ below.
554 # if this variable would be called filter, 2to3 would wrap the
555 # call in a list beause it is assuming we are talking about the
556 # builtin filter function here which no longer returns a list in
557 # python 3. because of that, do not rename filter_ to filter!
558 filter_ = self.environment.filters.get(self.name)
559 if filter_ is None or getattr(filter_, 'contextfilter', False):
560 raise Impossible()
561 obj = self.node.as_const(eval_ctx)
562 args = [x.as_const(eval_ctx) for x in self.args]
563 if getattr(filter_, 'evalcontextfilter', False):
564 args.insert(0, eval_ctx)
565 elif getattr(filter_, 'environmentfilter', False):
566 args.insert(0, self.environment)
567 kwargs = dict(x.as_const(eval_ctx) for x in self.kwargs)
568 if self.dyn_args is not None:
569 try:
570 args.extend(self.dyn_args.as_const(eval_ctx))
571 except Exception:
572 raise Impossible()
573 if self.dyn_kwargs is not None:
574 try:
575 kwargs.update(self.dyn_kwargs.as_const(eval_ctx))
576 except Exception:
577 raise Impossible()
578 try:
579 return filter_(obj, *args, **kwargs)
580 except Exception:
581 raise Impossible()
582
583
584 class Test(Expr):
585 """Applies a test on an expression. `name` is the name of the test, the
586 rest of the fields are the same as for :class:`Call`.
587 """
588 fields = ('node', 'name', 'args', 'kwargs', 'dyn_args', 'dyn_kwargs')
589
590
591 class Call(Expr):
592 """Calls an expression. `args` is a list of arguments, `kwargs` a list
593 of keyword arguments (list of :class:`Keyword` nodes), and `dyn_args`
594 and `dyn_kwargs` has to be either `None` or a node that is used as
595 node for dynamic positional (``*args``) or keyword (``**kwargs``)
596 arguments.
597 """
598 fields = ('node', 'args', 'kwargs', 'dyn_args', 'dyn_kwargs')
599
600 def as_const(self, eval_ctx=None):
601 eval_ctx = get_eval_context(self, eval_ctx)
602 if eval_ctx.volatile:
603 raise Impossible()
604 obj = self.node.as_const(eval_ctx)
605
606 # don't evaluate context functions
607 args = [x.as_const(eval_ctx) for x in self.args]
608 if isinstance(obj, _context_function_types):
609 if getattr(obj, 'contextfunction', False):
610 raise Impossible()
611 elif getattr(obj, 'evalcontextfunction', False):
612 args.insert(0, eval_ctx)
613 elif getattr(obj, 'environmentfunction', False):
614 args.insert(0, self.environment)
615
616 kwargs = dict(x.as_const(eval_ctx) for x in self.kwargs)
617 if self.dyn_args is not None:
618 try:
619 args.extend(self.dyn_args.as_const(eval_ctx))
620 except Exception:
621 raise Impossible()
622 if self.dyn_kwargs is not None:
623 try:
624 kwargs.update(self.dyn_kwargs.as_const(eval_ctx))
625 except Exception:
626 raise Impossible()
627 try:
628 return obj(*args, **kwargs)
629 except Exception:
630 raise Impossible()
631
632
633 class Getitem(Expr):
634 """Get an attribute or item from an expression and prefer the item."""
635 fields = ('node', 'arg', 'ctx')
636
637 def as_const(self, eval_ctx=None):
638 eval_ctx = get_eval_context(self, eval_ctx)
639 if self.ctx != 'load':
640 raise Impossible()
641 try:
642 return self.environment.getitem(self.node.as_const(eval_ctx),
643 self.arg.as_const(eval_ctx))
644 except Exception:
645 raise Impossible()
646
647 def can_assign(self):
648 return False
649
650
651 class Getattr(Expr):
652 """Get an attribute or item from an expression that is a ascii-only
653 bytestring and prefer the attribute.
654 """
655 fields = ('node', 'attr', 'ctx')
656
657 def as_const(self, eval_ctx=None):
658 if self.ctx != 'load':
659 raise Impossible()
660 try:
661 eval_ctx = get_eval_context(self, eval_ctx)
662 return self.environment.getattr(self.node.as_const(eval_ctx),
663 self.attr)
664 except Exception:
665 raise Impossible()
666
667 def can_assign(self):
668 return False
669
670
671 class Slice(Expr):
672 """Represents a slice object. This must only be used as argument for
673 :class:`Subscript`.
674 """
675 fields = ('start', 'stop', 'step')
676
677 def as_const(self, eval_ctx=None):
678 eval_ctx = get_eval_context(self, eval_ctx)
679 def const(obj):
680 if obj is None:
681 return None
682 return obj.as_const(eval_ctx)
683 return slice(const(self.start), const(self.stop), const(self.step))
684
685
686 class Concat(Expr):
687 """Concatenates the list of expressions provided after converting them to
688 unicode.
689 """
690 fields = ('nodes',)
691
692 def as_const(self, eval_ctx=None):
693 eval_ctx = get_eval_context(self, eval_ctx)
694 return ''.join(text_type(x.as_const(eval_ctx)) for x in self.nodes)
695
696
697 class Compare(Expr):
698 """Compares an expression with some other expressions. `ops` must be a
699 list of :class:`Operand`\s.
700 """
701 fields = ('expr', 'ops')
702
703 def as_const(self, eval_ctx=None):
704 eval_ctx = get_eval_context(self, eval_ctx)
705 result = value = self.expr.as_const(eval_ctx)
706 try:
707 for op in self.ops:
708 new_value = op.expr.as_const(eval_ctx)
709 result = _cmpop_to_func[op.op](value, new_value)
710 value = new_value
711 except Exception:
712 raise Impossible()
713 return result
714
715
716 class Operand(Helper):
717 """Holds an operator and an expression."""
718 fields = ('op', 'expr')
719
720 if __debug__:
721 Operand.__doc__ += '\nThe following operators are available: ' + \
722 ', '.join(sorted('``%s``' % x for x in set(_binop_to_func) |
723 set(_uaop_to_func) | set(_cmpop_to_func)))
724
725
726 class Mul(BinExpr):
727 """Multiplies the left with the right node."""
728 operator = '*'
729
730
731 class Div(BinExpr):
732 """Divides the left by the right node."""
733 operator = '/'
734
735
736 class FloorDiv(BinExpr):
737 """Divides the left by the right node and truncates conver the
738 result into an integer by truncating.
739 """
740 operator = '//'
741
742
743 class Add(BinExpr):
744 """Add the left to the right node."""
745 operator = '+'
746
747
748 class Sub(BinExpr):
749 """Substract the right from the left node."""
750 operator = '-'
751
752
753 class Mod(BinExpr):
754 """Left modulo right."""
755 operator = '%'
756
757
758 class Pow(BinExpr):
759 """Left to the power of right."""
760 operator = '**'
761
762
763 class And(BinExpr):
764 """Short circuited AND."""
765 operator = 'and'
766
767 def as_const(self, eval_ctx=None):
768 eval_ctx = get_eval_context(self, eval_ctx)
769 return self.left.as_const(eval_ctx) and self.right.as_const(eval_ctx)
770
771
772 class Or(BinExpr):
773 """Short circuited OR."""
774 operator = 'or'
775
776 def as_const(self, eval_ctx=None):
777 eval_ctx = get_eval_context(self, eval_ctx)
778 return self.left.as_const(eval_ctx) or self.right.as_const(eval_ctx)
779
780
781 class Not(UnaryExpr):
782 """Negate the expression."""
783 operator = 'not'
784
785
786 class Neg(UnaryExpr):
787 """Make the expression negative."""
788 operator = '-'
789
790
791 class Pos(UnaryExpr):
792 """Make the expression positive (noop for most expressions)"""
793 operator = '+'
794
795
796 # Helpers for extensions
797
798
799 class EnvironmentAttribute(Expr):
800 """Loads an attribute from the environment object. This is useful for
801 extensions that want to call a callback stored on the environment.
802 """
803 fields = ('name',)
804
805
806 class ExtensionAttribute(Expr):
807 """Returns the attribute of an extension bound to the environment.
808 The identifier is the identifier of the :class:`Extension`.
809
810 This node is usually constructed by calling the
811 :meth:`~jinja2.ext.Extension.attr` method on an extension.
812 """
813 fields = ('identifier', 'name')
814
815
816 class ImportedName(Expr):
817 """If created with an import name the import name is returned on node
818 access. For example ``ImportedName('cgi.escape')`` returns the `escape`
819 function from the cgi module on evaluation. Imports are optimized by the
820 compiler so there is no need to assign them to local variables.
821 """
822 fields = ('importname',)
823
824
825 class InternalName(Expr):
826 """An internal name in the compiler. You cannot create these nodes
827 yourself but the parser provides a
828 :meth:`~jinja2.parser.Parser.free_identifier` method that creates
829 a new identifier for you. This identifier is not available from the
830 template and is not threated specially by the compiler.
831 """
832 fields = ('name',)
833
834 def __init__(self):
835 raise TypeError('Can\'t create internal names. Use the '
836 '`free_identifier` method on a parser.')
837
838
839 class MarkSafe(Expr):
840 """Mark the wrapped expression as safe (wrap it as `Markup`)."""
841 fields = ('expr',)
842
843 def as_const(self, eval_ctx=None):
844 eval_ctx = get_eval_context(self, eval_ctx)
845 return Markup(self.expr.as_const(eval_ctx))
846
847
848 class MarkSafeIfAutoescape(Expr):
849 """Mark the wrapped expression as safe (wrap it as `Markup`) but
850 only if autoescaping is active.
851
852 .. versionadded:: 2.5
853 """
854 fields = ('expr',)
855
856 def as_const(self, eval_ctx=None):
857 eval_ctx = get_eval_context(self, eval_ctx)
858 if eval_ctx.volatile:
859 raise Impossible()
860 expr = self.expr.as_const(eval_ctx)
861 if eval_ctx.autoescape:
862 return Markup(expr)
863 return expr
864
865
866 class ContextReference(Expr):
867 """Returns the current template context. It can be used like a
868 :class:`Name` node, with a ``'load'`` ctx and will return the
869 current :class:`~jinja2.runtime.Context` object.
870
871 Here an example that assigns the current template name to a
872 variable named `foo`::
873
874 Assign(Name('foo', ctx='store'),
875 Getattr(ContextReference(), 'name'))
876 """
877
878
879 class Continue(Stmt):
880 """Continue a loop."""
881
882
883 class Break(Stmt):
884 """Break a loop."""
885
886
887 class Scope(Stmt):
888 """An artificial scope."""
889 fields = ('body',)
890
891
892 class EvalContextModifier(Stmt):
893 """Modifies the eval context. For each option that should be modified,
894 a :class:`Keyword` has to be added to the :attr:`options` list.
895
896 Example to change the `autoescape` setting::
897
898 EvalContextModifier(options=[Keyword('autoescape', Const(True))])
899 """
900 fields = ('options',)
901
902
903 class ScopedEvalContextModifier(EvalContextModifier):
904 """Modifies the eval context and reverts it later. Works exactly like
905 :class:`EvalContextModifier` but will only modify the
906 :class:`~jinja2.nodes.EvalContext` for nodes in the :attr:`body`.
907 """
908 fields = ('body',)
909
910
911 # make sure nobody creates custom nodes
912 def _failing_new(*args, **kwargs):
913 raise TypeError('can\'t create custom node types')
914 NodeType.__new__ = staticmethod(_failing_new); del _failing_new
OLDNEW
« no previous file with comments | « mojo/public/third_party/jinja2/meta.py ('k') | mojo/public/third_party/jinja2/optimizer.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698