Update Flask

This commit is contained in:
Ruud
2012-10-29 10:54:38 +01:00
parent c0900cfe94
commit b0f6f9b2ea
111 changed files with 817 additions and 477 deletions
Executable → Regular
+1 -1
View File
@@ -27,7 +27,7 @@
:license: BSD, see LICENSE for more details.
"""
__docformat__ = 'restructuredtext en'
__version__ = '2.7-dev'
__version__ = '2.6'
# high level interface
from jinja2.environment import Environment, Template
Executable → Regular
View File
View File
View File
View File
View File
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
+1 -1
View File
@@ -77,7 +77,7 @@ def make_frame_proxy(frame):
class ProcessedTraceback(object):
"""Holds a Jinja preprocessed traceback for printing or reraising."""
"""Holds a Jinja preprocessed traceback for priting or reraising."""
def __init__(self, exc_type, exc_value, frames):
assert frames, 'no frames for this traceback?'
Executable → Regular
View File
Executable → Regular
+5 -5
View File
@@ -67,7 +67,7 @@ def copy_cache(cache):
def load_extensions(environment, extensions):
"""Load the extensions from the list and bind it to the environment.
Returns a dict of instantiated environments.
Returns a dict of instanciated environments.
"""
result = {}
for extension in extensions:
@@ -239,7 +239,7 @@ class Environment(object):
# passed by keyword rather than position. However it's important to
# not change the order of arguments because it's used at least
# internally in those cases:
# - spontaneous environments (i18n extension and Template)
# - spontaneus environments (i18n extension and Template)
# - unittests
# If parameter changes are required only add parameters at the end
# and don't change the arguments (or the defaults!) of the arguments
@@ -435,7 +435,7 @@ class Environment(object):
return stream
def _generate(self, source, name, filename, defer_init=False):
"""Internal hook that can be overridden to hook a different generate
"""Internal hook that can be overriden to hook a different generate
method in.
.. versionadded:: 2.5
@@ -443,7 +443,7 @@ class Environment(object):
return generate(source, self, name, filename, defer_init=defer_init)
def _compile(self, source, filename):
"""Internal hook that can be overridden to hook a different compile
"""Internal hook that can be overriden to hook a different compile
method in.
.. versionadded:: 2.5
@@ -1053,7 +1053,7 @@ class TemplateStream(object):
def dump(self, fp, encoding=None, errors='strict'):
"""Dump the complete stream into a file or file-like object.
Per default unicode strings are written, if you want to encode
before writing specify an `encoding`.
before writing specifiy an `encoding`.
Example usage::
Executable → Regular
+1 -1
View File
@@ -62,7 +62,7 @@ class TemplatesNotFound(TemplateNotFound):
def __init__(self, names=(), message=None):
if message is None:
message = u'none of the templates given were found: ' + \
message = u'non of the templates given were found: ' + \
u', '.join(map(unicode, names))
TemplateNotFound.__init__(self, names and names[-1] or None, message)
self.templates = list(names)
Executable → Regular
+1 -9
View File
@@ -552,10 +552,6 @@ def babel_extract(fileobj, keywords, comment_tags, options):
The `newstyle_gettext` flag can be set to `True` to enable newstyle
gettext calls.
.. versionchanged:: 2.7
A `silent` option can now be provided. If set to `False` template
syntax errors are propagated instead of being ignored.
:param fileobj: the file-like object the messages should be extracted from
:param keywords: a list of keywords (i.e. function names) that should be
recognized as translation functions
@@ -575,10 +571,8 @@ def babel_extract(fileobj, keywords, comment_tags, options):
extensions.add(InternationalizationExtension)
def getbool(options, key, default=False):
return options.get(key, str(default)).lower() in \
('1', 'on', 'yes', 'true')
options.get(key, str(default)).lower() in ('1', 'on', 'yes', 'true')
silent = getbool(options, 'silent', True)
environment = Environment(
options.get('block_start_string', BLOCK_START_STRING),
options.get('block_end_string', BLOCK_END_STRING),
@@ -602,8 +596,6 @@ def babel_extract(fileobj, keywords, comment_tags, options):
node = environment.parse(source)
tokens = list(environment.lex(environment.preprocess(source)))
except TemplateSyntaxError, e:
if not silent:
raise
# skip templates with syntax errors
return
Executable → Regular
+18 -45
View File
@@ -13,10 +13,9 @@ import math
from random import choice
from operator import itemgetter
from itertools import imap, groupby
from jinja2.utils import Markup, escape, pformat, urlize, soft_unicode, \
unicode_urlencode
from jinja2.utils import Markup, escape, pformat, urlize, soft_unicode
from jinja2.runtime import Undefined
from jinja2.exceptions import FilterArgumentError
from jinja2.exceptions import FilterArgumentError, SecurityError
_word_re = re.compile(r'\w+(?u)')
@@ -71,26 +70,6 @@ def do_forceescape(value):
return escape(unicode(value))
def do_urlencode(value):
"""Escape strings for use in URLs (uses UTF-8 encoding). It accepts both
dictionaries and regular strings as well as pairwise iterables.
.. versionadded:: 2.7
"""
itemiter = None
if isinstance(value, dict):
itemiter = value.iteritems()
elif not isinstance(value, basestring):
try:
itemiter = iter(value)
except TypeError:
pass
if itemiter is None:
return unicode_urlencode(value)
return u'&'.join(unicode_urlencode(k) + '=' +
unicode_urlencode(v) for k, v in itemiter)
@evalcontextfilter
def do_replace(eval_ctx, s, old, new, count=None):
"""Return a copy of the value with all occurrences of a substring
@@ -176,12 +155,7 @@ def do_title(s):
"""Return a titlecased version of the value. I.e. words will start with
uppercase letters, all remaining characters are lowercase.
"""
rv = []
for item in re.compile(r'([-\s]+)(?u)').split(s):
if not item:
continue
rv.append(item[0].upper() + item[1:])
return ''.join(rv)
return soft_unicode(s).title()
def do_dictsort(value, case_sensitive=False, by='key'):
@@ -372,25 +346,25 @@ def do_filesizeformat(value, binary=False):
bytes = float(value)
base = binary and 1024 or 1000
prefixes = [
(binary and 'KiB' or 'kB'),
(binary and 'MiB' or 'MB'),
(binary and 'GiB' or 'GB'),
(binary and 'TiB' or 'TB'),
(binary and 'PiB' or 'PB'),
(binary and 'EiB' or 'EB'),
(binary and 'ZiB' or 'ZB'),
(binary and 'YiB' or 'YB')
(binary and "KiB" or "kB"),
(binary and "MiB" or "MB"),
(binary and "GiB" or "GB"),
(binary and "TiB" or "TB"),
(binary and "PiB" or "PB"),
(binary and "EiB" or "EB"),
(binary and "ZiB" or "ZB"),
(binary and "YiB" or "YB")
]
if bytes == 1:
return '1 Byte'
return "1 Byte"
elif bytes < base:
return '%d Bytes' % bytes
return "%d Bytes" % bytes
else:
for i, prefix in enumerate(prefixes):
unit = base ** (i + 2)
unit = base * base ** (i + 1)
if bytes < unit:
return '%.1f %s' % ((base * bytes / unit), prefix)
return '%.1f %s' % ((base * bytes / unit), prefix)
return "%.1f %s" % ((bytes / unit), prefix)
return "%.1f %s" % ((bytes / unit), prefix)
def do_pprint(value, verbose=False):
@@ -583,7 +557,7 @@ def do_batch(value, linecount, fill_with=None):
A filter that batches items. It works pretty much like `slice`
just the other way round. It returns a list of lists with the
given number of items. If you provide a second parameter this
is used to fill up missing items. See this example:
is used to fill missing items. See this example:
.. sourcecode:: html+jinja
@@ -823,6 +797,5 @@ FILTERS = {
'round': do_round,
'groupby': do_groupby,
'safe': do_mark_safe,
'xmlattr': do_xmlattr,
'urlencode': do_urlencode
'xmlattr': do_xmlattr
}
Executable → Regular
+4 -4
View File
@@ -414,7 +414,7 @@ class Lexer(object):
(operator_re, TOKEN_OPERATOR, None)
]
# assemble the root lexing rule. because "|" is ungreedy
# assamble the root lexing rule. because "|" is ungreedy
# we have to sort by length so that the lexer continues working
# as expected when we have parsing rules like <% for block and
# <%= for variables. (if someone wants asp like syntax)
@@ -491,7 +491,7 @@ class Lexer(object):
}
def _normalize_newlines(self, value):
"""Called for strings and template data to normalize it to unicode."""
"""Called for strings and template data to normlize it to unicode."""
return newline_re.sub(self.newline_sequence, value)
def tokenize(self, source, name=None, filename=None, state=None):
@@ -571,7 +571,7 @@ class Lexer(object):
if m is None:
continue
# we only match blocks and variables if braces / parentheses
# we only match blocks and variables if brances / parentheses
# are balanced. continue parsing with the lower rule which
# is the operator rule. do this only if the end tags look
# like operators
@@ -669,7 +669,7 @@ class Lexer(object):
# publish new function and start again
pos = pos2
break
# if loop terminated without break we haven't found a single match
# if loop terminated without break we havn't found a single match
# either we are at the end of the file or we have a problem
else:
# end of text
Executable → Regular
+1 -24
View File
@@ -330,16 +330,12 @@ class PrefixLoader(BaseLoader):
self.mapping = mapping
self.delimiter = delimiter
def get_loader(self, template):
def get_source(self, environment, template):
try:
prefix, name = template.split(self.delimiter, 1)
loader = self.mapping[prefix]
except (ValueError, KeyError):
raise TemplateNotFound(template)
return loader, name
def get_source(self, environment, template):
loader, name = self.get_loader(template)
try:
return loader.get_source(environment, name)
except TemplateNotFound:
@@ -347,16 +343,6 @@ class PrefixLoader(BaseLoader):
# (the one that includes the prefix)
raise TemplateNotFound(template)
@internalcode
def load(self, environment, name, globals=None):
loader, local_name = self.get_loader(name)
try:
return loader.load(environment, local_name)
except TemplateNotFound:
# re-raise the exception with the correct fileame here.
# (the one that includes the prefix)
raise TemplateNotFound(name)
def list_templates(self):
result = []
for prefix, loader in self.mapping.iteritems():
@@ -390,15 +376,6 @@ class ChoiceLoader(BaseLoader):
pass
raise TemplateNotFound(template)
@internalcode
def load(self, environment, name, globals=None):
for loader in self.loaders:
try:
return loader.load(environment, name, globals)
except TemplateNotFound:
pass
raise TemplateNotFound(name)
def list_templates(self):
found = set()
for loader in self.loaders:
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
+2 -1
View File
@@ -223,7 +223,7 @@ class Parser(object):
# raise a nicer error message in that case.
if self.stream.current.type == 'sub':
self.fail('Block names in Jinja have to be valid Python '
'identifiers and may not contain hyphens, use an '
'identifiers and may not contain hypens, use an '
'underscore instead.')
node.body = self.parse_statements(('name:endblock',), drop_needle=True)
@@ -698,6 +698,7 @@ class Parser(object):
arg = nodes.Const(attr_token.value, lineno=attr_token.lineno)
return nodes.Getitem(node, arg, 'load', lineno=token.lineno)
if token.type == 'lbracket':
priority_on_attribute = False
args = []
while self.stream.current.type != 'rbracket':
if args:
Executable → Regular
+2 -15
View File
@@ -30,8 +30,6 @@ to_string = unicode
#: the identity function. Useful for certain things in the environment
identity = lambda x: x
_last_iteration = object()
def markup_join(seq):
"""Concatenation that escapes if necessary and converts to unicode."""
@@ -272,7 +270,6 @@ class LoopContext(object):
def __init__(self, iterable, recurse=None):
self._iterator = iter(iterable)
self._recurse = recurse
self._after = self._safe_next()
self.index0 = -1
# try to get the length of the iterable early. This must be done
@@ -291,7 +288,7 @@ class LoopContext(object):
return args[self.index0 % len(args)]
first = property(lambda x: x.index0 == 0)
last = property(lambda x: x._after is _last_iteration)
last = property(lambda x: x.index0 + 1 == x.length)
index = property(lambda x: x.index0 + 1)
revindex = property(lambda x: x.length - x.index0)
revindex0 = property(lambda x: x.length - x.index)
@@ -302,12 +299,6 @@ class LoopContext(object):
def __iter__(self):
return LoopContextIterator(self)
def _safe_next(self):
try:
return next(self._iterator)
except StopIteration:
return _last_iteration
@internalcode
def loop(self, iterable):
if self._recurse is None:
@@ -353,11 +344,7 @@ class LoopContextIterator(object):
def next(self):
ctx = self.context
ctx.index0 += 1
if ctx._after is _last_iteration:
raise StopIteration()
next_elem = ctx._after
ctx._after = ctx._safe_next()
return next_elem, ctx
return next(ctx._iterator), ctx
class Macro(object):
Executable → Regular
View File
Executable → Regular
View File
View File
Executable → Regular
View File
View File
Executable → Regular
View File
View File
Executable → Regular
View File
Executable → Regular
+3 -43
View File
@@ -84,28 +84,10 @@ class FilterTestCase(JinjaTestCase):
'{{ 1000000000000|filesizeformat(true) }}'
)
out = tmpl.render()
self.assert_equal(out, (
'100 Bytes|1.0 kB|1.0 MB|1.0 GB|1.0 TB|100 Bytes|'
'1000 Bytes|976.6 KiB|953.7 MiB|931.3 GiB'
))
def test_filesizeformat_issue59(self):
tmpl = env.from_string(
'{{ 300|filesizeformat }}|'
'{{ 3000|filesizeformat }}|'
'{{ 3000000|filesizeformat }}|'
'{{ 3000000000|filesizeformat }}|'
'{{ 3000000000000|filesizeformat }}|'
'{{ 300|filesizeformat(true) }}|'
'{{ 3000|filesizeformat(true) }}|'
'{{ 3000000|filesizeformat(true) }}'
assert out == (
'100 Bytes|0.0 kB|0.0 MB|0.0 GB|0.0 TB|100 Bytes|'
'1000 Bytes|1.0 KiB|0.9 MiB|0.9 GiB'
)
out = tmpl.render()
self.assert_equal(out, (
'300 Bytes|3.0 kB|3.0 MB|3.0 GB|3.0 TB|300 Bytes|'
'2.9 KiB|2.9 MiB'
))
def test_first(self):
tmpl = env.from_string('{{ foo|first }}')
@@ -193,16 +175,6 @@ class FilterTestCase(JinjaTestCase):
def test_title(self):
tmpl = env.from_string('''{{ "foo bar"|title }}''')
assert tmpl.render() == "Foo Bar"
tmpl = env.from_string('''{{ "foo's bar"|title }}''')
assert tmpl.render() == "Foo's Bar"
tmpl = env.from_string('''{{ "foo bar"|title }}''')
assert tmpl.render() == "Foo Bar"
tmpl = env.from_string('''{{ "f bar f"|title }}''')
assert tmpl.render() == "F Bar F"
tmpl = env.from_string('''{{ "foo-bar"|title }}''')
assert tmpl.render() == "Foo-Bar"
tmpl = env.from_string('''{{ "foo\tbar"|title }}''')
assert tmpl.render() == "Foo\tBar"
def test_truncate(self):
tmpl = env.from_string(
@@ -377,18 +349,6 @@ class FilterTestCase(JinjaTestCase):
tmpl = env.from_string('{{ "<div>foo</div>" }}')
assert tmpl.render() == '&lt;div&gt;foo&lt;/div&gt;'
def test_urlencode(self):
env = Environment(autoescape=True)
tmpl = env.from_string('{{ "Hello, world!"|urlencode }}')
assert tmpl.render() == 'Hello%2C%20world%21'
tmpl = env.from_string('{{ o|urlencode }}')
assert tmpl.render(o=u"Hello, world\u203d") == "Hello%2C%20world%E2%80%BD"
assert tmpl.render(o=(("f", 1),)) == "f=1"
assert tmpl.render(o=(('f', 1), ("z", 2))) == "f=1&amp;z=2"
assert tmpl.render(o=((u"\u203d", 1),)) == "%E2%80%BD=1"
assert tmpl.render(o={u"\u203d": 1}) == "%E2%80%BD=1"
assert tmpl.render(o={0: 1}) == "0=1"
def suite():
suite = unittest.TestSuite()
Executable → Regular
View File
View File
+4 -4
View File
@@ -169,7 +169,7 @@ and bar comment #}
except TemplateSyntaxError, e:
assert str(e) == expected, 'unexpected error message'
else:
assert False, 'that was supposed to be an error'
assert False, 'that was suposed to be an error'
assert_error('{% for item in seq %}...{% endif %}',
"Encountered unknown tag 'endif'. Jinja was looking "
@@ -189,7 +189,7 @@ and bar comment #}
"that needs to be closed is 'for'.")
assert_error('{% block foo-bar-baz %}',
"Block names in Jinja have to be valid Python identifiers "
"and may not contain hyphens, use an underscore instead.")
"and may not contain hypens, use an underscore instead.")
assert_error('{% unknown_tag %}',
"Encountered unknown tag 'unknown_tag'.")
@@ -317,7 +317,7 @@ class SyntaxTestCase(JinjaTestCase):
self.assert_raises(TemplateSyntaxError, env.from_string,
'{% block x %}{% endblock y %}')
def test_constant_casing(self):
def test_contant_casing(self):
for const in True, False, None:
tmpl = env.from_string('{{ %s }}|{{ %s }}|{{ %s }}' % (
str(const), str(const).lower(), str(const).upper()
@@ -327,7 +327,7 @@ class SyntaxTestCase(JinjaTestCase):
def test_test_chaining(self):
self.assert_raises(TemplateSyntaxError, env.from_string,
'{{ foo is string is sequence }}')
assert env.from_string('{{ 42 is string or 42 is number }}'
env.from_string('{{ 42 is string or 42 is number }}'
).render() == 'True'
def test_string_concatenation(self):
Executable → Regular
-28
View File
@@ -182,34 +182,6 @@ class ModuleLoaderTestCase(JinjaTestCase):
tmpl_3c4ddf650c1a73df961a6d3d2ce2752f1b8fd490
assert mod.__file__.endswith('.pyc')
def test_choice_loader(self):
log = self.compile_down(py_compile=True)
assert 'Byte-compiled "a/test.html"' in log
self.mod_env.loader = loaders.ChoiceLoader([
self.mod_env.loader,
loaders.DictLoader({'DICT_SOURCE': 'DICT_TEMPLATE'})
])
tmpl1 = self.mod_env.get_template('a/test.html')
self.assert_equal(tmpl1.render(), 'BAR')
tmpl2 = self.mod_env.get_template('DICT_SOURCE')
self.assert_equal(tmpl2.render(), 'DICT_TEMPLATE')
def test_prefix_loader(self):
log = self.compile_down(py_compile=True)
assert 'Byte-compiled "a/test.html"' in log
self.mod_env.loader = loaders.PrefixLoader({
'MOD': self.mod_env.loader,
'DICT': loaders.DictLoader({'test.html': 'DICT_TEMPLATE'})
})
tmpl1 = self.mod_env.get_template('MOD/a/test.html')
self.assert_equal(tmpl1.render(), 'BAR')
tmpl2 = self.mod_env.get_template('DICT/test.html')
self.assert_equal(tmpl2.render(), 'DICT_TEMPLATE')
def suite():
suite = unittest.TestSuite()
View File
View File
View File
View File
View File
View File
View File
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
+7 -26
View File
@@ -11,10 +11,6 @@
import re
import sys
import errno
try:
from urllib.parse import quote_from_bytes as url_quote
except ImportError:
from urllib import quote as url_quote
try:
from thread import allocate_lock
except ImportError:
@@ -67,7 +63,7 @@ except TypeError, _error:
del _test_gen_bug, _error
# for python 2.x we create ourselves a next() function that does the
# for python 2.x we create outselves a next() function that does the
# basics without exception catching.
try:
next = next
@@ -132,7 +128,7 @@ def contextfunction(f):
def evalcontextfunction(f):
"""This decorator can be used to mark a function or method as an eval
"""This decoraotr can be used to mark a function or method as an eval
context callable. This is similar to the :func:`contextfunction`
but instead of passing the context, an evaluation context object is
passed. For more information about the eval context, see
@@ -195,7 +191,7 @@ def clear_caches():
def import_string(import_name, silent=False):
"""Imports an object based on a string. This is useful if you want to
"""Imports an object based on a string. This use useful if you want to
use import paths as endpoints or something similar. An import path can
be specified either in dotted notation (``xml.sax.saxutils.escape``)
or with a colon as object delimiter (``xml.sax.saxutils:escape``).
@@ -353,21 +349,6 @@ def generate_lorem_ipsum(n=5, html=True, min=20, max=100):
return Markup(u'\n'.join(u'<p>%s</p>' % escape(x) for x in result))
def unicode_urlencode(obj, charset='utf-8'):
"""URL escapes a single bytestring or unicode string with the
given charset if applicable to URL safe quoting under all rules
that need to be considered under all supported Python versions.
If non strings are provided they are converted to their unicode
representation first.
"""
if not isinstance(obj, basestring):
obj = unicode(obj)
if isinstance(obj, unicode):
obj = obj.encode(charset)
return unicode(url_quote(obj))
class LRUCache(object):
"""A simple LRU Cache implementation."""
@@ -412,7 +393,7 @@ class LRUCache(object):
return (self.capacity,)
def copy(self):
"""Return a shallow copy of the instance."""
"""Return an shallow copy of the instance."""
rv = self.__class__(self.capacity)
rv._mapping.update(self._mapping)
rv._queue = deque(self._queue)
@@ -462,7 +443,7 @@ class LRUCache(object):
"""Get an item from the cache. Moves the item up so that it has the
highest priority then.
Raise a `KeyError` if it does not exist.
Raise an `KeyError` if it does not exist.
"""
rv = self._mapping[key]
if self._queue[-1] != key:
@@ -497,7 +478,7 @@ class LRUCache(object):
def __delitem__(self, key):
"""Remove an item from the cache dict.
Raise a `KeyError` if it does not exist.
Raise an `KeyError` if it does not exist.
"""
self._wlock.acquire()
try:
@@ -598,7 +579,7 @@ class Joiner(object):
# try markupsafe first, if that fails go with Jinja2's bundled version
# of markupsafe. Markupsafe was previously Jinja2's implementation of
# the Markup object but was moved into a separate package in a patchlevel
# the Markup object but was moved into a separate package in a patchleve
# release
try:
from markupsafe import Markup, escape, soft_unicode
Executable → Regular
View File