Permalink
Browse files

small refactoring

--HG--
branch : trunk
  • Loading branch information...
mitsuhiko committed May 18, 2008
1 parent dd65ef4 commit ed1e0d4a8bbaa7b2b10a9c4a9ce14bc6ac3d3892
Showing with 85 additions and 60 deletions.
  1. +1 −2 examples/rwbench/rwbench.py
  2. +53 −51 jinja2/compiler.py
  3. +0 −1 jinja2/environment.py
  4. +8 −0 jinja2/nodes.py
  5. +23 −6 jinja2/runtime.py
@@ -41,8 +41,7 @@ def __init__(self, id):
self.title = generate_lorem_ipsum(1, False, 5, 10)
self.user = choice(users)
self.body = generate_lorem_ipsum()
- self.pub_date = datetime.utcfromtimestamp(randrange(1000000000,
- 2000000000))
+ self.pub_date = datetime.utcfromtimestamp(randrange(10 ** 9, 2 * 10 ** 9))
class User(object):
View
@@ -357,6 +357,19 @@ def temporary_identifier(self):
self._last_identifier += 1
return 't%d' % self._last_identifier
+ def buffer(self, frame):
+ """Enable buffering for the frame from that point onwards."""
+ frame.buffer = buf = self.temporary_identifier()
+ self.writeline('%s = []' % buf)
+ return buf
+
+ def return_buffer_contents(self, frame):
+ """Return the buffer contents of the frame."""
+ if self.environment.autoescape:
+ self.writeline('return Markup(concat(%s))' % frame.buffer)
+ else:
+ self.writeline('return concat(%s)' % frame.buffer)
+
def indent(self):
"""Indent by one."""
self._indentation += 1
@@ -748,7 +761,7 @@ def visit_Include(self, node, frame):
if frame.buffer is None:
self.writeline('yield event')
else:
- self.writeline('%s.append(event)' % frame.buffer)
+ self.writeline('%s(event)' % frame.buffer)
self.outdent()
def visit_Import(self, node, frame):
@@ -839,10 +852,9 @@ def visit_For(self, node, frame):
# otherwise we set up a buffer and add a function def
else:
- loop_frame.buffer = buf = self.temporary_identifier()
self.writeline('def loop(reciter, loop_render_func):', node)
self.indent()
- self.writeline('%s = []' % buf, node)
+ self.buffer(loop_frame)
aliases = {}
self.pull_locals(loop_frame)
@@ -919,10 +931,7 @@ def visit_For(self, node, frame):
# if the node was recursive we have to return the buffer contents
# and start the iteration code
if node.recursive:
- if self.environment.autoescape:
- self.writeline('return Markup(concat(%s))' % buf)
- else:
- self.writeline('return concat(%s)' % buf)
+ self.return_buffer_contents(loop_frame)
self.outdent()
if frame.buffer is None:
self.writeline('yield loop(', node)
@@ -951,15 +960,11 @@ def visit_Macro(self, node, frame):
macro_frame = self.function_scoping(node, frame)
args = macro_frame.arguments
self.writeline('def macro(%s):' % ', '.join(args), node)
- macro_frame.buffer = buf = self.temporary_identifier()
self.indent()
+ self.buffer(macro_frame)
self.pull_locals(macro_frame)
- self.writeline('%s = []' % buf)
self.blockvisit(node.body, macro_frame)
- if self.environment.autoescape:
- self.writeline('return Markup(concat(%s))' % buf)
- else:
- self.writeline("return concat(%s)" % buf)
+ self.return_buffer_contents(macro_frame)
self.outdent()
self.newline()
if frame.toplevel:
@@ -985,15 +990,11 @@ def visit_CallBlock(self, node, frame):
(exclude=('call',)))
args = call_frame.arguments
self.writeline('def call(%s):' % ', '.join(args), node)
- call_frame.buffer = buf = self.temporary_identifier()
self.indent()
self.pull_locals(call_frame)
- self.writeline('%s = []' % buf)
+ self.buffer(call_frame)
self.blockvisit(node.body, call_frame)
- if self.environment.autoescape:
- self.writeline("return Markup(concat(%s))" % buf)
- else:
- self.writeline('return concat(%s)' % buf)
+ self.return_buffer_contents(call_frame)
self.outdent()
arg_tuple = ', '.join(repr(x.name) for x in node.args)
if len(node.args) == 1:
@@ -1022,17 +1023,17 @@ def visit_FilterBlock(self, node, frame):
aliases = self.collect_shadowed(filter_frame)
self.pull_locals(filter_frame)
- filter_frame.buffer = buf = self.temporary_identifier()
+ self.buffer(filter_frame)
- self.writeline('%s = []' % buf, node)
for child in node.body:
self.visit(child, filter_frame)
if frame.buffer is None:
self.writeline('yield ', node)
else:
self.writeline('%s.append(' % frame.buffer, node)
- self.visit_Filter(node.filter, filter_frame, 'concat(%s)' % buf)
+ self.visit_Filter(node.filter, filter_frame, 'concat(%s)'
+ % filter_frame.buffer)
if frame.buffer is not None:
self.write(')')
@@ -1070,9 +1071,8 @@ def visit_Output(self, node, frame):
else:
body.append([const])
- # if we have less than 3 nodes or less than 6 and a buffer we
- # yield or extend/append
- if len(body) < 3 or (frame.buffer is not None and len(body) < 6):
+ # if we have less than 3 nodes or a buffer we yield or extend/append
+ if len(body) < 3 or frame.buffer is not None:
if frame.buffer is not None:
# for one item we append, for more we extend
if len(body) == 1:
@@ -1089,7 +1089,7 @@ def visit_Output(self, node, frame):
self.writeline(val + ', ')
else:
if frame.buffer is None:
- self.writeline('yield ')
+ self.writeline('yield ', item)
else:
self.newline(item)
close = 1
@@ -1119,15 +1119,12 @@ def visit_Output(self, node, frame):
else:
format.append('%s')
arguments.append(item)
- if frame.buffer is None:
- self.writeline('yield ')
- else:
- self.writeline('%s.append(' % frame.buffer)
+ self.writeline('yield ')
self.write(repr(concat(format)) + ' % (')
idx = -1
self.indent()
for argument in arguments:
- self.newline()
+ self.newline(argument)
close = 0
if self.environment.autoescape:
self.write('escape(')
@@ -1139,8 +1136,6 @@ def visit_Output(self, node, frame):
self.write(')' * close + ', ')
self.outdent()
self.writeline(')')
- if frame.buffer is not None:
- self.write(')')
if outdent_later:
self.outdent()
@@ -1187,27 +1182,9 @@ def visit_Name(self, node, frame):
frame.assigned_names.add(node.name)
self.write('l_' + node.name)
- def visit_MarkSafe(self, node, frame):
- self.write('Markup(')
- self.visit(node.expr, frame)
- self.write(')')
-
- def visit_EnvironmentAttribute(self, node, frame):
- self.write('environment.' + node.name)
-
- def visit_ExtensionAttribute(self, node, frame):
- self.write('environment.extensions[%r].%s' % (node.identifier, node.attr))
-
- def visit_ImportedName(self, node, frame):
- self.write(self.import_aliases[node.importname])
-
- def visit_InternalName(self, node, frame):
- self.write(node.name)
-
def visit_Const(self, node, frame):
val = node.value
if isinstance(val, float):
- # XXX: add checks for infinity and nan
self.write(str(val))
else:
self.write(repr(val))
@@ -1372,3 +1349,28 @@ def visit_Call(self, node, frame, extra_kwargs=None):
def visit_Keyword(self, node, frame):
self.write(node.key + '=')
self.visit(node.value, frame)
+
+ # Unused nodes for extensions
+
+ def visit_MarkSafe(self, node, frame):
+ self.write('Markup(')
+ self.visit(node.expr, frame)
+ self.write(')')
+
+ def visit_EnvironmentAttribute(self, node, frame):
+ self.write('environment.' + node.name)
+
+ def visit_ExtensionAttribute(self, node, frame):
+ self.write('environment.extensions[%r].%s' % (node.identifier, node.attr))
+
+ def visit_ImportedName(self, node, frame):
+ self.write(self.import_aliases[node.importname])
+
+ def visit_InternalName(self, node, frame):
+ self.write(node.name)
+
+ def visit_Continue(self, node, frame):
+ self.writeline('continue', node)
+
+ def visit_Break(self, node, frame):
+ self.writeline('break', node)
View
@@ -337,7 +337,6 @@ def compile(self, source, name=None, filename=None, raw=False):
if self.optimized:
node = optimize(source, self)
source = generate(node, self, name, filename)
- #print source
if raw:
return source
if filename is None:
View
@@ -800,5 +800,13 @@ def as_const(self):
return Markup(self.expr.as_const())
+class Continue(Stmt):
+ """Continue a loop."""
+
+
+class Break(Stmt):
+ """Break a loop."""
+
+
# and close down
_node_setup_finished = True
View
@@ -185,7 +185,7 @@ def __init__(self, iterable, enforce_length=False, recurse=None):
len(self)
def cycle(self, *args):
- """A replacement for the old ``{% cycle %}`` tag."""
+ """Cycles among the arguments with the current loop index."""
if not args:
raise TypeError('no items for cycling given')
return args[self.index0 % len(args)]
@@ -200,7 +200,7 @@ def __len__(self):
return self.length
def __iter__(self):
- return self
+ return LoopContextIterator(self)
def loop(self, iterable):
if self._recurse is None:
@@ -212,16 +212,17 @@ def loop(self, iterable):
# the the loop without or with too many arguments.
__call__ = loop; del loop
- def next(self):
- self.index0 += 1
- return self._next(), self
-
@property
def length(self):
if self._length is None:
try:
+ # first try to get the length from the iterable (if the
+ # iterable is a sequence)
length = len(self._iterable)
except TypeError:
+ # if that's not possible (ie: iterating over a generator)
+ # we have to convert the iterable into a sequence and
+ # use the length of that.
self._iterable = tuple(self._iterable)
self._next = iter(self._iterable).next
length = len(tuple(self._iterable)) + self.index0 + 1
@@ -236,6 +237,22 @@ def __repr__(self):
)
+class LoopContextIterator(object):
+ """The iterator for a loop context."""
+ __slots__ = ('context',)
+
+ def __init__(self, context):
+ self.context = context
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ ctx = self.context
+ ctx.index0 += 1
+ return ctx._next(), ctx
+
+
class Macro(object):
"""Wraps a macro."""

0 comments on commit ed1e0d4

Please sign in to comment.