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

Side by Side Diff: third_party/jinja2/nodes.py

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

Powered by Google App Engine
This is Rietveld 408576698