1b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# -*- coding: utf-8 -*-
2b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)"""
3b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    jinja2.utils
4b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ~~~~~~~~~~~~
5b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
6b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    Utility functions.
7b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
8b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    :copyright: (c) 2010 by the Jinja Team.
9b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    :license: BSD, see LICENSE for more details.
10b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)"""
11b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)import re
12b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)import sys
13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)import errno
14b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)try:
15b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from thread import allocate_lock
16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)except ImportError:
17b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from dummy_thread import allocate_lock
18b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)from collections import deque
19b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)from itertools import imap
20b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
21b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
22b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_word_split_re = re.compile(r'(\s+)')
23b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_punctuation_re = re.compile(
24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    '^(?P<lead>(?:%s)*)(?P<middle>.*?)(?P<trail>(?:%s)*)$' % (
25b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        '|'.join(imap(re.escape, ('(', '<', '&lt;'))),
26b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        '|'.join(imap(re.escape, ('.', ',', ')', '>', '\n', '&gt;')))
27b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    )
28b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles))
29b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_simple_email_re = re.compile(r'^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$')
30b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_striptags_re = re.compile(r'(<!--.*?-->|<[^>]*>)')
31b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_entity_re = re.compile(r'&([^;]+);')
32b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
33b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_digits = '0123456789'
34b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
35b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# special singleton representing missing values for the runtime
36b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)missing = type('MissingType', (), {'__repr__': lambda x: 'missing'})()
37b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# internal code
39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)internal_code = set()
40b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# concatenate a list of strings and convert them to unicode.
43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# unfortunately there is a bug in python 2.4 and lower that causes
44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# unicode.join trash the traceback.
45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_concat = u''.join
46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)try:
47b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def _test_gen_bug():
48b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        raise TypeError(_test_gen_bug)
49b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        yield None
50b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    _concat(_test_gen_bug())
51b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)except TypeError, _error:
52b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if not _error.args or _error.args[0] is not _test_gen_bug:
53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        def concat(gen):
54b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            try:
55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                return _concat(list(gen))
56b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            except Exception:
57b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                # this hack is needed so that the current frame
58b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                # does not show up in the traceback.
59b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                exc_type, exc_value, tb = sys.exc_info()
60b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                raise exc_type, exc_value, tb.tb_next
61b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    else:
62b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        concat = _concat
63b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    del _test_gen_bug, _error
64b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
65b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# for python 2.x we create outselves a next() function that does the
67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# basics without exception catching.
68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)try:
69b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    next = next
70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)except NameError:
71b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def next(x):
72b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return x.next()
73b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
74b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
75b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# if this python version is unable to deal with unicode filenames
76b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# when passed to encode we let this function encode it properly.
77b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# This is used in a couple of places.  As far as Jinja is concerned
78b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# filenames are unicode *or* bytestrings in 2.x and unicode only in
79b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# 3.x because compile cannot handle bytes
80b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)if sys.version_info < (3, 0):
81b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def _encode_filename(filename):
82b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if isinstance(filename, unicode):
83b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return filename.encode('utf-8')
84b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return filename
85b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)else:
86b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def _encode_filename(filename):
87b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        assert filename is None or isinstance(filename, str), \
88b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            'filenames must be strings'
89b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return filename
90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
91b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)from keyword import iskeyword as is_python_keyword
92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# common types.  These do exist in the special types module too which however
95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# does not exist in IronPython out of the box.  Also that way we don't have
96b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# to deal with implementation specific stuff here
97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class _C(object):
98b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def method(self): pass
99b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def _func():
100b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    yield None
101b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)FunctionType = type(_func)
102b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)GeneratorType = type(_func())
103b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)MethodType = type(_C.method)
104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)CodeType = type(_C.method.func_code)
105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)try:
106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    raise TypeError()
107b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)except TypeError:
108b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    _tb = sys.exc_info()[2]
109b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    TracebackType = type(_tb)
110b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    FrameType = type(_tb.tb_frame)
111b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)del _C, _tb, _func
112b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
113b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def contextfunction(f):
115b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """This decorator can be used to mark a function or method context callable.
116b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    A context callable is passed the active :class:`Context` as first argument when
117b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    called from the template.  This is useful if a function wants to get access
118b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    to the context or functions provided on the context object.  For example
119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    a function that returns a sorted list of template variables the current
120b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    template exports could look like this::
121b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
122b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        @contextfunction
123b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        def get_exported_names(context):
124b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return sorted(context.exported_vars)
125b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
126b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    f.contextfunction = True
127b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return f
128b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
129b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
130b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def evalcontextfunction(f):
131b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """This decoraotr can be used to mark a function or method as an eval
132b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    context callable.  This is similar to the :func:`contextfunction`
133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    but instead of passing the context, an evaluation context object is
134b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    passed.  For more information about the eval context, see
135b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    :ref:`eval-context`.
136b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
137b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    .. versionadded:: 2.4
138b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
139b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    f.evalcontextfunction = True
140b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return f
141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
142b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def environmentfunction(f):
144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """This decorator can be used to mark a function or method as environment
145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    callable.  This decorator works exactly like the :func:`contextfunction`
146b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    decorator just that the first argument is the active :class:`Environment`
147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    and not context.
148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
149b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    f.environmentfunction = True
150b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return f
151b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
152b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
153b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def internalcode(f):
154b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Marks the function as internally used"""
155b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    internal_code.add(f.func_code)
156b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return f
157b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
158b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
159b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def is_undefined(obj):
160b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Check if the object passed is undefined.  This does nothing more than
161b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    performing an instance check against :class:`Undefined` but looks nicer.
162b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    This can be used for custom filters or tests that want to react to
163b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    undefined variables.  For example a custom default filter can look like
164b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    this::
165b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
166b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        def default(var, default=''):
167b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if is_undefined(var):
168b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                return default
169b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return var
170b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
171b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from jinja2.runtime import Undefined
172b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return isinstance(obj, Undefined)
173b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
174b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
175b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def consume(iterable):
176b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Consumes an iterable without doing anything with it."""
177b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    for event in iterable:
178b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        pass
179b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
180b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
181b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def clear_caches():
182b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Jinja2 keeps internal caches for environments and lexers.  These are
183b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    used so that Jinja2 doesn't have to recreate environments and lexers all
184b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    the time.  Normally you don't have to care about that but if you are
185b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    messuring memory consumption you may want to clean the caches.
186b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
187b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from jinja2.environment import _spontaneous_environments
188b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from jinja2.lexer import _lexer_cache
189b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    _spontaneous_environments.clear()
190b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    _lexer_cache.clear()
191b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
192b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
193b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def import_string(import_name, silent=False):
194b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Imports an object based on a string.  This use useful if you want to
195b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    use import paths as endpoints or something similar.  An import path can
196b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    be specified either in dotted notation (``xml.sax.saxutils.escape``)
197b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    or with a colon as object delimiter (``xml.sax.saxutils:escape``).
198b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
199b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    If the `silent` is True the return value will be `None` if the import
200b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    fails.
201b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
202b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    :return: imported object
203b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
204b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    try:
205b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if ':' in import_name:
206b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            module, obj = import_name.split(':', 1)
207b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        elif '.' in import_name:
208b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            items = import_name.split('.')
209b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            module = '.'.join(items[:-1])
210b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            obj = items[-1]
211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        else:
212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return __import__(import_name)
213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return getattr(__import__(module, None, None, [obj]), obj)
214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    except (ImportError, AttributeError):
215b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if not silent:
216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            raise
217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
218b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
219b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def open_if_exists(filename, mode='rb'):
220b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Returns a file descriptor for the filename if that file exists,
221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    otherwise `None`.
222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    try:
224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return open(filename, mode)
225b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    except IOError, e:
226b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if e.errno not in (errno.ENOENT, errno.EISDIR):
227b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            raise
228b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
229b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
230b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def object_type_repr(obj):
231b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Returns the name of the object's type.  For some recognized
232b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    singletons the name of the object is returned instead. (For
233b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    example for `None` and `Ellipsis`).
234b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
235b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if obj is None:
236b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return 'None'
237b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    elif obj is Ellipsis:
238b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return 'Ellipsis'
239b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    # __builtin__ in 2.x, builtins in 3.x
240b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if obj.__class__.__module__ in ('__builtin__', 'builtins'):
241b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        name = obj.__class__.__name__
242b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    else:
243b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        name = obj.__class__.__module__ + '.' + obj.__class__.__name__
244b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return '%s object' % name
245b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
246b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
247b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def pformat(obj, verbose=False):
248b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Prettyprint an object.  Either use the `pretty` library or the
249b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    builtin `pprint`.
250b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
251b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    try:
252b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        from pretty import pretty
253b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return pretty(obj, verbose=verbose)
254b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    except ImportError:
255b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        from pprint import pformat
256b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return pformat(obj)
257b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
258b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
259b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def urlize(text, trim_url_limit=None, nofollow=False):
260b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Converts any URLs in text into clickable links. Works on http://,
261b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    https:// and www. links. Links can have trailing punctuation (periods,
262b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    commas, close-parens) and leading punctuation (opening parens) and
263b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    it'll still do the right thing.
264b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
265b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    If trim_url_limit is not None, the URLs in link text will be limited
266b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    to trim_url_limit characters.
267b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
268b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    If nofollow is True, the URLs in link text will get a rel="nofollow"
269b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    attribute.
270b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
271b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    trim_url = lambda x, limit=trim_url_limit: limit is not None \
272b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                         and (x[:limit] + (len(x) >=limit and '...'
273b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                         or '')) or x
274b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    words = _word_split_re.split(unicode(escape(text)))
275b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    nofollow_attr = nofollow and ' rel="nofollow"' or ''
276b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    for i, word in enumerate(words):
277b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        match = _punctuation_re.match(word)
278b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if match:
279b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            lead, middle, trail = match.groups()
280b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if middle.startswith('www.') or (
281b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                '@' not in middle and
282b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                not middle.startswith('http://') and
283b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                len(middle) > 0 and
284b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                middle[0] in _letters + _digits and (
285b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    middle.endswith('.org') or
286b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    middle.endswith('.net') or
287b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    middle.endswith('.com')
288b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                )):
289b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                middle = '<a href="http://%s"%s>%s</a>' % (middle,
290b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    nofollow_attr, trim_url(middle))
291b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if middle.startswith('http://') or \
292b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)               middle.startswith('https://'):
293b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                middle = '<a href="%s"%s>%s</a>' % (middle,
294b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    nofollow_attr, trim_url(middle))
295b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if '@' in middle and not middle.startswith('www.') and \
296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)               not ':' in middle and _simple_email_re.match(middle):
297b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                middle = '<a href="mailto:%s">%s</a>' % (middle, middle)
298b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if lead + middle + trail != word:
299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                words[i] = lead + middle + trail
300b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return u''.join(words)
301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
302b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def generate_lorem_ipsum(n=5, html=True, min=20, max=100):
304b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Generate some lorem impsum for the template."""
305b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from jinja2.constants import LOREM_IPSUM_WORDS
306b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from random import choice, randrange
307b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    words = LOREM_IPSUM_WORDS.split()
308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    result = []
309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
310b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    for _ in xrange(n):
311b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        next_capitalized = True
312b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        last_comma = last_fullstop = 0
313b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        word = None
314b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        last = None
315b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        p = []
316b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
317b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        # each paragraph contains out of 20 to 100 words.
318b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        for idx, _ in enumerate(xrange(randrange(min, max))):
319b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            while True:
320b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                word = choice(words)
321b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                if word != last:
322b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    last = word
323b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    break
324b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if next_capitalized:
325b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                word = word.capitalize()
326b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                next_capitalized = False
327b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            # add commas
328b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if idx - randrange(3, 8) > last_comma:
329b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                last_comma = idx
330b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                last_fullstop += 2
331b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                word += ','
332b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            # add end of sentences
333b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if idx - randrange(10, 20) > last_fullstop:
334b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                last_comma = last_fullstop = idx
335b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                word += '.'
336b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                next_capitalized = True
337b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            p.append(word)
338b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
339b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        # ensure that the paragraph ends with a dot.
340b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        p = u' '.join(p)
341b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if p.endswith(','):
342b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            p = p[:-1] + '.'
343b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        elif not p.endswith('.'):
344b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            p += '.'
345b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        result.append(p)
346b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
347b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if not html:
348b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return u'\n\n'.join(result)
349b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return Markup(u'\n'.join(u'<p>%s</p>' % escape(x) for x in result))
350b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
351b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
352b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class LRUCache(object):
353b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """A simple LRU Cache implementation."""
354b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
355b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    # this is fast for small capacities (something below 1000) but doesn't
356b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    # scale.  But as long as it's only used as storage for templates this
357b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    # won't do any harm.
358b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
359b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __init__(self, capacity):
360b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.capacity = capacity
361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._mapping = {}
362b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._queue = deque()
363b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._postinit()
364b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
365b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def _postinit(self):
366b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        # alias all queue methods for faster lookup
367b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._popleft = self._queue.popleft
368b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._pop = self._queue.pop
369b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if hasattr(self._queue, 'remove'):
370b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._remove = self._queue.remove
371b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._wlock = allocate_lock()
372b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._append = self._queue.append
373b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
374b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def _remove(self, obj):
375b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Python 2.4 compatibility."""
376b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        for idx, item in enumerate(self._queue):
377b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if item == obj:
378b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                del self._queue[idx]
379b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                break
380b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
381b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __getstate__(self):
382b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return {
383b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            'capacity':     self.capacity,
384b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            '_mapping':     self._mapping,
385b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            '_queue':       self._queue
386b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        }
387b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
388b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __setstate__(self, d):
389b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.__dict__.update(d)
390b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._postinit()
391b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
392b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __getnewargs__(self):
393b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return (self.capacity,)
394b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
395b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def copy(self):
396b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Return an shallow copy of the instance."""
397b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        rv = self.__class__(self.capacity)
398b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        rv._mapping.update(self._mapping)
399b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        rv._queue = deque(self._queue)
400b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return rv
401b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
402b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def get(self, key, default=None):
403b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Return an item from the cache dict or `default`"""
404b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        try:
405b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return self[key]
406b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        except KeyError:
407b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return default
408b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
409b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def setdefault(self, key, default=None):
410b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Set `default` if the key is not in the cache otherwise
411b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        leave unchanged. Return the value of this key.
412b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """
413b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        try:
414b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return self[key]
415b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        except KeyError:
416b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self[key] = default
417b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return default
418b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
419b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def clear(self):
420b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Clear the cache."""
421b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._wlock.acquire()
422b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        try:
423b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._mapping.clear()
424b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._queue.clear()
425b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        finally:
426b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._wlock.release()
427b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
428b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __contains__(self, key):
429b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Check if a key exists in this cache."""
430b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return key in self._mapping
431b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
432b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __len__(self):
433b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Return the current size of the cache."""
434b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return len(self._mapping)
435b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
436b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __repr__(self):
437b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return '<%s %r>' % (
438b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self.__class__.__name__,
439b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._mapping
440b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        )
441b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
442b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __getitem__(self, key):
443b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Get an item from the cache. Moves the item up so that it has the
444b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        highest priority then.
445b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
446b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        Raise an `KeyError` if it does not exist.
447b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """
448b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        rv = self._mapping[key]
449b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if self._queue[-1] != key:
450b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            try:
451b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                self._remove(key)
452b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            except ValueError:
453b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                # if something removed the key from the container
454b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                # when we read, ignore the ValueError that we would
455b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                # get otherwise.
456b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                pass
457b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._append(key)
458b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return rv
459b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
460b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __setitem__(self, key, value):
461b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Sets the value for an item. Moves the item up so that it
462b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        has the highest priority then.
463b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """
464b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._wlock.acquire()
465b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        try:
466b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if key in self._mapping:
467b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                try:
468b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    self._remove(key)
469b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                except ValueError:
470b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    # __getitem__ is not locked, it might happen
471b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    pass
472b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            elif len(self._mapping) == self.capacity:
473b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                del self._mapping[self._popleft()]
474b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._append(key)
475b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._mapping[key] = value
476b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        finally:
477b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._wlock.release()
478b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
479b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __delitem__(self, key):
480b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Remove an item from the cache dict.
481b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        Raise an `KeyError` if it does not exist.
482b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """
483b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._wlock.acquire()
484b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        try:
485b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            del self._mapping[key]
486b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            try:
487b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                self._remove(key)
488b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            except ValueError:
489b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                # __getitem__ is not locked, it might happen
490b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                pass
491b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        finally:
492b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._wlock.release()
493b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
494b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def items(self):
495b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Return a list of items."""
496b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        result = [(key, self._mapping[key]) for key in list(self._queue)]
497b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        result.reverse()
498b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return result
499b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
500b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def iteritems(self):
501b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Iterate over all items."""
502b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return iter(self.items())
503b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
504b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def values(self):
505b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Return a list of all values."""
506b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return [x[1] for x in self.items()]
507b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
508b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def itervalue(self):
509b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Iterate over all values."""
510b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return iter(self.values())
511b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
512b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def keys(self):
513b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Return a list of all keys ordered by most recent usage."""
514b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return list(self)
515b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
516b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def iterkeys(self):
517b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Iterate over all keys in the cache dict, ordered by
518b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        the most recent usage.
519b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """
520b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return reversed(tuple(self._queue))
521b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
522b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    __iter__ = iterkeys
523b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
524b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __reversed__(self):
525b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Iterate over the values in the cache dict, oldest items
526b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        coming first.
527b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """
528b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return iter(tuple(self._queue))
529b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
530b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    __copy__ = copy
531b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
532b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
533b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# register the LRU cache as mutable mapping if possible
534b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)try:
535b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from collections import MutableMapping
536b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    MutableMapping.register(LRUCache)
537b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)except ImportError:
538b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    pass
539b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
540b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
541b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class Cycler(object):
542b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """A cycle helper for templates."""
543b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
544b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __init__(self, *items):
545b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if not items:
546b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            raise RuntimeError('at least one item has to be provided')
547b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.items = items
548b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.reset()
549b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
550b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def reset(self):
551b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Resets the cycle."""
552b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.pos = 0
553b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
554b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    @property
555b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def current(self):
556b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Returns the current item."""
557b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return self.items[self.pos]
558b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
559b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def next(self):
560b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Goes one item ahead and returns it."""
561b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        rv = self.current
562b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.pos = (self.pos + 1) % len(self.items)
563b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return rv
564b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
565b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
566b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class Joiner(object):
567b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """A joining helper for templates."""
568b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
569b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __init__(self, sep=u', '):
570b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.sep = sep
571b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.used = False
572b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
573b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __call__(self):
574b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if not self.used:
575b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self.used = True
576b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return u''
577b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return self.sep
578b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
579b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
580b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# try markupsafe first, if that fails go with Jinja2's bundled version
581b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# of markupsafe.  Markupsafe was previously Jinja2's implementation of
582b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# the Markup object but was moved into a separate package in a patchleve
583b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# release
584b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)try:
585b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from markupsafe import Markup, escape, soft_unicode
586b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)except ImportError:
587b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from jinja2._markupsafe import Markup, escape, soft_unicode
588b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
589b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
590b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# partials
591b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)try:
592b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from functools import partial
593b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)except ImportError:
594b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    class partial(object):
595b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        def __init__(self, _func, *args, **kwargs):
596b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._func = _func
597b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._args = args
598b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._kwargs = kwargs
599b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        def __call__(self, *args, **kwargs):
600b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            kwargs.update(self._kwargs)
601b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return self._func(*(self._args + args), **kwargs)
602