# the expression pointing to the parent loop. We make the
# undefined a bit more debug friendly at the same time.
parent_loop = 'loop' in aliases and aliases['loop'] \
- or "environment.undefined('loop', extra=%r)" % \
+ or "environment.undefined(%r)" % "'loop' is undefined. " \
'the filter section of a loop as well as the ' \
'else block doesn\'t have access to the special ' \
"'loop' variable of the current loop. Because " \
self.writeline('continue')
self.outdent(2)
- self.blockvisit(node.body, loop_frame, force_generator=False)
+ self.blockvisit(node.body, loop_frame, force_generator=True)
if node.else_:
self.writeline('if l_loop is None:')
except ImportError:
itemgetter = lambda a: lambda b: b[a]
from urllib import urlencode, quote
-from itertools import imap
+from itertools import imap, groupby
from jinja2.utils import Markup, escape, pformat, urlize, soft_unicode
from jinja2.runtime import Undefined
result = []
for key, value in d.iteritems():
if value is not None and not isinstance(value, Undefined):
- result.append(u'%s="%s"' % (
- escape(env.to_unicode(key)),
- escape(env.to_unicode(value), True)
- ))
+ result.append(u'%s="%s"' % (escape(key), escape(value)))
rv = u' '.join(
u'%s="%s"' % (escape(key), escape(value))
for key, value in d.iteritems()
try:
return int(value)
except (TypeError, ValueError):
- return default
+ try:
+ return int(float(value))
+ except (TypeError, ValueError):
+ return default
def do_float(value, default=0.0):
return default
-def do_string(value):
- """Convert the value into an string."""
- return soft_unicode(value)
-
-
def do_format(value, *args, **kwargs):
"""
Apply python string formatting on an object:
If you pass it a second argument it's used to fill missing
values on the last iteration.
"""
- seq = list(seq)
+ seq = list(value)
length = len(seq)
items_per_slice = length // slices
slices_with_extra = length % slices
'wordcount': do_wordcount,
'int': do_int,
'float': do_float,
- 'string': do_string,
+ 'string': soft_unicode,
+ 'list': list,
'urlize': do_urlize,
'format': do_format,
'trim': do_trim,
value = self.parse_expression()
items.append(nodes.Pair(key, value, lineno=key.lineno))
self.stream.expect('rbrace')
- return nodes.Dict(items, token.lineno, self.filename)
+ return nodes.Dict(items, lineno=token.lineno)
def parse_postfix(self, node):
while 1:
from itertools import imap
+_word_split_re = re.compile(r'(\s+)')
+_punctuation_re = re.compile(
+ '^(?P<lead>(?:%s)*)(?P<middle>.*?)(?P<trail>(?:%s)*)$' % (
+ '|'.join(imap(re.escape, ('(', '<', '<'))),
+ '|'.join(imap(re.escape, ('.', ',', ')', '>', '\n', '>')))
+ )
+)
+_simple_email_re = re.compile(r'^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$')
+
+
def soft_unicode(s):
"""Make a string unicode if it isn't already. That way a markup
string is not converted back to unicode.
def pformat(obj, verbose=False):
- """
- Prettyprint an object. Either use the `pretty` library or the
+ """Prettyprint an object. Either use the `pretty` library or the
builtin `pprint`.
"""
try:
return pformat(obj)
-_word_split_re = re.compile(r'(\s+)')
-
-_punctuation_re = re.compile(
- '^(?P<lead>(?:%s)*)(?P<middle>.*?)(?P<trail>(?:%s)*)$' % (
- '|'.join(imap(re.escape, ('(', '<', '<'))),
- '|'.join(imap(re.escape, ('.', ',', ')', '>', '\n', '>')))
- )
-)
-
-_simple_email_re = re.compile(r'^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$')
-
-
def urlize(text, trim_url_limit=None, nofollow=False):
- """
- Converts any URLs in text into clickable links. Works on http://,
+ """Converts any URLs in text into clickable links. Works on http://,
https:// and www. links. Links can have trailing punctuation (periods,
commas, close-parens) and leading punctuation (opening parens) and
it'll still do the right thing.
def copy(self):
"""Return an shallow copy of the instance."""
- rv = LRUCache(self.capacity)
+ rv = self.__class__(self.capacity)
rv._mapping.update(self._mapping)
- rv._queue = self._queue[:]
+ rv._queue = deque(self._queue)
return rv
def get(self, key, default=None):
return default
def setdefault(self, key, default=None):
- """
- Set `default` if the key is not in the cache otherwise
+ """Set `default` if the key is not in the cache otherwise
leave unchanged. Return the value of this key.
"""
if key in self:
__copy__ = copy
- def __deepcopy__(self):
- """Return a deep copy of the LRU Cache"""
- rv = LRUCache(self.capacity)
- rv._mapping = deepcopy(self._mapping)
- rv._queue = deepcopy(self._queue)
- return rv
-
# we have to import it down here as the speedups module imports the
# markup type which is define above.
DICTSORT = '''{{ foo|dictsort }}|\
{{ foo|dictsort(true) }}|\
{{ foo|dictsort(false, 'value') }}'''
-BATCH = '''{{ foo|batch(3) }}|{{ foo|batch(3, 'X') }}'''
-SLICE = '''{{ foo|slice(3) }}|{{ foo|slice(3, 'X') }}'''
-ESCAPE = '''{{ '<">&'|escape }}|{{ '<">&'|escape(true) }}'''
+BATCH = '''{{ foo|batch(3)|list }}|{{ foo|batch(3, 'X')|list }}'''
+SLICE = '''{{ foo|slice(3)|list }}|{{ foo|slice(3, 'X')|list }}'''
+ESCAPE = '''{{ '<">&'|escape }}'''
STRIPTAGS = '''{{ foo|striptags }}'''
FILESIZEFORMAT = '{{ 100|filesizeformat }}|\
{{ 1000|filesizeformat }}|\
LOWER = '''{{ "FOO"|lower }}'''
PPRINT = '''{{ data|pprint }}'''
RANDOM = '''{{ seq|random }}'''
-REVERSE = '''{{ "foobar"|reverse }}|{{ [1, 2, 3]|reverse }}'''
+REVERSE = '''{{ "foobar"|reverse|join }}|{{ [1, 2, 3]|reverse|list }}'''
STRING = '''{{ range(10)|string }}'''
TITLE = '''{{ "foo bar"|title }}'''
TRIM = '''{{ " foo "|trim }}'''
def test_escape(env):
tmpl = env.from_string(ESCAPE)
out = tmpl.render()
- assert out == '<">&|<">&'
+ assert out == '<">&'
def test_striptags(env):
DEFINED = '''{{ missing is defined }}|{{ true is defined }}'''
EVEN = '''{{ 1 is even }}|{{ 2 is even }}'''
LOWER = '''{{ "foo" is lower }}|{{ "FOO" is lower }}'''
-MATCHING = '''{{ "42" is matching('^\\d+$') }}|\
-{{ "foo" is matching('^\\d+$') }}|\
-{{ "foo bar" is matching @/^foo\\s+BAR$/i }}'''
NUMERIC = '''{{ "43" is numeric }}|{{ "foo" is numeric }}|\
{{ 42 is numeric }}'''
ODD = '''{{ 1 is odd }}|{{ 2 is odd }}'''
assert tmpl.render() == 'True|False'
-def test_matching(env):
- tmpl = env.from_string(MATCHING)
- assert tmpl.render() == 'True|False|True'
-
-
def test_numeric(env):
tmpl = env.from_string(NUMERIC)
assert tmpl.render() == 'True|False|True'