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

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

Issue 23506004: Update Jinja2 (Python template library) to 2.7.1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 7 years, 3 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/bccache.py ('k') | third_party/jinja2/debug.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 """ 2 """
3 jinja2.compiler 3 jinja2.compiler
4 ~~~~~~~~~~~~~~~ 4 ~~~~~~~~~~~~~~~
5 5
6 Compiles nodes into python code. 6 Compiles nodes into python code.
7 7
8 :copyright: (c) 2010 by the Jinja Team. 8 :copyright: (c) 2010 by the Jinja Team.
9 :license: BSD, see LICENSE for more details. 9 :license: BSD, see LICENSE for more details.
10 """ 10 """
11 from cStringIO import StringIO
12 from itertools import chain 11 from itertools import chain
13 from copy import deepcopy 12 from copy import deepcopy
13 from keyword import iskeyword as is_python_keyword
14 from jinja2 import nodes 14 from jinja2 import nodes
15 from jinja2.nodes import EvalContext 15 from jinja2.nodes import EvalContext
16 from jinja2.visitor import NodeVisitor 16 from jinja2.visitor import NodeVisitor
17 from jinja2.exceptions import TemplateAssertionError 17 from jinja2.exceptions import TemplateAssertionError
18 from jinja2.utils import Markup, concat, escape, is_python_keyword, next 18 from jinja2.utils import Markup, concat, escape
19 from jinja2._compat import range_type, next, text_type, string_types, \
20 iteritems, NativeStringIO, imap
19 21
20 22
21 operators = { 23 operators = {
22 'eq': '==', 24 'eq': '==',
23 'ne': '!=', 25 'ne': '!=',
24 'gt': '>', 26 'gt': '>',
25 'gteq': '>=', 27 'gteq': '>=',
26 'lt': '<', 28 'lt': '<',
27 'lteq': '<=', 29 'lteq': '<=',
28 'in': 'in', 30 'in': 'in',
29 'notin': 'not in' 31 'notin': 'not in'
30 } 32 }
31 33
32 try:
33 exec '(0 if 0 else 0)'
34 except SyntaxError:
35 have_condexpr = False
36 else:
37 have_condexpr = True
38
39
40 # what method to iterate over items do we want to use for dict iteration 34 # what method to iterate over items do we want to use for dict iteration
41 # in generated code? on 2.x let's go with iteritems, on 3.x with items 35 # in generated code? on 2.x let's go with iteritems, on 3.x with items
42 if hasattr(dict, 'iteritems'): 36 if hasattr(dict, 'iteritems'):
43 dict_item_iter = 'iteritems' 37 dict_item_iter = 'iteritems'
44 else: 38 else:
45 dict_item_iter = 'items' 39 dict_item_iter = 'items'
46 40
47 41
48 # does if 0: dummy(x) get us x into the scope? 42 # does if 0: dummy(x) get us x into the scope?
49 def unoptimize_before_dead_code(): 43 def unoptimize_before_dead_code():
50 x = 42 44 x = 42
51 def f(): 45 def f():
52 if 0: dummy(x) 46 if 0: dummy(x)
53 return f 47 return f
54 unoptimize_before_dead_code = bool(unoptimize_before_dead_code().func_closure) 48
49 # The getattr is necessary for pypy which does not set this attribute if
50 # no closure is on the function
51 unoptimize_before_dead_code = bool(
52 getattr(unoptimize_before_dead_code(), '__closure__', None))
55 53
56 54
57 def generate(node, environment, name, filename, stream=None, 55 def generate(node, environment, name, filename, stream=None,
58 defer_init=False): 56 defer_init=False):
59 """Generate the python source for a node tree.""" 57 """Generate the python source for a node tree."""
60 if not isinstance(node, nodes.Template): 58 if not isinstance(node, nodes.Template):
61 raise TypeError('Can\'t compile non template nodes') 59 raise TypeError('Can\'t compile non template nodes')
62 generator = CodeGenerator(environment, name, filename, stream, defer_init) 60 generator = CodeGenerator(environment, name, filename, stream, defer_init)
63 generator.visit(node) 61 generator.visit(node)
64 if stream is None: 62 if stream is None:
65 return generator.stream.getvalue() 63 return generator.stream.getvalue()
66 64
67 65
68 def has_safe_repr(value): 66 def has_safe_repr(value):
69 """Does the node have a safe representation?""" 67 """Does the node have a safe representation?"""
70 if value is None or value is NotImplemented or value is Ellipsis: 68 if value is None or value is NotImplemented or value is Ellipsis:
71 return True 69 return True
72 if isinstance(value, (bool, int, long, float, complex, basestring, 70 if isinstance(value, (bool, int, float, complex, range_type,
73 xrange, Markup)): 71 Markup) + string_types):
74 return True 72 return True
75 if isinstance(value, (tuple, list, set, frozenset)): 73 if isinstance(value, (tuple, list, set, frozenset)):
76 for item in value: 74 for item in value:
77 if not has_safe_repr(item): 75 if not has_safe_repr(item):
78 return False 76 return False
79 return True 77 return True
80 elif isinstance(value, dict): 78 elif isinstance(value, dict):
81 for key, value in value.iteritems(): 79 for key, value in iteritems(value):
82 if not has_safe_repr(key): 80 if not has_safe_repr(key):
83 return False 81 return False
84 if not has_safe_repr(value): 82 if not has_safe_repr(value):
85 return False 83 return False
86 return True 84 return True
87 return False 85 return False
88 86
89 87
90 def find_undeclared(nodes, names): 88 def find_undeclared(nodes, names):
91 """Check if the names passed are accessed undeclared. The return value 89 """Check if the names passed are accessed undeclared. The return value
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 doesn't make sense to further process the code. Any block that 359 doesn't make sense to further process the code. Any block that
362 raises such an exception is not further processed. 360 raises such an exception is not further processed.
363 """ 361 """
364 362
365 363
366 class CodeGenerator(NodeVisitor): 364 class CodeGenerator(NodeVisitor):
367 365
368 def __init__(self, environment, name, filename, stream=None, 366 def __init__(self, environment, name, filename, stream=None,
369 defer_init=False): 367 defer_init=False):
370 if stream is None: 368 if stream is None:
371 stream = StringIO() 369 stream = NativeStringIO()
372 self.environment = environment 370 self.environment = environment
373 self.name = name 371 self.name = name
374 self.filename = filename 372 self.filename = filename
375 self.stream = stream 373 self.stream = stream
376 self.created_block_context = False 374 self.created_block_context = False
377 self.defer_init = defer_init 375 self.defer_init = defer_init
378 376
379 # aliases for imports 377 # aliases for imports
380 self.import_aliases = {} 378 self.import_aliases = {}
381 379
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 533
536 for arg in node.args: 534 for arg in node.args:
537 self.write(', ') 535 self.write(', ')
538 self.visit(arg, frame) 536 self.visit(arg, frame)
539 537
540 if not kwarg_workaround: 538 if not kwarg_workaround:
541 for kwarg in node.kwargs: 539 for kwarg in node.kwargs:
542 self.write(', ') 540 self.write(', ')
543 self.visit(kwarg, frame) 541 self.visit(kwarg, frame)
544 if extra_kwargs is not None: 542 if extra_kwargs is not None:
545 for key, value in extra_kwargs.iteritems(): 543 for key, value in iteritems(extra_kwargs):
546 self.write(', %s=%s' % (key, value)) 544 self.write(', %s=%s' % (key, value))
547 if node.dyn_args: 545 if node.dyn_args:
548 self.write(', *') 546 self.write(', *')
549 self.visit(node.dyn_args, frame) 547 self.visit(node.dyn_args, frame)
550 548
551 if kwarg_workaround: 549 if kwarg_workaround:
552 if node.dyn_kwargs is not None: 550 if node.dyn_kwargs is not None:
553 self.write(', **dict({') 551 self.write(', **dict({')
554 else: 552 else:
555 self.write(', **{') 553 self.write(', **{')
556 for kwarg in node.kwargs: 554 for kwarg in node.kwargs:
557 self.write('%r: ' % kwarg.key) 555 self.write('%r: ' % kwarg.key)
558 self.visit(kwarg.value, frame) 556 self.visit(kwarg.value, frame)
559 self.write(', ') 557 self.write(', ')
560 if extra_kwargs is not None: 558 if extra_kwargs is not None:
561 for key, value in extra_kwargs.iteritems(): 559 for key, value in iteritems(extra_kwargs):
562 self.write('%r: %s, ' % (key, value)) 560 self.write('%r: %s, ' % (key, value))
563 if node.dyn_kwargs is not None: 561 if node.dyn_kwargs is not None:
564 self.write('}, **') 562 self.write('}, **')
565 self.visit(node.dyn_kwargs, frame) 563 self.visit(node.dyn_kwargs, frame)
566 self.write(')') 564 self.write(')')
567 else: 565 else:
568 self.write('}') 566 self.write('}')
569 567
570 elif node.dyn_kwargs is not None: 568 elif node.dyn_kwargs is not None:
571 self.write(', **') 569 self.write(', **')
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 to_declare = set() 616 to_declare = set()
619 for name in frame.identifiers.declared_locally: 617 for name in frame.identifiers.declared_locally:
620 if name not in aliases: 618 if name not in aliases:
621 to_declare.add('l_' + name) 619 to_declare.add('l_' + name)
622 if to_declare: 620 if to_declare:
623 self.writeline(' = '.join(to_declare) + ' = missing') 621 self.writeline(' = '.join(to_declare) + ' = missing')
624 return aliases 622 return aliases
625 623
626 def pop_scope(self, aliases, frame): 624 def pop_scope(self, aliases, frame):
627 """Restore all aliases and delete unused variables.""" 625 """Restore all aliases and delete unused variables."""
628 for name, alias in aliases.iteritems(): 626 for name, alias in iteritems(aliases):
629 self.writeline('l_%s = %s' % (name, alias)) 627 self.writeline('l_%s = %s' % (name, alias))
630 to_delete = set() 628 to_delete = set()
631 for name in frame.identifiers.declared_locally: 629 for name in frame.identifiers.declared_locally:
632 if name not in aliases: 630 if name not in aliases:
633 to_delete.add('l_' + name) 631 to_delete.add('l_' + name)
634 if to_delete: 632 if to_delete:
635 # we cannot use the del statement here because enclosed 633 # we cannot use the del statement here because enclosed
636 # scopes can trigger a SyntaxError: 634 # scopes can trigger a SyntaxError:
637 # a = 42; b = lambda: a; del a 635 # a = 42; b = lambda: a; del a
638 self.writeline(' = '.join(to_delete) + ' = missing') 636 self.writeline(' = '.join(to_delete) + ' = missing')
(...skipping 17 matching lines...) Expand all
656 children = list(children) 654 children = list(children)
657 func_frame = frame.inner() 655 func_frame = frame.inner()
658 func_frame.inspect(children) 656 func_frame.inspect(children)
659 657
660 # variables that are undeclared (accessed before declaration) and 658 # variables that are undeclared (accessed before declaration) and
661 # declared locally *and* part of an outside scope raise a template 659 # declared locally *and* part of an outside scope raise a template
662 # assertion error. Reason: we can't generate reasonable code from 660 # assertion error. Reason: we can't generate reasonable code from
663 # it without aliasing all the variables. 661 # it without aliasing all the variables.
664 # this could be fixed in Python 3 where we have the nonlocal 662 # this could be fixed in Python 3 where we have the nonlocal
665 # keyword or if we switch to bytecode generation 663 # keyword or if we switch to bytecode generation
666 overriden_closure_vars = ( 664 overridden_closure_vars = (
667 func_frame.identifiers.undeclared & 665 func_frame.identifiers.undeclared &
668 func_frame.identifiers.declared & 666 func_frame.identifiers.declared &
669 (func_frame.identifiers.declared_locally | 667 (func_frame.identifiers.declared_locally |
670 func_frame.identifiers.declared_parameter) 668 func_frame.identifiers.declared_parameter)
671 ) 669 )
672 if overriden_closure_vars: 670 if overridden_closure_vars:
673 self.fail('It\'s not possible to set and access variables ' 671 self.fail('It\'s not possible to set and access variables '
674 'derived from an outer scope! (affects: %s)' % 672 'derived from an outer scope! (affects: %s)' %
675 ', '.join(sorted(overriden_closure_vars)), node.lineno) 673 ', '.join(sorted(overridden_closure_vars)), node.lineno)
676 674
677 # remove variables from a closure from the frame's undeclared 675 # remove variables from a closure from the frame's undeclared
678 # identifiers. 676 # identifiers.
679 func_frame.identifiers.undeclared -= ( 677 func_frame.identifiers.undeclared -= (
680 func_frame.identifiers.undeclared & 678 func_frame.identifiers.undeclared &
681 func_frame.identifiers.declared 679 func_frame.identifiers.declared
682 ) 680 )
683 681
684 # no special variables for this scope, abort early 682 # no special variables for this scope, abort early
685 if not find_special: 683 if not find_special:
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 self.indent() 818 self.indent()
821 self.writeline('if parent_template is not None:') 819 self.writeline('if parent_template is not None:')
822 self.indent() 820 self.indent()
823 self.writeline('for event in parent_template.' 821 self.writeline('for event in parent_template.'
824 'root_render_func(context):') 822 'root_render_func(context):')
825 self.indent() 823 self.indent()
826 self.writeline('yield event') 824 self.writeline('yield event')
827 self.outdent(2 + (not self.has_known_extends)) 825 self.outdent(2 + (not self.has_known_extends))
828 826
829 # at this point we now have the blocks collected and can visit them too. 827 # at this point we now have the blocks collected and can visit them too.
830 for name, block in self.blocks.iteritems(): 828 for name, block in iteritems(self.blocks):
831 block_frame = Frame(eval_ctx) 829 block_frame = Frame(eval_ctx)
832 block_frame.inspect(block.body) 830 block_frame.inspect(block.body)
833 block_frame.block = name 831 block_frame.block = name
834 self.writeline('def block_%s(context%s):' % (name, envenv), 832 self.writeline('def block_%s(context%s):' % (name, envenv),
835 block, 1) 833 block, 1)
836 self.indent() 834 self.indent()
837 undeclared = find_undeclared(block.body, ('self', 'super')) 835 undeclared = find_undeclared(block.body, ('self', 'super'))
838 if 'self' in undeclared: 836 if 'self' in undeclared:
839 block_frame.identifiers.add_special('self') 837 block_frame.identifiers.add_special('self')
840 self.writeline('l_self = TemplateReference(context)') 838 self.writeline('l_self = TemplateReference(context)')
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 885
888 # if we have a known extends we just add a template runtime 886 # if we have a known extends we just add a template runtime
889 # error into the generated code. We could catch that at compile 887 # error into the generated code. We could catch that at compile
890 # time too, but i welcome it not to confuse users by throwing the 888 # time too, but i welcome it not to confuse users by throwing the
891 # same error at different times just "because we can". 889 # same error at different times just "because we can".
892 if not self.has_known_extends: 890 if not self.has_known_extends:
893 self.writeline('if parent_template is not None:') 891 self.writeline('if parent_template is not None:')
894 self.indent() 892 self.indent()
895 self.writeline('raise TemplateRuntimeError(%r)' % 893 self.writeline('raise TemplateRuntimeError(%r)' %
896 'extended multiple times') 894 'extended multiple times')
897 self.outdent()
898 895
899 # if we have a known extends already we don't need that code here 896 # if we have a known extends already we don't need that code here
900 # as we know that the template execution will end here. 897 # as we know that the template execution will end here.
901 if self.has_known_extends: 898 if self.has_known_extends:
902 raise CompilerExit() 899 raise CompilerExit()
900 else:
901 self.outdent()
903 902
904 self.writeline('parent_template = environment.get_template(', node) 903 self.writeline('parent_template = environment.get_template(', node)
905 self.visit(node.template, frame) 904 self.visit(node.template, frame)
906 self.write(', %r)' % self.name) 905 self.write(', %r)' % self.name)
907 self.writeline('for name, parent_block in parent_template.' 906 self.writeline('for name, parent_block in parent_template.'
908 'blocks.%s():' % dict_item_iter) 907 'blocks.%s():' % dict_item_iter)
909 self.indent() 908 self.indent()
910 self.writeline('context.blocks.setdefault(name, []).' 909 self.writeline('context.blocks.setdefault(name, []).'
911 'append(parent_block)') 910 'append(parent_block)')
912 self.outdent() 911 self.outdent()
(...skipping 10 matching lines...) Expand all
923 def visit_Include(self, node, frame): 922 def visit_Include(self, node, frame):
924 """Handles includes.""" 923 """Handles includes."""
925 if node.with_context: 924 if node.with_context:
926 self.unoptimize_scope(frame) 925 self.unoptimize_scope(frame)
927 if node.ignore_missing: 926 if node.ignore_missing:
928 self.writeline('try:') 927 self.writeline('try:')
929 self.indent() 928 self.indent()
930 929
931 func_name = 'get_or_select_template' 930 func_name = 'get_or_select_template'
932 if isinstance(node.template, nodes.Const): 931 if isinstance(node.template, nodes.Const):
933 if isinstance(node.template.value, basestring): 932 if isinstance(node.template.value, string_types):
934 func_name = 'get_template' 933 func_name = 'get_template'
935 elif isinstance(node.template.value, (tuple, list)): 934 elif isinstance(node.template.value, (tuple, list)):
936 func_name = 'select_template' 935 func_name = 'select_template'
937 elif isinstance(node.template, (nodes.Tuple, nodes.List)): 936 elif isinstance(node.template, (nodes.Tuple, nodes.List)):
938 func_name = 'select_template' 937 func_name = 'select_template'
939 938
940 self.writeline('template = environment.%s(' % func_name, node) 939 self.writeline('template = environment.%s(' % func_name, node)
941 self.visit(node.template, frame) 940 self.visit(node.template, frame)
942 self.write(', %r)' % self.name) 941 self.write(', %r)' % self.name)
943 if node.ignore_missing: 942 if node.ignore_missing:
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1025 else: 1024 else:
1026 self.writeline('context.vars.update({%s})' % ', '.join( 1025 self.writeline('context.vars.update({%s})' % ', '.join(
1027 '%r: l_%s' % (name, name) for name in var_names 1026 '%r: l_%s' % (name, name) for name in var_names
1028 )) 1027 ))
1029 if discarded_names: 1028 if discarded_names:
1030 if len(discarded_names) == 1: 1029 if len(discarded_names) == 1:
1031 self.writeline('context.exported_vars.discard(%r)' % 1030 self.writeline('context.exported_vars.discard(%r)' %
1032 discarded_names[0]) 1031 discarded_names[0])
1033 else: 1032 else:
1034 self.writeline('context.exported_vars.difference_' 1033 self.writeline('context.exported_vars.difference_'
1035 'update((%s))' % ', '.join(map(repr, discarded_na mes))) 1034 'update((%s))' % ', '.join(imap(repr, discarded_n ames)))
1036 1035
1037 def visit_For(self, node, frame): 1036 def visit_For(self, node, frame):
1038 # when calculating the nodes for the inner frame we have to exclude 1037 # when calculating the nodes for the inner frame we have to exclude
1039 # the iterator contents from it 1038 # the iterator contents from it
1040 children = node.iter_child_nodes(exclude=('iter',)) 1039 children = node.iter_child_nodes(exclude=('iter',))
1041 if node.recursive: 1040 if node.recursive:
1042 loop_frame = self.function_scoping(node, frame, children, 1041 loop_frame = self.function_scoping(node, frame, children,
1043 find_special=False) 1042 find_special=False)
1044 else: 1043 else:
1045 loop_frame = frame.inner() 1044 loop_frame = frame.inner()
1046 loop_frame.inspect(children) 1045 loop_frame.inspect(children)
1047 1046
1048 # try to figure out if we have an extended loop. An extended loop 1047 # try to figure out if we have an extended loop. An extended loop
1049 # is necessary if the loop is in recursive mode if the special loop 1048 # is necessary if the loop is in recursive mode if the special loop
1050 # variable is accessed in the body. 1049 # variable is accessed in the body.
1051 extended_loop = node.recursive or 'loop' in \ 1050 extended_loop = node.recursive or 'loop' in \
1052 find_undeclared(node.iter_child_nodes( 1051 find_undeclared(node.iter_child_nodes(
1053 only=('body',)), ('loop',)) 1052 only=('body',)), ('loop',))
1054 1053
1055 # if we don't have an recursive loop we have to find the shadowed 1054 # if we don't have an recursive loop we have to find the shadowed
1056 # variables at that point. Because loops can be nested but the loop 1055 # variables at that point. Because loops can be nested but the loop
1057 # variable is a special one we have to enforce aliasing for it. 1056 # variable is a special one we have to enforce aliasing for it.
1058 if not node.recursive: 1057 if not node.recursive:
1059 aliases = self.push_scope(loop_frame, ('loop',)) 1058 aliases = self.push_scope(loop_frame, ('loop',))
1060 1059
1061 # otherwise we set up a buffer and add a function def 1060 # otherwise we set up a buffer and add a function def
1062 else: 1061 else:
1063 self.writeline('def loop(reciter, loop_render_func):', node) 1062 self.writeline('def loop(reciter, loop_render_func, depth=0):', node )
1064 self.indent() 1063 self.indent()
1065 self.buffer(loop_frame) 1064 self.buffer(loop_frame)
1066 aliases = {} 1065 aliases = {}
1067 1066
1068 # make sure the loop variable is a special one and raise a template 1067 # make sure the loop variable is a special one and raise a template
1069 # assertion error if a loop tries to write to loop 1068 # assertion error if a loop tries to write to loop
1070 if extended_loop: 1069 if extended_loop:
1070 self.writeline('l_loop = missing')
1071 loop_frame.identifiers.add_special('loop') 1071 loop_frame.identifiers.add_special('loop')
1072 for name in node.find_all(nodes.Name): 1072 for name in node.find_all(nodes.Name):
1073 if name.ctx == 'store' and name.name == 'loop': 1073 if name.ctx == 'store' and name.name == 'loop':
1074 self.fail('Can\'t assign to special loop variable ' 1074 self.fail('Can\'t assign to special loop variable '
1075 'in for-loop target', name.lineno) 1075 'in for-loop target', name.lineno)
1076 1076
1077 self.pull_locals(loop_frame) 1077 self.pull_locals(loop_frame)
1078 if node.else_: 1078 if node.else_:
1079 iteration_indicator = self.temporary_identifier() 1079 iteration_indicator = self.temporary_identifier()
1080 self.writeline('%s = 1' % iteration_indicator) 1080 self.writeline('%s = 1' % iteration_indicator)
(...skipping 30 matching lines...) Expand all
1111 test_frame = loop_frame.copy() 1111 test_frame = loop_frame.copy()
1112 self.visit(node.test, test_frame) 1112 self.visit(node.test, test_frame)
1113 self.write('))') 1113 self.write('))')
1114 1114
1115 elif node.recursive: 1115 elif node.recursive:
1116 self.write('reciter') 1116 self.write('reciter')
1117 else: 1117 else:
1118 self.visit(node.iter, loop_frame) 1118 self.visit(node.iter, loop_frame)
1119 1119
1120 if node.recursive: 1120 if node.recursive:
1121 self.write(', recurse=loop_render_func):') 1121 self.write(', loop_render_func, depth):')
1122 else: 1122 else:
1123 self.write(extended_loop and '):' or ':') 1123 self.write(extended_loop and '):' or ':')
1124 1124
1125 # tests in not extended loops become a continue 1125 # tests in not extended loops become a continue
1126 if not extended_loop and node.test is not None: 1126 if not extended_loop and node.test is not None:
1127 self.indent() 1127 self.indent()
1128 self.writeline('if not ') 1128 self.writeline('if not ')
1129 self.visit(node.test, loop_frame) 1129 self.visit(node.test, loop_frame)
1130 self.write(':') 1130 self.write(':')
1131 self.indent() 1131 self.indent()
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 self.newline(node) 1209 self.newline(node)
1210 self.visit(node.node, frame) 1210 self.visit(node.node, frame)
1211 1211
1212 def visit_Output(self, node, frame): 1212 def visit_Output(self, node, frame):
1213 # if we have a known extends statement, we don't output anything 1213 # if we have a known extends statement, we don't output anything
1214 # if we are in a require_output_check section 1214 # if we are in a require_output_check section
1215 if self.has_known_extends and frame.require_output_check: 1215 if self.has_known_extends and frame.require_output_check:
1216 return 1216 return
1217 1217
1218 if self.environment.finalize: 1218 if self.environment.finalize:
1219 finalize = lambda x: unicode(self.environment.finalize(x)) 1219 finalize = lambda x: text_type(self.environment.finalize(x))
1220 else: 1220 else:
1221 finalize = unicode 1221 finalize = text_type
1222 1222
1223 # if we are inside a frame that requires output checking, we do so 1223 # if we are inside a frame that requires output checking, we do so
1224 outdent_later = False 1224 outdent_later = False
1225 if frame.require_output_check: 1225 if frame.require_output_check:
1226 self.writeline('if parent_template is None:') 1226 self.writeline('if parent_template is None:')
1227 self.indent() 1227 self.indent()
1228 outdent_later = True 1228 outdent_later = True
1229 1229
1230 # try to evaluate as many chunks as possible into a static 1230 # try to evaluate as many chunks as possible into a static
1231 # string at compile time. 1231 # string at compile time.
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1360 if idx: 1360 if idx:
1361 self.write(', ') 1361 self.write(', ')
1362 self.write('%r: l_%s' % (name, name)) 1362 self.write('%r: l_%s' % (name, name))
1363 self.write('})') 1363 self.write('})')
1364 if public_names: 1364 if public_names:
1365 if len(public_names) == 1: 1365 if len(public_names) == 1:
1366 self.writeline('context.exported_vars.add(%r)' % 1366 self.writeline('context.exported_vars.add(%r)' %
1367 public_names[0]) 1367 public_names[0])
1368 else: 1368 else:
1369 self.writeline('context.exported_vars.update((%s))' % 1369 self.writeline('context.exported_vars.update((%s))' %
1370 ', '.join(map(repr, public_names))) 1370 ', '.join(imap(repr, public_names)))
1371 1371
1372 # -- Expression Visitors 1372 # -- Expression Visitors
1373 1373
1374 def visit_Name(self, node, frame): 1374 def visit_Name(self, node, frame):
1375 if node.ctx == 'store' and frame.toplevel: 1375 if node.ctx == 'store' and frame.toplevel:
1376 frame.toplevel_assignments.add(node.name) 1376 frame.toplevel_assignments.add(node.name)
1377 self.write('l_' + node.name) 1377 self.write('l_' + node.name)
1378 frame.assigned_names.add(node.name) 1378 frame.assigned_names.add(node.name)
1379 1379
1380 def visit_Const(self, node, frame): 1380 def visit_Const(self, node, frame):
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1548 self.write(')') 1548 self.write(')')
1549 1549
1550 def visit_CondExpr(self, node, frame): 1550 def visit_CondExpr(self, node, frame):
1551 def write_expr2(): 1551 def write_expr2():
1552 if node.expr2 is not None: 1552 if node.expr2 is not None:
1553 return self.visit(node.expr2, frame) 1553 return self.visit(node.expr2, frame)
1554 self.write('environment.undefined(%r)' % ('the inline if-' 1554 self.write('environment.undefined(%r)' % ('the inline if-'
1555 'expression on %s evaluated to false and ' 1555 'expression on %s evaluated to false and '
1556 'no else section was defined.' % self.position(node))) 1556 'no else section was defined.' % self.position(node)))
1557 1557
1558 if not have_condexpr: 1558 self.write('(')
1559 self.write('((') 1559 self.visit(node.expr1, frame)
1560 self.visit(node.test, frame) 1560 self.write(' if ')
1561 self.write(') and (') 1561 self.visit(node.test, frame)
1562 self.visit(node.expr1, frame) 1562 self.write(' else ')
1563 self.write(',) or (') 1563 write_expr2()
1564 write_expr2() 1564 self.write(')')
1565 self.write(',))[0]')
1566 else:
1567 self.write('(')
1568 self.visit(node.expr1, frame)
1569 self.write(' if ')
1570 self.visit(node.test, frame)
1571 self.write(' else ')
1572 write_expr2()
1573 self.write(')')
1574 1565
1575 def visit_Call(self, node, frame, forward_caller=False): 1566 def visit_Call(self, node, frame, forward_caller=False):
1576 if self.environment.sandboxed: 1567 if self.environment.sandboxed:
1577 self.write('environment.call(context, ') 1568 self.write('environment.call(context, ')
1578 else: 1569 else:
1579 self.write('context.call(') 1570 self.write('context.call(')
1580 self.visit(node.node, frame) 1571 self.visit(node.node, frame)
1581 extra_kwargs = forward_caller and {'caller': 'caller'} or None 1572 extra_kwargs = forward_caller and {'caller': 'caller'} or None
1582 self.signature(node, frame, extra_kwargs) 1573 self.signature(node, frame, extra_kwargs)
1583 self.write(')') 1574 self.write(')')
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1640 1631
1641 def visit_ScopedEvalContextModifier(self, node, frame): 1632 def visit_ScopedEvalContextModifier(self, node, frame):
1642 old_ctx_name = self.temporary_identifier() 1633 old_ctx_name = self.temporary_identifier()
1643 safed_ctx = frame.eval_ctx.save() 1634 safed_ctx = frame.eval_ctx.save()
1644 self.writeline('%s = context.eval_ctx.save()' % old_ctx_name) 1635 self.writeline('%s = context.eval_ctx.save()' % old_ctx_name)
1645 self.visit_EvalContextModifier(node, frame) 1636 self.visit_EvalContextModifier(node, frame)
1646 for child in node.body: 1637 for child in node.body:
1647 self.visit(child, frame) 1638 self.visit(child, frame)
1648 frame.eval_ctx.revert(safed_ctx) 1639 frame.eval_ctx.revert(safed_ctx)
1649 self.writeline('context.eval_ctx.revert(%s)' % old_ctx_name) 1640 self.writeline('context.eval_ctx.revert(%s)' % old_ctx_name)
OLDNEW
« no previous file with comments | « third_party/jinja2/bccache.py ('k') | third_party/jinja2/debug.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698