Made it possible to refer to names from outer scopes in included templates
that were unused in the callers frame (#327).
--HG--
branch : trunk
diff --git a/jinja2/compiler.py b/jinja2/compiler.py
index 8d605c7..b6bf2eb 100644
--- a/jinja2/compiler.py
+++ b/jinja2/compiler.py
@@ -520,6 +520,16 @@
self.writeline('%s = environment.%s[%r]' %
(mapping[name], dependency, name))
+ def unoptimize_scope(self, frame):
+ """Disable Python optimizations for the frame."""
+ # XXX: this is not that nice but it has no real overhead. It
+ # mainly works because python finds the locals before dead code
+ # is removed. If that breaks we have to add a dummy function
+ # that just accepts the arguments and does nothing.
+ if frame.identifiers.declared:
+ self.writeline('if 0: dummy(%s)' % ', '.join(
+ 'l_' + name for name in frame.identifiers.declared))
+
def push_scope(self, frame, extra_vars=()):
"""This function returns all the shadowed variables in a dict
in the form name: alias and will write the required assignments
@@ -821,6 +831,8 @@
def visit_Include(self, node, frame):
"""Handles includes."""
+ if node.with_context:
+ self.unoptimize_scope(frame)
if node.ignore_missing:
self.writeline('try:')
self.indent()
@@ -852,6 +864,8 @@
def visit_Import(self, node, frame):
"""Visit regular imports."""
+ if node.with_context:
+ self.unoptimize_scope(frame)
self.writeline('l_%s = ' % node.target, node)
if frame.toplevel:
self.write('context.vars[%r] = ' % node.target)