__all__ = ['e', 't', 'p', 'l', 'm']
+
+_global_frame = sys._getframe()
e = Environment()
t = e.from_string
-if os.environ.get('JDEBUG_SOURCEPRINT'):
- original_translate = PythonTranslator.translate
-
- def debug_translate(self):
- rv = original_translate(self)
- sys.stderr.write('## GENERATED SOURCE:\n%s\n' % rv)
- return rv
-
- PythonTranslator.translate = debug_translate
-
-
def p(x=None, f=None):
if x is None and f is not None:
x = e.loader.get_source(f)
def freeze(self):
self.clear()
- self.update()
-
- def update(self):
- self.guarded_objects.clear()
for obj in gc.get_objects():
self.guarded_objects[id(obj)] = True
def get_delta(self):
+ frm = sys._getframe()
result = []
for obj in gc.get_objects():
- if id(obj) not in self.guarded_objects:
+ if id(obj) not in self.guarded_objects and \
+ obj is not frm and obj is not result:
result.append(obj)
return result
return assemble_list()
+ def sanitize_tree(self, body, extends):
+ self._sanitize_tree([body], [body], extends, body)
+ return body
+
+ def _sanitize_tree(self, nodelist, stack, extends, body):
+ """
+ This is not a closure because python leaks memory if it is. It's used
+ by `parse()` to make sure blocks do not trigger unexpected behavior.
+ """
+ for node in nodelist:
+ if extends is not None and \
+ node.__class__ is nodes.Block and \
+ stack[-1] is not body:
+ for n in stack:
+ if n.__class__ is nodes.Block:
+ break
+ else:
+ raise TemplateSyntaxError('misplaced block %r, '
+ 'blocks in child '
+ 'templates must be '
+ 'either top level or '
+ 'located in a block '
+ 'tag.' % node.name,
+ node.lineno,
+ self.filename)
+ stack.append(node)
+ self._sanitize_tree(node.get_child_nodes(), stack, extends, body)
+ stack.pop()
+
def parse(self):
"""
Parse the template and return a Template node. This also does some
if leading_whitespace:
self.stream.shift(leading_whitespace)
- body = self.subparse(None)
- def walk(nodelist, stack):
- for node in nodelist:
- if extends is not None and \
- node.__class__ is nodes.Block and \
- stack[-1] is not body:
- for n in stack:
- if n.__class__ is nodes.Block:
- break
- else:
- raise TemplateSyntaxError('misplaced block %r, '
- 'blocks in child '
- 'templates must be '
- 'either top level or '
- 'located in a block '
- 'tag.' % node.name,
- node.lineno,
- self.filename)
- stack.append(node)
- walk(node.get_child_nodes(), stack)
- stack.pop()
- walk([body], [body])
+ body = self.sanitize_tree(self.subparse(None), extends)
return nodes.Template(extends, body, 1, self.filename)
finally:
self.close()