diff options
author | coderick14 | 2017-05-17 15:40:18 +0530 |
---|---|---|
committer | coderick14 | 2017-05-17 15:41:00 +0530 |
commit | fe407193c200e03070928c1e2c1a6e067d32893d (patch) | |
tree | 1c492aa814754b5db5d644c769f5382306217298 /lib/python2.7/site-packages/django/template | |
parent | 9a1393e8470d855762e699abca9911b9cdae6a7d (diff) | |
download | SBHS-2018-Rpi-fe407193c200e03070928c1e2c1a6e067d32893d.tar.gz SBHS-2018-Rpi-fe407193c200e03070928c1e2c1a6e067d32893d.tar.bz2 SBHS-2018-Rpi-fe407193c200e03070928c1e2c1a6e067d32893d.zip |
Upgrade to Django 1.11
- Database integration yet to be tested
Diffstat (limited to 'lib/python2.7/site-packages/django/template')
15 files changed, 0 insertions, 5010 deletions
diff --git a/lib/python2.7/site-packages/django/template/__init__.py b/lib/python2.7/site-packages/django/template/__init__.py deleted file mode 100644 index ca1bd49..0000000 --- a/lib/python2.7/site-packages/django/template/__init__.py +++ /dev/null @@ -1,80 +0,0 @@ -""" -This is the Django template system. - -How it works: - -The Lexer.tokenize() function converts a template string (i.e., a string containing -markup with custom template tags) to tokens, which can be either plain text -(TOKEN_TEXT), variables (TOKEN_VAR) or block statements (TOKEN_BLOCK). - -The Parser() class takes a list of tokens in its constructor, and its parse() -method returns a compiled template -- which is, under the hood, a list of -Node objects. - -Each Node is responsible for creating some sort of output -- e.g. simple text -(TextNode), variable values in a given context (VariableNode), results of basic -logic (IfNode), results of looping (ForNode), or anything else. The core Node -types are TextNode, VariableNode, IfNode and ForNode, but plugin modules can -define their own custom node types. - -Each Node has a render() method, which takes a Context and returns a string of -the rendered node. For example, the render() method of a Variable Node returns -the variable's value as a string. The render() method of an IfNode returns the -rendered output of whatever was inside the loop, recursively. - -The Template class is a convenient wrapper that takes care of template -compilation and rendering. - -Usage: - -The only thing you should ever use directly in this file is the Template class. -Create a compiled template object with a template_string, then call render() -with a context. In the compilation stage, the TemplateSyntaxError exception -will be raised if the template doesn't have proper syntax. - -Sample code: - ->>> from django import template ->>> s = u'<html>{% if test %}<h1>{{ varvalue }}</h1>{% endif %}</html>' ->>> t = template.Template(s) - -(t is now a compiled template, and its render() method can be called multiple -times with multiple contexts) - ->>> c = template.Context({'test':True, 'varvalue': 'Hello'}) ->>> t.render(c) -u'<html><h1>Hello</h1></html>' ->>> c = template.Context({'test':False, 'varvalue': 'Hello'}) ->>> t.render(c) -u'<html></html>' -""" - -# Template lexing symbols -from django.template.base import (ALLOWED_VARIABLE_CHARS, BLOCK_TAG_END, - BLOCK_TAG_START, COMMENT_TAG_END, COMMENT_TAG_START, - FILTER_ARGUMENT_SEPARATOR, FILTER_SEPARATOR, SINGLE_BRACE_END, - SINGLE_BRACE_START, TOKEN_BLOCK, TOKEN_COMMENT, TOKEN_TEXT, TOKEN_VAR, - TRANSLATOR_COMMENT_MARK, UNKNOWN_SOURCE, VARIABLE_ATTRIBUTE_SEPARATOR, - VARIABLE_TAG_END, VARIABLE_TAG_START, filter_re, tag_re) - -# Exceptions -from django.template.base import (ContextPopException, InvalidTemplateLibrary, - TemplateDoesNotExist, TemplateEncodingError, TemplateSyntaxError, - VariableDoesNotExist) - -# Template parts -from django.template.base import (Context, FilterExpression, Lexer, Node, - NodeList, Parser, RequestContext, Origin, StringOrigin, Template, - TextNode, Token, TokenParser, Variable, VariableNode, constant_string, - filter_raw_string) - -# Compiling templates -from django.template.base import (compile_string, resolve_variable, - unescape_string_literal, generic_tag_compiler) - -# Library management -from django.template.base import (Library, add_to_builtins, builtins, - get_library, get_templatetags_modules, get_text_list, import_library, - libraries) - -__all__ = ('Template', 'Context', 'RequestContext', 'compile_string') diff --git a/lib/python2.7/site-packages/django/template/base.py b/lib/python2.7/site-packages/django/template/base.py deleted file mode 100644 index 26f8111..0000000 --- a/lib/python2.7/site-packages/django/template/base.py +++ /dev/null @@ -1,1335 +0,0 @@ -from __future__ import absolute_import, unicode_literals - -import re -from functools import partial -from inspect import getargspec - -from django.conf import settings -from django.template.context import (BaseContext, Context, RequestContext, - ContextPopException) -from django.utils.importlib import import_module -from django.utils.itercompat import is_iterable -from django.utils.text import (smart_split, unescape_string_literal, - get_text_list) -from django.utils.encoding import force_str, force_text -from django.utils.translation import ugettext_lazy, pgettext_lazy -from django.utils.safestring import (SafeData, EscapeData, mark_safe, - mark_for_escaping) -from django.utils.formats import localize -from django.utils.html import escape -from django.utils.module_loading import module_has_submodule -from django.utils import six -from django.utils.timezone import template_localtime -from django.utils.encoding import python_2_unicode_compatible - - -TOKEN_TEXT = 0 -TOKEN_VAR = 1 -TOKEN_BLOCK = 2 -TOKEN_COMMENT = 3 -TOKEN_MAPPING = { - TOKEN_TEXT: 'Text', - TOKEN_VAR: 'Var', - TOKEN_BLOCK: 'Block', - TOKEN_COMMENT: 'Comment', -} - -# template syntax constants -FILTER_SEPARATOR = '|' -FILTER_ARGUMENT_SEPARATOR = ':' -VARIABLE_ATTRIBUTE_SEPARATOR = '.' -BLOCK_TAG_START = '{%' -BLOCK_TAG_END = '%}' -VARIABLE_TAG_START = '{{' -VARIABLE_TAG_END = '}}' -COMMENT_TAG_START = '{#' -COMMENT_TAG_END = '#}' -TRANSLATOR_COMMENT_MARK = 'Translators' -SINGLE_BRACE_START = '{' -SINGLE_BRACE_END = '}' - -ALLOWED_VARIABLE_CHARS = ('abcdefghijklmnopqrstuvwxyz' - 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.') - -# what to report as the origin for templates that come from non-loader sources -# (e.g. strings) -UNKNOWN_SOURCE = '<unknown source>' - -# match a variable or block tag and capture the entire tag, including start/end -# delimiters -tag_re = (re.compile('(%s.*?%s|%s.*?%s|%s.*?%s)' % - (re.escape(BLOCK_TAG_START), re.escape(BLOCK_TAG_END), - re.escape(VARIABLE_TAG_START), re.escape(VARIABLE_TAG_END), - re.escape(COMMENT_TAG_START), re.escape(COMMENT_TAG_END)))) - -# global dictionary of libraries that have been loaded using get_library -libraries = {} -# global list of libraries to load by default for a new parser -builtins = [] - -# True if TEMPLATE_STRING_IF_INVALID contains a format string (%s). None means -# uninitialised. -invalid_var_format_string = None - -class TemplateSyntaxError(Exception): - pass - -class TemplateDoesNotExist(Exception): - pass - -class TemplateEncodingError(Exception): - pass - -@python_2_unicode_compatible -class VariableDoesNotExist(Exception): - - def __init__(self, msg, params=()): - self.msg = msg - self.params = params - - def __str__(self): - return self.msg % tuple([force_text(p, errors='replace') - for p in self.params]) - -class InvalidTemplateLibrary(Exception): - pass - -class Origin(object): - def __init__(self, name): - self.name = name - - def reload(self): - raise NotImplementedError - - def __str__(self): - return self.name - -class StringOrigin(Origin): - def __init__(self, source): - super(StringOrigin, self).__init__(UNKNOWN_SOURCE) - self.source = source - - def reload(self): - return self.source - -class Template(object): - def __init__(self, template_string, origin=None, - name='<Unknown Template>'): - try: - template_string = force_text(template_string) - except UnicodeDecodeError: - raise TemplateEncodingError("Templates can only be constructed " - "from unicode or UTF-8 strings.") - if settings.TEMPLATE_DEBUG and origin is None: - origin = StringOrigin(template_string) - self.nodelist = compile_string(template_string, origin) - self.name = name - - def __iter__(self): - for node in self.nodelist: - for subnode in node: - yield subnode - - def _render(self, context): - return self.nodelist.render(context) - - def render(self, context): - "Display stage -- can be called many times" - context.render_context.push() - try: - return self._render(context) - finally: - context.render_context.pop() - -def compile_string(template_string, origin): - "Compiles template_string into NodeList ready for rendering" - if settings.TEMPLATE_DEBUG: - from django.template.debug import DebugLexer, DebugParser - lexer_class, parser_class = DebugLexer, DebugParser - else: - lexer_class, parser_class = Lexer, Parser - lexer = lexer_class(template_string, origin) - parser = parser_class(lexer.tokenize()) - return parser.parse() - -class Token(object): - def __init__(self, token_type, contents): - # token_type must be TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK or - # TOKEN_COMMENT. - self.token_type, self.contents = token_type, contents - self.lineno = None - - def __str__(self): - token_name = TOKEN_MAPPING[self.token_type] - return ('<%s token: "%s...">' % - (token_name, self.contents[:20].replace('\n', ''))) - - def split_contents(self): - split = [] - bits = iter(smart_split(self.contents)) - for bit in bits: - # Handle translation-marked template pieces - if bit.startswith('_("') or bit.startswith("_('"): - sentinal = bit[2] + ')' - trans_bit = [bit] - while not bit.endswith(sentinal): - bit = next(bits) - trans_bit.append(bit) - bit = ' '.join(trans_bit) - split.append(bit) - return split - -class Lexer(object): - def __init__(self, template_string, origin): - self.template_string = template_string - self.origin = origin - self.lineno = 1 - self.verbatim = False - - def tokenize(self): - """ - Return a list of tokens from a given template_string. - """ - in_tag = False - result = [] - for bit in tag_re.split(self.template_string): - if bit: - result.append(self.create_token(bit, in_tag)) - in_tag = not in_tag - return result - - def create_token(self, token_string, in_tag): - """ - Convert the given token string into a new Token object and return it. - If in_tag is True, we are processing something that matched a tag, - otherwise it should be treated as a literal string. - """ - if in_tag and token_string.startswith(BLOCK_TAG_START): - # The [2:-2] ranges below strip off *_TAG_START and *_TAG_END. - # We could do len(BLOCK_TAG_START) to be more "correct", but we've - # hard-coded the 2s here for performance. And it's not like - # the TAG_START values are going to change anytime, anyway. - block_content = token_string[2:-2].strip() - if self.verbatim and block_content == self.verbatim: - self.verbatim = False - if in_tag and not self.verbatim: - if token_string.startswith(VARIABLE_TAG_START): - token = Token(TOKEN_VAR, token_string[2:-2].strip()) - elif token_string.startswith(BLOCK_TAG_START): - if block_content[:9] in ('verbatim', 'verbatim '): - self.verbatim = 'end%s' % block_content - token = Token(TOKEN_BLOCK, block_content) - elif token_string.startswith(COMMENT_TAG_START): - content = '' - if token_string.find(TRANSLATOR_COMMENT_MARK): - content = token_string[2:-2].strip() - token = Token(TOKEN_COMMENT, content) - else: - token = Token(TOKEN_TEXT, token_string) - token.lineno = self.lineno - self.lineno += token_string.count('\n') - return token - -class Parser(object): - def __init__(self, tokens): - self.tokens = tokens - self.tags = {} - self.filters = {} - for lib in builtins: - self.add_library(lib) - - def parse(self, parse_until=None): - if parse_until is None: - parse_until = [] - nodelist = self.create_nodelist() - while self.tokens: - token = self.next_token() - # Use the raw values here for TOKEN_* for a tiny performance boost. - if token.token_type == 0: # TOKEN_TEXT - self.extend_nodelist(nodelist, TextNode(token.contents), token) - elif token.token_type == 1: # TOKEN_VAR - if not token.contents: - self.empty_variable(token) - try: - filter_expression = self.compile_filter(token.contents) - except TemplateSyntaxError as e: - if not self.compile_filter_error(token, e): - raise - var_node = self.create_variable_node(filter_expression) - self.extend_nodelist(nodelist, var_node, token) - elif token.token_type == 2: # TOKEN_BLOCK - try: - command = token.contents.split()[0] - except IndexError: - self.empty_block_tag(token) - if command in parse_until: - # put token back on token list so calling - # code knows why it terminated - self.prepend_token(token) - return nodelist - # execute callback function for this tag and append - # resulting node - self.enter_command(command, token) - try: - compile_func = self.tags[command] - except KeyError: - self.invalid_block_tag(token, command, parse_until) - try: - compiled_result = compile_func(self, token) - except TemplateSyntaxError as e: - if not self.compile_function_error(token, e): - raise - self.extend_nodelist(nodelist, compiled_result, token) - self.exit_command() - if parse_until: - self.unclosed_block_tag(parse_until) - return nodelist - - def skip_past(self, endtag): - while self.tokens: - token = self.next_token() - if token.token_type == TOKEN_BLOCK and token.contents == endtag: - return - self.unclosed_block_tag([endtag]) - - def create_variable_node(self, filter_expression): - return VariableNode(filter_expression) - - def create_nodelist(self): - return NodeList() - - def extend_nodelist(self, nodelist, node, token): - if node.must_be_first and nodelist: - try: - if nodelist.contains_nontext: - raise AttributeError - except AttributeError: - raise TemplateSyntaxError("%r must be the first tag " - "in the template." % node) - if isinstance(nodelist, NodeList) and not isinstance(node, TextNode): - nodelist.contains_nontext = True - nodelist.append(node) - - def enter_command(self, command, token): - pass - - def exit_command(self): - pass - - def error(self, token, msg): - return TemplateSyntaxError(msg) - - def empty_variable(self, token): - raise self.error(token, "Empty variable tag") - - def empty_block_tag(self, token): - raise self.error(token, "Empty block tag") - - def invalid_block_tag(self, token, command, parse_until=None): - if parse_until: - raise self.error(token, "Invalid block tag: '%s', expected %s" % - (command, get_text_list(["'%s'" % p for p in parse_until]))) - raise self.error(token, "Invalid block tag: '%s'" % command) - - def unclosed_block_tag(self, parse_until): - raise self.error(None, "Unclosed tags: %s " % ', '.join(parse_until)) - - def compile_filter_error(self, token, e): - pass - - def compile_function_error(self, token, e): - pass - - def next_token(self): - return self.tokens.pop(0) - - def prepend_token(self, token): - self.tokens.insert(0, token) - - def delete_first_token(self): - del self.tokens[0] - - def add_library(self, lib): - self.tags.update(lib.tags) - self.filters.update(lib.filters) - - def compile_filter(self, token): - """ - Convenient wrapper for FilterExpression - """ - return FilterExpression(token, self) - - def find_filter(self, filter_name): - if filter_name in self.filters: - return self.filters[filter_name] - else: - raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name) - -class TokenParser(object): - """ - Subclass this and implement the top() method to parse a template line. - When instantiating the parser, pass in the line from the Django template - parser. - - The parser's "tagname" instance-variable stores the name of the tag that - the filter was called with. - """ - def __init__(self, subject): - self.subject = subject - self.pointer = 0 - self.backout = [] - self.tagname = self.tag() - - def top(self): - """ - Overload this method to do the actual parsing and return the result. - """ - raise NotImplementedError() - - def more(self): - """ - Returns True if there is more stuff in the tag. - """ - return self.pointer < len(self.subject) - - def back(self): - """ - Undoes the last microparser. Use this for lookahead and backtracking. - """ - if not len(self.backout): - raise TemplateSyntaxError("back called without some previous " - "parsing") - self.pointer = self.backout.pop() - - def tag(self): - """ - A microparser that just returns the next tag from the line. - """ - subject = self.subject - i = self.pointer - if i >= len(subject): - raise TemplateSyntaxError("expected another tag, found " - "end of string: %s" % subject) - p = i - while i < len(subject) and subject[i] not in (' ', '\t'): - i += 1 - s = subject[p:i] - while i < len(subject) and subject[i] in (' ', '\t'): - i += 1 - self.backout.append(self.pointer) - self.pointer = i - return s - - def value(self): - """ - A microparser that parses for a value: some string constant or - variable name. - """ - subject = self.subject - i = self.pointer - - def next_space_index(subject, i): - """ - Increment pointer until a real space (i.e. a space not within - quotes) is encountered - """ - while i < len(subject) and subject[i] not in (' ', '\t'): - if subject[i] in ('"', "'"): - c = subject[i] - i += 1 - while i < len(subject) and subject[i] != c: - i += 1 - if i >= len(subject): - raise TemplateSyntaxError("Searching for value. " - "Unexpected end of string in column %d: %s" % - (i, subject)) - i += 1 - return i - - if i >= len(subject): - raise TemplateSyntaxError("Searching for value. Expected another " - "value but found end of string: %s" % - subject) - if subject[i] in ('"', "'"): - p = i - i += 1 - while i < len(subject) and subject[i] != subject[p]: - i += 1 - if i >= len(subject): - raise TemplateSyntaxError("Searching for value. Unexpected " - "end of string in column %d: %s" % - (i, subject)) - i += 1 - - # Continue parsing until next "real" space, - # so that filters are also included - i = next_space_index(subject, i) - - res = subject[p:i] - while i < len(subject) and subject[i] in (' ', '\t'): - i += 1 - self.backout.append(self.pointer) - self.pointer = i - return res - else: - p = i - i = next_space_index(subject, i) - s = subject[p:i] - while i < len(subject) and subject[i] in (' ', '\t'): - i += 1 - self.backout.append(self.pointer) - self.pointer = i - return s - -# This only matches constant *strings* (things in quotes or marked for -# translation). Numbers are treated as variables for implementation reasons -# (so that they retain their type when passed to filters). -constant_string = r""" -(?:%(i18n_open)s%(strdq)s%(i18n_close)s| -%(i18n_open)s%(strsq)s%(i18n_close)s| -%(strdq)s| -%(strsq)s) -""" % { - 'strdq': r'"[^"\\]*(?:\\.[^"\\]*)*"', # double-quoted string - 'strsq': r"'[^'\\]*(?:\\.[^'\\]*)*'", # single-quoted string - 'i18n_open': re.escape("_("), - 'i18n_close': re.escape(")"), - } -constant_string = constant_string.replace("\n", "") - -filter_raw_string = r""" -^(?P<constant>%(constant)s)| -^(?P<var>[%(var_chars)s]+|%(num)s)| - (?:\s*%(filter_sep)s\s* - (?P<filter_name>\w+) - (?:%(arg_sep)s - (?: - (?P<constant_arg>%(constant)s)| - (?P<var_arg>[%(var_chars)s]+|%(num)s) - ) - )? - )""" % { - 'constant': constant_string, - 'num': r'[-+\.]?\d[\d\.e]*', - 'var_chars': "\w\.", - 'filter_sep': re.escape(FILTER_SEPARATOR), - 'arg_sep': re.escape(FILTER_ARGUMENT_SEPARATOR), - } - -filter_re = re.compile(filter_raw_string, re.UNICODE | re.VERBOSE) - -class FilterExpression(object): - """ - Parses a variable token and its optional filters (all as a single string), - and return a list of tuples of the filter name and arguments. - Sample:: - - >>> token = 'variable|default:"Default value"|date:"Y-m-d"' - >>> p = Parser('') - >>> fe = FilterExpression(token, p) - >>> len(fe.filters) - 2 - >>> fe.var - <Variable: 'variable'> - - This class should never be instantiated outside of the - get_filters_from_token helper function. - """ - def __init__(self, token, parser): - self.token = token - matches = filter_re.finditer(token) - var_obj = None - filters = [] - upto = 0 - for match in matches: - start = match.start() - if upto != start: - raise TemplateSyntaxError("Could not parse some characters: " - "%s|%s|%s" % - (token[:upto], token[upto:start], - token[start:])) - if var_obj is None: - var, constant = match.group("var", "constant") - if constant: - try: - var_obj = Variable(constant).resolve({}) - except VariableDoesNotExist: - var_obj = None - elif var is None: - raise TemplateSyntaxError("Could not find variable at " - "start of %s." % token) - else: - var_obj = Variable(var) - else: - filter_name = match.group("filter_name") - args = [] - constant_arg, var_arg = match.group("constant_arg", "var_arg") - if constant_arg: - args.append((False, Variable(constant_arg).resolve({}))) - elif var_arg: - args.append((True, Variable(var_arg))) - filter_func = parser.find_filter(filter_name) - self.args_check(filter_name, filter_func, args) - filters.append((filter_func, args)) - upto = match.end() - if upto != len(token): - raise TemplateSyntaxError("Could not parse the remainder: '%s' " - "from '%s'" % (token[upto:], token)) - - self.filters = filters - self.var = var_obj - - def resolve(self, context, ignore_failures=False): - if isinstance(self.var, Variable): - try: - obj = self.var.resolve(context) - except VariableDoesNotExist: - if ignore_failures: - obj = None - else: - if settings.TEMPLATE_STRING_IF_INVALID: - global invalid_var_format_string - if invalid_var_format_string is None: - invalid_var_format_string = '%s' in settings.TEMPLATE_STRING_IF_INVALID - if invalid_var_format_string: - return settings.TEMPLATE_STRING_IF_INVALID % self.var - return settings.TEMPLATE_STRING_IF_INVALID - else: - obj = settings.TEMPLATE_STRING_IF_INVALID - else: - obj = self.var - for func, args in self.filters: - arg_vals = [] - for lookup, arg in args: - if not lookup: - arg_vals.append(mark_safe(arg)) - else: - arg_vals.append(arg.resolve(context)) - if getattr(func, 'expects_localtime', False): - obj = template_localtime(obj, context.use_tz) - if getattr(func, 'needs_autoescape', False): - new_obj = func(obj, autoescape=context.autoescape, *arg_vals) - else: - new_obj = func(obj, *arg_vals) - if getattr(func, 'is_safe', False) and isinstance(obj, SafeData): - obj = mark_safe(new_obj) - elif isinstance(obj, EscapeData): - obj = mark_for_escaping(new_obj) - else: - obj = new_obj - return obj - - def args_check(name, func, provided): - provided = list(provided) - plen = len(provided) - # Check to see if a decorator is providing the real function. - func = getattr(func, '_decorated_function', func) - args, varargs, varkw, defaults = getargspec(func) - # First argument is filter input. - args.pop(0) - if defaults: - nondefs = args[:-len(defaults)] - else: - nondefs = args - # Args without defaults must be provided. - try: - for arg in nondefs: - provided.pop(0) - except IndexError: - # Not enough - raise TemplateSyntaxError("%s requires %d arguments, %d provided" % - (name, len(nondefs), plen)) - - # Defaults can be overridden. - defaults = list(defaults) if defaults else [] - try: - for parg in provided: - defaults.pop(0) - except IndexError: - # Too many. - raise TemplateSyntaxError("%s requires %d arguments, %d provided" % - (name, len(nondefs), plen)) - - return True - args_check = staticmethod(args_check) - - def __str__(self): - return self.token - -def resolve_variable(path, context): - """ - Returns the resolved variable, which may contain attribute syntax, within - the given context. - - Deprecated; use the Variable class instead. - """ - return Variable(path).resolve(context) - -class Variable(object): - """ - A template variable, resolvable against a given context. The variable may - be a hard-coded string (if it begins and ends with single or double quote - marks):: - - >>> c = {'article': {'section':u'News'}} - >>> Variable('article.section').resolve(c) - u'News' - >>> Variable('article').resolve(c) - {'section': u'News'} - >>> class AClass: pass - >>> c = AClass() - >>> c.article = AClass() - >>> c.article.section = u'News' - - (The example assumes VARIABLE_ATTRIBUTE_SEPARATOR is '.') - """ - - def __init__(self, var): - self.var = var - self.literal = None - self.lookups = None - self.translate = False - self.message_context = None - - try: - # First try to treat this variable as a number. - # - # Note that this could cause an OverflowError here that we're not - # catching. Since this should only happen at compile time, that's - # probably OK. - self.literal = float(var) - - # So it's a float... is it an int? If the original value contained a - # dot or an "e" then it was a float, not an int. - if '.' not in var and 'e' not in var.lower(): - self.literal = int(self.literal) - - # "2." is invalid - if var.endswith('.'): - raise ValueError - - except ValueError: - # A ValueError means that the variable isn't a number. - if var.startswith('_(') and var.endswith(')'): - # The result of the lookup should be translated at rendering - # time. - self.translate = True - var = var[2:-1] - # If it's wrapped with quotes (single or double), then - # we're also dealing with a literal. - try: - self.literal = mark_safe(unescape_string_literal(var)) - except ValueError: - # Otherwise we'll set self.lookups so that resolve() knows we're - # dealing with a bonafide variable - if var.find(VARIABLE_ATTRIBUTE_SEPARATOR + '_') > -1 or var[0] == '_': - raise TemplateSyntaxError("Variables and attributes may " - "not begin with underscores: '%s'" % - var) - self.lookups = tuple(var.split(VARIABLE_ATTRIBUTE_SEPARATOR)) - - def resolve(self, context): - """Resolve this variable against a given context.""" - if self.lookups is not None: - # We're dealing with a variable that needs to be resolved - value = self._resolve_lookup(context) - else: - # We're dealing with a literal, so it's already been "resolved" - value = self.literal - if self.translate: - if self.message_context: - return pgettext_lazy(self.message_context, value) - else: - return ugettext_lazy(value) - return value - - def __repr__(self): - return "<%s: %r>" % (self.__class__.__name__, self.var) - - def __str__(self): - return self.var - - def _resolve_lookup(self, context): - """ - Performs resolution of a real variable (i.e. not a literal) against the - given context. - - As indicated by the method's name, this method is an implementation - detail and shouldn't be called by external code. Use Variable.resolve() - instead. - """ - current = context - try: # catch-all for silent variable failures - for bit in self.lookups: - try: # dictionary lookup - current = current[bit] - except (TypeError, AttributeError, KeyError, ValueError): - try: # attribute lookup - # Don't return class attributes if the class is the context: - if isinstance(current, BaseContext) and getattr(type(current), bit): - raise AttributeError - current = getattr(current, bit) - except (TypeError, AttributeError): - try: # list-index lookup - current = current[int(bit)] - except (IndexError, # list index out of range - ValueError, # invalid literal for int() - KeyError, # current is a dict without `int(bit)` key - TypeError): # unsubscriptable object - raise VariableDoesNotExist("Failed lookup for key " - "[%s] in %r", - (bit, current)) # missing attribute - if callable(current): - if getattr(current, 'do_not_call_in_templates', False): - pass - elif getattr(current, 'alters_data', False): - current = settings.TEMPLATE_STRING_IF_INVALID - else: - try: # method call (assuming no args required) - current = current() - except TypeError: # arguments *were* required - # GOTCHA: This will also catch any TypeError - # raised in the function itself. - current = settings.TEMPLATE_STRING_IF_INVALID # invalid method call - except Exception as e: - if getattr(e, 'silent_variable_failure', False): - current = settings.TEMPLATE_STRING_IF_INVALID - else: - raise - - return current - -class Node(object): - # Set this to True for nodes that must be first in the template (although - # they can be preceded by text nodes. - must_be_first = False - child_nodelists = ('nodelist',) - - def render(self, context): - """ - Return the node rendered as a string. - """ - pass - - def __iter__(self): - yield self - - def get_nodes_by_type(self, nodetype): - """ - Return a list of all nodes (within this node and its nodelist) - of the given type - """ - nodes = [] - if isinstance(self, nodetype): - nodes.append(self) - for attr in self.child_nodelists: - nodelist = getattr(self, attr, None) - if nodelist: - nodes.extend(nodelist.get_nodes_by_type(nodetype)) - return nodes - -class NodeList(list): - # Set to True the first time a non-TextNode is inserted by - # extend_nodelist(). - contains_nontext = False - - def render(self, context): - bits = [] - for node in self: - if isinstance(node, Node): - bit = self.render_node(node, context) - else: - bit = node - bits.append(force_text(bit)) - return mark_safe(''.join(bits)) - - def get_nodes_by_type(self, nodetype): - "Return a list of all nodes of the given type" - nodes = [] - for node in self: - nodes.extend(node.get_nodes_by_type(nodetype)) - return nodes - - def render_node(self, node, context): - return node.render(context) - -class TextNode(Node): - def __init__(self, s): - self.s = s - - def __repr__(self): - return force_str("<Text Node: '%s'>" % self.s[:25], 'ascii', - errors='replace') - - def render(self, context): - return self.s - -def render_value_in_context(value, context): - """ - Converts any value to a string to become part of a rendered template. This - means escaping, if required, and conversion to a unicode object. If value - is a string, it is expected to have already been translated. - """ - value = template_localtime(value, use_tz=context.use_tz) - value = localize(value, use_l10n=context.use_l10n) - value = force_text(value) - if ((context.autoescape and not isinstance(value, SafeData)) or - isinstance(value, EscapeData)): - return escape(value) - else: - return value - -class VariableNode(Node): - def __init__(self, filter_expression): - self.filter_expression = filter_expression - - def __repr__(self): - return "<Variable Node: %s>" % self.filter_expression - - def render(self, context): - try: - output = self.filter_expression.resolve(context) - except UnicodeDecodeError: - # Unicode conversion can fail sometimes for reasons out of our - # control (e.g. exception rendering). In that case, we fail - # quietly. - return '' - return render_value_in_context(output, context) - -# Regex for token keyword arguments -kwarg_re = re.compile(r"(?:(\w+)=)?(.+)") - -def token_kwargs(bits, parser, support_legacy=False): - """ - A utility method for parsing token keyword arguments. - - :param bits: A list containing remainder of the token (split by spaces) - that is to be checked for arguments. Valid arguments will be removed - from this list. - - :param support_legacy: If set to true ``True``, the legacy format - ``1 as foo`` will be accepted. Otherwise, only the standard ``foo=1`` - format is allowed. - - :returns: A dictionary of the arguments retrieved from the ``bits`` token - list. - - There is no requirement for all remaining token ``bits`` to be keyword - arguments, so the dictionary will be returned as soon as an invalid - argument format is reached. - """ - if not bits: - return {} - match = kwarg_re.match(bits[0]) - kwarg_format = match and match.group(1) - if not kwarg_format: - if not support_legacy: - return {} - if len(bits) < 3 or bits[1] != 'as': - return {} - - kwargs = {} - while bits: - if kwarg_format: - match = kwarg_re.match(bits[0]) - if not match or not match.group(1): - return kwargs - key, value = match.groups() - del bits[:1] - else: - if len(bits) < 3 or bits[1] != 'as': - return kwargs - key, value = bits[2], bits[0] - del bits[:3] - kwargs[key] = parser.compile_filter(value) - if bits and not kwarg_format: - if bits[0] != 'and': - return kwargs - del bits[:1] - return kwargs - -def parse_bits(parser, bits, params, varargs, varkw, defaults, - takes_context, name): - """ - Parses bits for template tag helpers (simple_tag, include_tag and - assignment_tag), in particular by detecting syntax errors and by - extracting positional and keyword arguments. - """ - if takes_context: - if params[0] == 'context': - params = params[1:] - else: - raise TemplateSyntaxError( - "'%s' is decorated with takes_context=True so it must " - "have a first argument of 'context'" % name) - args = [] - kwargs = {} - unhandled_params = list(params) - for bit in bits: - # First we try to extract a potential kwarg from the bit - kwarg = token_kwargs([bit], parser) - if kwarg: - # The kwarg was successfully extracted - param, value = list(six.iteritems(kwarg))[0] - if param not in params and varkw is None: - # An unexpected keyword argument was supplied - raise TemplateSyntaxError( - "'%s' received unexpected keyword argument '%s'" % - (name, param)) - elif param in kwargs: - # The keyword argument has already been supplied once - raise TemplateSyntaxError( - "'%s' received multiple values for keyword argument '%s'" % - (name, param)) - else: - # All good, record the keyword argument - kwargs[str(param)] = value - if param in unhandled_params: - # If using the keyword syntax for a positional arg, then - # consume it. - unhandled_params.remove(param) - else: - if kwargs: - raise TemplateSyntaxError( - "'%s' received some positional argument(s) after some " - "keyword argument(s)" % name) - else: - # Record the positional argument - args.append(parser.compile_filter(bit)) - try: - # Consume from the list of expected positional arguments - unhandled_params.pop(0) - except IndexError: - if varargs is None: - raise TemplateSyntaxError( - "'%s' received too many positional arguments" % - name) - if defaults is not None: - # Consider the last n params handled, where n is the - # number of defaults. - unhandled_params = unhandled_params[:-len(defaults)] - if unhandled_params: - # Some positional arguments were not supplied - raise TemplateSyntaxError( - "'%s' did not receive value(s) for the argument(s): %s" % - (name, ", ".join(["'%s'" % p for p in unhandled_params]))) - return args, kwargs - -def generic_tag_compiler(parser, token, params, varargs, varkw, defaults, - name, takes_context, node_class): - """ - Returns a template.Node subclass. - """ - bits = token.split_contents()[1:] - args, kwargs = parse_bits(parser, bits, params, varargs, varkw, - defaults, takes_context, name) - return node_class(takes_context, args, kwargs) - -class TagHelperNode(Node): - """ - Base class for tag helper nodes such as SimpleNode, InclusionNode and - AssignmentNode. Manages the positional and keyword arguments to be passed - to the decorated function. - """ - - def __init__(self, takes_context, args, kwargs): - self.takes_context = takes_context - self.args = args - self.kwargs = kwargs - - def get_resolved_arguments(self, context): - resolved_args = [var.resolve(context) for var in self.args] - if self.takes_context: - resolved_args = [context] + resolved_args - resolved_kwargs = dict((k, v.resolve(context)) - for k, v in self.kwargs.items()) - return resolved_args, resolved_kwargs - -class Library(object): - def __init__(self): - self.filters = {} - self.tags = {} - - def tag(self, name=None, compile_function=None): - if name is None and compile_function is None: - # @register.tag() - return self.tag_function - elif name is not None and compile_function is None: - if callable(name): - # @register.tag - return self.tag_function(name) - else: - # @register.tag('somename') or @register.tag(name='somename') - def dec(func): - return self.tag(name, func) - return dec - elif name is not None and compile_function is not None: - # register.tag('somename', somefunc) - self.tags[name] = compile_function - return compile_function - else: - raise InvalidTemplateLibrary("Unsupported arguments to " - "Library.tag: (%r, %r)", (name, compile_function)) - - def tag_function(self, func): - self.tags[getattr(func, "_decorated_function", func).__name__] = func - return func - - def filter(self, name=None, filter_func=None, **flags): - if name is None and filter_func is None: - # @register.filter() - def dec(func): - return self.filter_function(func, **flags) - return dec - - elif name is not None and filter_func is None: - if callable(name): - # @register.filter - return self.filter_function(name, **flags) - else: - # @register.filter('somename') or @register.filter(name='somename') - def dec(func): - return self.filter(name, func, **flags) - return dec - - elif name is not None and filter_func is not None: - # register.filter('somename', somefunc) - self.filters[name] = filter_func - for attr in ('expects_localtime', 'is_safe', 'needs_autoescape'): - if attr in flags: - value = flags[attr] - # set the flag on the filter for FilterExpression.resolve - setattr(filter_func, attr, value) - # set the flag on the innermost decorated function - # for decorators that need it e.g. stringfilter - if hasattr(filter_func, "_decorated_function"): - setattr(filter_func._decorated_function, attr, value) - filter_func._filter_name = name - return filter_func - else: - raise InvalidTemplateLibrary("Unsupported arguments to " - "Library.filter: (%r, %r)", (name, filter_func)) - - def filter_function(self, func, **flags): - name = getattr(func, "_decorated_function", func).__name__ - return self.filter(name, func, **flags) - - def simple_tag(self, func=None, takes_context=None, name=None): - def dec(func): - params, varargs, varkw, defaults = getargspec(func) - - class SimpleNode(TagHelperNode): - - def render(self, context): - resolved_args, resolved_kwargs = self.get_resolved_arguments(context) - return func(*resolved_args, **resolved_kwargs) - - function_name = (name or - getattr(func, '_decorated_function', func).__name__) - compile_func = partial(generic_tag_compiler, - params=params, varargs=varargs, varkw=varkw, - defaults=defaults, name=function_name, - takes_context=takes_context, node_class=SimpleNode) - compile_func.__doc__ = func.__doc__ - self.tag(function_name, compile_func) - return func - - if func is None: - # @register.simple_tag(...) - return dec - elif callable(func): - # @register.simple_tag - return dec(func) - else: - raise TemplateSyntaxError("Invalid arguments provided to simple_tag") - - def assignment_tag(self, func=None, takes_context=None, name=None): - def dec(func): - params, varargs, varkw, defaults = getargspec(func) - - class AssignmentNode(TagHelperNode): - def __init__(self, takes_context, args, kwargs, target_var): - super(AssignmentNode, self).__init__(takes_context, args, kwargs) - self.target_var = target_var - - def render(self, context): - resolved_args, resolved_kwargs = self.get_resolved_arguments(context) - context[self.target_var] = func(*resolved_args, **resolved_kwargs) - return '' - - function_name = (name or - getattr(func, '_decorated_function', func).__name__) - - def compile_func(parser, token): - bits = token.split_contents()[1:] - if len(bits) < 2 or bits[-2] != 'as': - raise TemplateSyntaxError( - "'%s' tag takes at least 2 arguments and the " - "second last argument must be 'as'" % function_name) - target_var = bits[-1] - bits = bits[:-2] - args, kwargs = parse_bits(parser, bits, params, - varargs, varkw, defaults, takes_context, function_name) - return AssignmentNode(takes_context, args, kwargs, target_var) - - compile_func.__doc__ = func.__doc__ - self.tag(function_name, compile_func) - return func - - if func is None: - # @register.assignment_tag(...) - return dec - elif callable(func): - # @register.assignment_tag - return dec(func) - else: - raise TemplateSyntaxError("Invalid arguments provided to assignment_tag") - - def inclusion_tag(self, file_name, context_class=Context, takes_context=False, name=None): - def dec(func): - params, varargs, varkw, defaults = getargspec(func) - - class InclusionNode(TagHelperNode): - - def render(self, context): - resolved_args, resolved_kwargs = self.get_resolved_arguments(context) - _dict = func(*resolved_args, **resolved_kwargs) - - if not getattr(self, 'nodelist', False): - from django.template.loader import get_template, select_template - if isinstance(file_name, Template): - t = file_name - elif not isinstance(file_name, six.string_types) and is_iterable(file_name): - t = select_template(file_name) - else: - t = get_template(file_name) - self.nodelist = t.nodelist - new_context = context_class(_dict, **{ - 'autoescape': context.autoescape, - 'current_app': context.current_app, - 'use_l10n': context.use_l10n, - 'use_tz': context.use_tz, - }) - # Copy across the CSRF token, if present, because - # inclusion tags are often used for forms, and we need - # instructions for using CSRF protection to be as simple - # as possible. - csrf_token = context.get('csrf_token', None) - if csrf_token is not None: - new_context['csrf_token'] = csrf_token - return self.nodelist.render(new_context) - - function_name = (name or - getattr(func, '_decorated_function', func).__name__) - compile_func = partial(generic_tag_compiler, - params=params, varargs=varargs, varkw=varkw, - defaults=defaults, name=function_name, - takes_context=takes_context, node_class=InclusionNode) - compile_func.__doc__ = func.__doc__ - self.tag(function_name, compile_func) - return func - return dec - -def is_library_missing(name): - """Check if library that failed to load cannot be found under any - templatetags directory or does exist but fails to import. - - Non-existing condition is checked recursively for each subpackage in cases - like <appdir>/templatetags/subpackage/package/module.py. - """ - # Don't bother to check if '.' is in name since any name will be prefixed - # with some template root. - path, module = name.rsplit('.', 1) - try: - package = import_module(path) - return not module_has_submodule(package, module) - except ImportError: - return is_library_missing(path) - -def import_library(taglib_module): - """ - Load a template tag library module. - - Verifies that the library contains a 'register' attribute, and - returns that attribute as the representation of the library - """ - try: - mod = import_module(taglib_module) - except ImportError as e: - # If the ImportError is because the taglib submodule does not exist, - # that's not an error that should be raised. If the submodule exists - # and raised an ImportError on the attempt to load it, that we want - # to raise. - if is_library_missing(taglib_module): - return None - else: - raise InvalidTemplateLibrary("ImportError raised loading %s: %s" % - (taglib_module, e)) - try: - return mod.register - except AttributeError: - raise InvalidTemplateLibrary("Template library %s does not have " - "a variable named 'register'" % - taglib_module) - -templatetags_modules = [] - -def get_templatetags_modules(): - """ - Return the list of all available template tag modules. - - Caches the result for faster access. - """ - global templatetags_modules - if not templatetags_modules: - _templatetags_modules = [] - # Populate list once per process. Mutate the local list first, and - # then assign it to the global name to ensure there are no cases where - # two threads try to populate it simultaneously. - for app_module in ['django'] + list(settings.INSTALLED_APPS): - try: - templatetag_module = '%s.templatetags' % app_module - import_module(templatetag_module) - _templatetags_modules.append(templatetag_module) - except ImportError: - continue - templatetags_modules = _templatetags_modules - return templatetags_modules - -def get_library(library_name): - """ - Load the template library module with the given name. - - If library is not already loaded loop over all templatetags modules - to locate it. - - {% load somelib %} and {% load someotherlib %} loops twice. - - Subsequent loads eg. {% load somelib %} in the same process will grab - the cached module from libraries. - """ - lib = libraries.get(library_name, None) - if not lib: - templatetags_modules = get_templatetags_modules() - tried_modules = [] - for module in templatetags_modules: - taglib_module = '%s.%s' % (module, library_name) - tried_modules.append(taglib_module) - lib = import_library(taglib_module) - if lib: - libraries[library_name] = lib - break - if not lib: - raise InvalidTemplateLibrary("Template library %s not found, " - "tried %s" % - (library_name, - ','.join(tried_modules))) - return lib - - -def add_to_builtins(module): - builtins.append(import_library(module)) - - -add_to_builtins('django.template.defaulttags') -add_to_builtins('django.template.defaultfilters') diff --git a/lib/python2.7/site-packages/django/template/context.py b/lib/python2.7/site-packages/django/template/context.py deleted file mode 100644 index 1ef7e88..0000000 --- a/lib/python2.7/site-packages/django/template/context.py +++ /dev/null @@ -1,169 +0,0 @@ -from copy import copy -from django.utils.module_loading import import_by_path - -# Cache of actual callables. -_standard_context_processors = None -# We need the CSRF processor no matter what the user has in their settings, -# because otherwise it is a security vulnerability, and we can't afford to leave -# this to human error or failure to read migration instructions. -_builtin_context_processors = ('django.core.context_processors.csrf',) - -class ContextPopException(Exception): - "pop() has been called more times than push()" - pass - -class BaseContext(object): - def __init__(self, dict_=None): - self._reset_dicts(dict_) - - def _reset_dicts(self, value=None): - builtins = {'True': True, 'False': False, 'None': None} - self.dicts = [builtins] - if value is not None: - self.dicts.append(value) - - def __copy__(self): - duplicate = copy(super(BaseContext, self)) - duplicate.dicts = self.dicts[:] - return duplicate - - def __repr__(self): - return repr(self.dicts) - - def __iter__(self): - for d in reversed(self.dicts): - yield d - - def push(self): - d = {} - self.dicts.append(d) - return d - - def pop(self): - if len(self.dicts) == 1: - raise ContextPopException - return self.dicts.pop() - - def __setitem__(self, key, value): - "Set a variable in the current context" - self.dicts[-1][key] = value - - def __getitem__(self, key): - "Get a variable's value, starting at the current context and going upward" - for d in reversed(self.dicts): - if key in d: - return d[key] - raise KeyError(key) - - def __delitem__(self, key): - "Delete a variable from the current context" - del self.dicts[-1][key] - - def has_key(self, key): - for d in self.dicts: - if key in d: - return True - return False - - def __contains__(self, key): - return self.has_key(key) - - def get(self, key, otherwise=None): - for d in reversed(self.dicts): - if key in d: - return d[key] - return otherwise - - def new(self, values=None): - """ - Returns a new context with the same properties, but with only the - values given in 'values' stored. - """ - new_context = copy(self) - new_context._reset_dicts(values) - return new_context - -class Context(BaseContext): - "A stack container for variable context" - def __init__(self, dict_=None, autoescape=True, current_app=None, - use_l10n=None, use_tz=None): - self.autoescape = autoescape - self.current_app = current_app - self.use_l10n = use_l10n - self.use_tz = use_tz - self.render_context = RenderContext() - super(Context, self).__init__(dict_) - - def __copy__(self): - duplicate = super(Context, self).__copy__() - duplicate.render_context = copy(self.render_context) - return duplicate - - def update(self, other_dict): - "Pushes other_dict to the stack of dictionaries in the Context" - if not hasattr(other_dict, '__getitem__'): - raise TypeError('other_dict must be a mapping (dictionary-like) object.') - self.dicts.append(other_dict) - return other_dict - -class RenderContext(BaseContext): - """ - A stack container for storing Template state. - - RenderContext simplifies the implementation of template Nodes by providing a - safe place to store state between invocations of a node's `render` method. - - The RenderContext also provides scoping rules that are more sensible for - 'template local' variables. The render context stack is pushed before each - template is rendered, creating a fresh scope with nothing in it. Name - resolution fails if a variable is not found at the top of the RequestContext - stack. Thus, variables are local to a specific template and don't affect the - rendering of other templates as they would if they were stored in the normal - template context. - """ - def __iter__(self): - for d in self.dicts[-1]: - yield d - - def has_key(self, key): - return key in self.dicts[-1] - - def get(self, key, otherwise=None): - d = self.dicts[-1] - if key in d: - return d[key] - return otherwise - -# This is a function rather than module-level procedural code because we only -# want it to execute if somebody uses RequestContext. -def get_standard_processors(): - from django.conf import settings - global _standard_context_processors - if _standard_context_processors is None: - processors = [] - collect = [] - collect.extend(_builtin_context_processors) - collect.extend(settings.TEMPLATE_CONTEXT_PROCESSORS) - for path in collect: - func = import_by_path(path) - processors.append(func) - _standard_context_processors = tuple(processors) - return _standard_context_processors - -class RequestContext(Context): - """ - This subclass of template.Context automatically populates itself using - the processors defined in TEMPLATE_CONTEXT_PROCESSORS. - Additional processors can be specified as a list of callables - using the "processors" keyword argument. - """ - def __init__(self, request, dict_=None, processors=None, current_app=None, - use_l10n=None, use_tz=None): - Context.__init__(self, dict_, current_app=current_app, - use_l10n=use_l10n, use_tz=use_tz) - if processors is None: - processors = () - else: - processors = tuple(processors) - for processor in get_standard_processors() + processors: - self.update(processor(request)) diff --git a/lib/python2.7/site-packages/django/template/debug.py b/lib/python2.7/site-packages/django/template/debug.py deleted file mode 100644 index 043dd91..0000000 --- a/lib/python2.7/site-packages/django/template/debug.py +++ /dev/null @@ -1,101 +0,0 @@ -from django.template.base import Lexer, Parser, tag_re, NodeList, VariableNode, TemplateSyntaxError -from django.utils.encoding import force_text -from django.utils.html import escape -from django.utils.safestring import SafeData, EscapeData -from django.utils.formats import localize -from django.utils.timezone import template_localtime - - -class DebugLexer(Lexer): - def __init__(self, template_string, origin): - super(DebugLexer, self).__init__(template_string, origin) - - def tokenize(self): - "Return a list of tokens from a given template_string" - result, upto = [], 0 - for match in tag_re.finditer(self.template_string): - start, end = match.span() - if start > upto: - result.append(self.create_token(self.template_string[upto:start], (upto, start), False)) - upto = start - result.append(self.create_token(self.template_string[start:end], (start, end), True)) - upto = end - last_bit = self.template_string[upto:] - if last_bit: - result.append(self.create_token(last_bit, (upto, upto + len(last_bit)), False)) - return result - - def create_token(self, token_string, source, in_tag): - token = super(DebugLexer, self).create_token(token_string, in_tag) - token.source = self.origin, source - return token - -class DebugParser(Parser): - def __init__(self, lexer): - super(DebugParser, self).__init__(lexer) - self.command_stack = [] - - def enter_command(self, command, token): - self.command_stack.append( (command, token.source) ) - - def exit_command(self): - self.command_stack.pop() - - def error(self, token, msg): - return self.source_error(token.source, msg) - - def source_error(self, source, msg): - e = TemplateSyntaxError(msg) - e.django_template_source = source - return e - - def create_nodelist(self): - return DebugNodeList() - - def create_variable_node(self, contents): - return DebugVariableNode(contents) - - def extend_nodelist(self, nodelist, node, token): - node.source = token.source - super(DebugParser, self).extend_nodelist(nodelist, node, token) - - def unclosed_block_tag(self, parse_until): - command, source = self.command_stack.pop() - msg = "Unclosed tag '%s'. Looking for one of: %s " % (command, ', '.join(parse_until)) - raise self.source_error(source, msg) - - def compile_filter_error(self, token, e): - if not hasattr(e, 'django_template_source'): - e.django_template_source = token.source - - def compile_function_error(self, token, e): - if not hasattr(e, 'django_template_source'): - e.django_template_source = token.source - -class DebugNodeList(NodeList): - def render_node(self, node, context): - try: - return node.render(context) - except Exception as e: - if not hasattr(e, 'django_template_source'): - e.django_template_source = node.source - raise - - -class DebugVariableNode(VariableNode): - def render(self, context): - try: - output = self.filter_expression.resolve(context) - output = template_localtime(output, use_tz=context.use_tz) - output = localize(output, use_l10n=context.use_l10n) - output = force_text(output) - except UnicodeDecodeError: - return '' - except Exception as e: - if not hasattr(e, 'django_template_source'): - e.django_template_source = self.source - raise - if (context.autoescape and not isinstance(output, SafeData)) or isinstance(output, EscapeData): - return escape(output) - else: - return output diff --git a/lib/python2.7/site-packages/django/template/defaultfilters.py b/lib/python2.7/site-packages/django/template/defaultfilters.py deleted file mode 100644 index 76c0121..0000000 --- a/lib/python2.7/site-packages/django/template/defaultfilters.py +++ /dev/null @@ -1,893 +0,0 @@ -"""Default variable filters.""" -from __future__ import unicode_literals - -import re -import random as random_module -from decimal import Decimal, InvalidOperation, Context, ROUND_HALF_UP -from functools import wraps -from pprint import pformat - -from django.template.base import Variable, Library, VariableDoesNotExist -from django.conf import settings -from django.utils import formats -from django.utils.dateformat import format, time_format -from django.utils.encoding import force_text, iri_to_uri -from django.utils.html import (conditional_escape, escapejs, fix_ampersands, - escape, urlize as urlize_impl, linebreaks, strip_tags, avoid_wrapping) -from django.utils.http import urlquote -from django.utils.text import Truncator, wrap, phone2numeric -from django.utils.safestring import mark_safe, SafeData, mark_for_escaping -from django.utils import six -from django.utils.timesince import timesince, timeuntil -from django.utils.translation import ugettext, ungettext -from django.utils.text import normalize_newlines - -register = Library() - -####################### -# STRING DECORATOR # -####################### - -def stringfilter(func): - """ - Decorator for filters which should only receive unicode objects. The object - passed as the first positional argument will be converted to a unicode - object. - """ - def _dec(*args, **kwargs): - if args: - args = list(args) - args[0] = force_text(args[0]) - if (isinstance(args[0], SafeData) and - getattr(_dec._decorated_function, 'is_safe', False)): - return mark_safe(func(*args, **kwargs)) - return func(*args, **kwargs) - - # Include a reference to the real function (used to check original - # arguments by the template parser, and to bear the 'is_safe' attribute - # when multiple decorators are applied). - _dec._decorated_function = getattr(func, '_decorated_function', func) - - return wraps(func)(_dec) - - -################### -# STRINGS # -################### - -@register.filter(is_safe=True) -@stringfilter -def addslashes(value): - """ - Adds slashes before quotes. Useful for escaping strings in CSV, for - example. Less useful for escaping JavaScript; use the ``escapejs`` - filter instead. - """ - return value.replace('\\', '\\\\').replace('"', '\\"').replace("'", "\\'") - -@register.filter(is_safe=True) -@stringfilter -def capfirst(value): - """Capitalizes the first character of the value.""" - return value and value[0].upper() + value[1:] - -@register.filter("escapejs") -@stringfilter -def escapejs_filter(value): - """Hex encodes characters for use in JavaScript strings.""" - return escapejs(value) - -@register.filter("fix_ampersands", is_safe=True) -@stringfilter -def fix_ampersands_filter(value): - """Replaces ampersands with ``&`` entities.""" - return fix_ampersands(value) - -# Values for testing floatformat input against infinity and NaN representations, -# which differ across platforms and Python versions. Some (i.e. old Windows -# ones) are not recognized by Decimal but we want to return them unchanged vs. -# returning an empty string as we do for completely invalid input. Note these -# need to be built up from values that are not inf/nan, since inf/nan values do -# not reload properly from .pyc files on Windows prior to some level of Python 2.5 -# (see Python Issue757815 and Issue1080440). -pos_inf = 1e200 * 1e200 -neg_inf = -1e200 * 1e200 -nan = (1e200 * 1e200) // (1e200 * 1e200) -special_floats = [str(pos_inf), str(neg_inf), str(nan)] - -@register.filter(is_safe=True) -def floatformat(text, arg=-1): - """ - Displays a float to a specified number of decimal places. - - If called without an argument, it displays the floating point number with - one decimal place -- but only if there's a decimal place to be displayed: - - * num1 = 34.23234 - * num2 = 34.00000 - * num3 = 34.26000 - * {{ num1|floatformat }} displays "34.2" - * {{ num2|floatformat }} displays "34" - * {{ num3|floatformat }} displays "34.3" - - If arg is positive, it will always display exactly arg number of decimal - places: - - * {{ num1|floatformat:3 }} displays "34.232" - * {{ num2|floatformat:3 }} displays "34.000" - * {{ num3|floatformat:3 }} displays "34.260" - - If arg is negative, it will display arg number of decimal places -- but - only if there are places to be displayed: - - * {{ num1|floatformat:"-3" }} displays "34.232" - * {{ num2|floatformat:"-3" }} displays "34" - * {{ num3|floatformat:"-3" }} displays "34.260" - - If the input float is infinity or NaN, the (platform-dependent) string - representation of that value will be displayed. - """ - - try: - input_val = force_text(text) - d = Decimal(input_val) - except UnicodeEncodeError: - return '' - except InvalidOperation: - if input_val in special_floats: - return input_val - try: - d = Decimal(force_text(float(text))) - except (ValueError, InvalidOperation, TypeError, UnicodeEncodeError): - return '' - try: - p = int(arg) - except ValueError: - return input_val - - try: - m = int(d) - d - except (ValueError, OverflowError, InvalidOperation): - return input_val - - if not m and p < 0: - return mark_safe(formats.number_format('%d' % (int(d)), 0)) - - if p == 0: - exp = Decimal(1) - else: - exp = Decimal('1.0') / (Decimal(10) ** abs(p)) - try: - # Set the precision high enough to avoid an exception, see #15789. - tupl = d.as_tuple() - units = len(tupl[1]) - tupl[2] - prec = abs(p) + units + 1 - - # Avoid conversion to scientific notation by accessing `sign`, `digits` - # and `exponent` from `Decimal.as_tuple()` directly. - sign, digits, exponent = d.quantize(exp, ROUND_HALF_UP, - Context(prec=prec)).as_tuple() - digits = [six.text_type(digit) for digit in reversed(digits)] - while len(digits) <= abs(exponent): - digits.append('0') - digits.insert(-exponent, '.') - if sign: - digits.append('-') - number = ''.join(reversed(digits)) - return mark_safe(formats.number_format(number, abs(p))) - except InvalidOperation: - return input_val - -@register.filter(is_safe=True) -@stringfilter -def iriencode(value): - """Escapes an IRI value for use in a URL.""" - return force_text(iri_to_uri(value)) - -@register.filter(is_safe=True, needs_autoescape=True) -@stringfilter -def linenumbers(value, autoescape=None): - """Displays text with line numbers.""" - lines = value.split('\n') - # Find the maximum width of the line count, for use with zero padding - # string format command - width = six.text_type(len(six.text_type(len(lines)))) - if not autoescape or isinstance(value, SafeData): - for i, line in enumerate(lines): - lines[i] = ("%0" + width + "d. %s") % (i + 1, line) - else: - for i, line in enumerate(lines): - lines[i] = ("%0" + width + "d. %s") % (i + 1, escape(line)) - return mark_safe('\n'.join(lines)) - -@register.filter(is_safe=True) -@stringfilter -def lower(value): - """Converts a string into all lowercase.""" - return value.lower() - -@register.filter(is_safe=False) -@stringfilter -def make_list(value): - """ - Returns the value turned into a list. - - For an integer, it's a list of digits. - For a string, it's a list of characters. - """ - return list(value) - -@register.filter(is_safe=True) -@stringfilter -def slugify(value): - """ - Converts to lowercase, removes non-word characters (alphanumerics and - underscores) and converts spaces to hyphens. Also strips leading and - trailing whitespace. - """ - from django.utils.text import slugify - return slugify(value) - -@register.filter(is_safe=True) -def stringformat(value, arg): - """ - Formats the variable according to the arg, a string formatting specifier. - - This specifier uses Python string formating syntax, with the exception that - the leading "%" is dropped. - - See http://docs.python.org/lib/typesseq-strings.html for documentation - of Python string formatting - """ - try: - return ("%" + six.text_type(arg)) % value - except (ValueError, TypeError): - return "" - -@register.filter(is_safe=True) -@stringfilter -def title(value): - """Converts a string into titlecase.""" - t = re.sub("([a-z])'([A-Z])", lambda m: m.group(0).lower(), value.title()) - return re.sub("\d([A-Z])", lambda m: m.group(0).lower(), t) - -@register.filter(is_safe=True) -@stringfilter -def truncatechars(value, arg): - """ - Truncates a string after a certain number of characters. - - Argument: Number of characters to truncate after. - """ - try: - length = int(arg) - except ValueError: # Invalid literal for int(). - return value # Fail silently. - return Truncator(value).chars(length) - -@register.filter(is_safe=True) -@stringfilter -def truncatewords(value, arg): - """ - Truncates a string after a certain number of words. - - Argument: Number of words to truncate after. - - Newlines within the string are removed. - """ - try: - length = int(arg) - except ValueError: # Invalid literal for int(). - return value # Fail silently. - return Truncator(value).words(length, truncate=' ...') - -@register.filter(is_safe=True) -@stringfilter -def truncatewords_html(value, arg): - """ - Truncates HTML after a certain number of words. - - Argument: Number of words to truncate after. - - Newlines in the HTML are preserved. - """ - try: - length = int(arg) - except ValueError: # invalid literal for int() - return value # Fail silently. - return Truncator(value).words(length, html=True, truncate=' ...') - -@register.filter(is_safe=False) -@stringfilter -def upper(value): - """Converts a string into all uppercase.""" - return value.upper() - -@register.filter(is_safe=False) -@stringfilter -def urlencode(value, safe=None): - """ - Escapes a value for use in a URL. - - Takes an optional ``safe`` parameter used to determine the characters which - should not be escaped by Django's ``urlquote`` method. If not provided, the - default safe characters will be used (but an empty string can be provided - when *all* characters should be escaped). - """ - kwargs = {} - if safe is not None: - kwargs['safe'] = safe - return urlquote(value, **kwargs) - -@register.filter(is_safe=True, needs_autoescape=True) -@stringfilter -def urlize(value, autoescape=None): - """Converts URLs in plain text into clickable links.""" - return mark_safe(urlize_impl(value, nofollow=True, autoescape=autoescape)) - -@register.filter(is_safe=True, needs_autoescape=True) -@stringfilter -def urlizetrunc(value, limit, autoescape=None): - """ - Converts URLs into clickable links, truncating URLs to the given character - limit, and adding 'rel=nofollow' attribute to discourage spamming. - - Argument: Length to truncate URLs to. - """ - return mark_safe(urlize_impl(value, trim_url_limit=int(limit), nofollow=True, - autoescape=autoescape)) - -@register.filter(is_safe=False) -@stringfilter -def wordcount(value): - """Returns the number of words.""" - return len(value.split()) - -@register.filter(is_safe=True) -@stringfilter -def wordwrap(value, arg): - """ - Wraps words at specified line length. - - Argument: number of characters to wrap the text at. - """ - return wrap(value, int(arg)) - -@register.filter(is_safe=True) -@stringfilter -def ljust(value, arg): - """ - Left-aligns the value in a field of a given width. - - Argument: field size. - """ - return value.ljust(int(arg)) - -@register.filter(is_safe=True) -@stringfilter -def rjust(value, arg): - """ - Right-aligns the value in a field of a given width. - - Argument: field size. - """ - return value.rjust(int(arg)) - -@register.filter(is_safe=True) -@stringfilter -def center(value, arg): - """Centers the value in a field of a given width.""" - return value.center(int(arg)) - -@register.filter -@stringfilter -def cut(value, arg): - """ - Removes all values of arg from the given string. - """ - safe = isinstance(value, SafeData) - value = value.replace(arg, '') - if safe and arg != ';': - return mark_safe(value) - return value - -################### -# HTML STRINGS # -################### - -@register.filter("escape", is_safe=True) -@stringfilter -def escape_filter(value): - """ - Marks the value as a string that should not be auto-escaped. - """ - return mark_for_escaping(value) - -@register.filter(is_safe=True) -@stringfilter -def force_escape(value): - """ - Escapes a string's HTML. This returns a new string containing the escaped - characters (as opposed to "escape", which marks the content for later - possible escaping). - """ - return escape(value) - -@register.filter("linebreaks", is_safe=True, needs_autoescape=True) -@stringfilter -def linebreaks_filter(value, autoescape=None): - """ - Replaces line breaks in plain text with appropriate HTML; a single - newline becomes an HTML line break (``<br />``) and a new line - followed by a blank line becomes a paragraph break (``</p>``). - """ - autoescape = autoescape and not isinstance(value, SafeData) - return mark_safe(linebreaks(value, autoescape)) - -@register.filter(is_safe=True, needs_autoescape=True) -@stringfilter -def linebreaksbr(value, autoescape=None): - """ - Converts all newlines in a piece of plain text to HTML line breaks - (``<br />``). - """ - autoescape = autoescape and not isinstance(value, SafeData) - value = normalize_newlines(value) - if autoescape: - value = escape(value) - return mark_safe(value.replace('\n', '<br />')) - -@register.filter(is_safe=True) -@stringfilter -def safe(value): - """ - Marks the value as a string that should not be auto-escaped. - """ - return mark_safe(value) - -@register.filter(is_safe=True) -def safeseq(value): - """ - A "safe" filter for sequences. Marks each element in the sequence, - individually, as safe, after converting them to unicode. Returns a list - with the results. - """ - return [mark_safe(force_text(obj)) for obj in value] - -@register.filter(is_safe=True) -@stringfilter -def removetags(value, tags): - """Removes a space separated list of [X]HTML tags from the output.""" - from django.utils.html import remove_tags - return remove_tags(value, tags) - -@register.filter(is_safe=True) -@stringfilter -def striptags(value): - """Strips all [X]HTML tags.""" - return strip_tags(value) - -################### -# LISTS # -################### - -@register.filter(is_safe=False) -def dictsort(value, arg): - """ - Takes a list of dicts, returns that list sorted by the property given in - the argument. - """ - try: - return sorted(value, key=Variable(arg).resolve) - except (TypeError, VariableDoesNotExist): - return '' - -@register.filter(is_safe=False) -def dictsortreversed(value, arg): - """ - Takes a list of dicts, returns that list sorted in reverse order by the - property given in the argument. - """ - try: - return sorted(value, key=Variable(arg).resolve, reverse=True) - except (TypeError, VariableDoesNotExist): - return '' - -@register.filter(is_safe=False) -def first(value): - """Returns the first item in a list.""" - try: - return value[0] - except IndexError: - return '' - -@register.filter(is_safe=True, needs_autoescape=True) -def join(value, arg, autoescape=None): - """ - Joins a list with a string, like Python's ``str.join(list)``. - """ - value = map(force_text, value) - if autoescape: - value = [conditional_escape(v) for v in value] - try: - data = conditional_escape(arg).join(value) - except AttributeError: # fail silently but nicely - return value - return mark_safe(data) - -@register.filter(is_safe=True) -def last(value): - "Returns the last item in a list" - try: - return value[-1] - except IndexError: - return '' - -@register.filter(is_safe=True) -def length(value): - """Returns the length of the value - useful for lists.""" - try: - return len(value) - except (ValueError, TypeError): - return '' - -@register.filter(is_safe=False) -def length_is(value, arg): - """Returns a boolean of whether the value's length is the argument.""" - try: - return len(value) == int(arg) - except (ValueError, TypeError): - return '' - -@register.filter(is_safe=True) -def random(value): - """Returns a random item from the list.""" - return random_module.choice(value) - -@register.filter("slice", is_safe=True) -def slice_filter(value, arg): - """ - Returns a slice of the list. - - Uses the same syntax as Python's list slicing; see - http://www.diveintopython3.net/native-datatypes.html#slicinglists - for an introduction. - """ - try: - bits = [] - for x in arg.split(':'): - if len(x) == 0: - bits.append(None) - else: - bits.append(int(x)) - return value[slice(*bits)] - - except (ValueError, TypeError): - return value # Fail silently. - -@register.filter(is_safe=True, needs_autoescape=True) -def unordered_list(value, autoescape=None): - """ - Recursively takes a self-nested list and returns an HTML unordered list -- - WITHOUT opening and closing <ul> tags. - - The list is assumed to be in the proper format. For example, if ``var`` - contains: ``['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]``, - then ``{{ var|unordered_list }}`` would return:: - - <li>States - <ul> - <li>Kansas - <ul> - <li>Lawrence</li> - <li>Topeka</li> - </ul> - </li> - <li>Illinois</li> - </ul> - </li> - """ - if autoescape: - escaper = conditional_escape - else: - escaper = lambda x: x - def convert_old_style_list(list_): - """ - Converts old style lists to the new easier to understand format. - - The old list format looked like: - ['Item 1', [['Item 1.1', []], ['Item 1.2', []]] - - And it is converted to: - ['Item 1', ['Item 1.1', 'Item 1.2]] - """ - if not isinstance(list_, (tuple, list)) or len(list_) != 2: - return list_, False - first_item, second_item = list_ - if second_item == []: - return [first_item], True - try: - # see if second item is iterable - iter(second_item) - except TypeError: - return list_, False - old_style_list = True - new_second_item = [] - for sublist in second_item: - item, old_style_list = convert_old_style_list(sublist) - if not old_style_list: - break - new_second_item.extend(item) - if old_style_list: - second_item = new_second_item - return [first_item, second_item], old_style_list - def _helper(list_, tabs=1): - indent = '\t' * tabs - output = [] - - list_length = len(list_) - i = 0 - while i < list_length: - title = list_[i] - sublist = '' - sublist_item = None - if isinstance(title, (list, tuple)): - sublist_item = title - title = '' - elif i < list_length - 1: - next_item = list_[i+1] - if next_item and isinstance(next_item, (list, tuple)): - # The next item is a sub-list. - sublist_item = next_item - # We've processed the next item now too. - i += 1 - if sublist_item: - sublist = _helper(sublist_item, tabs+1) - sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist, - indent, indent) - output.append('%s<li>%s%s</li>' % (indent, - escaper(force_text(title)), sublist)) - i += 1 - return '\n'.join(output) - value, converted = convert_old_style_list(value) - return mark_safe(_helper(value)) - -################### -# INTEGERS # -################### - -@register.filter(is_safe=False) -def add(value, arg): - """Adds the arg to the value.""" - try: - return int(value) + int(arg) - except (ValueError, TypeError): - try: - return value + arg - except Exception: - return '' - -@register.filter(is_safe=False) -def get_digit(value, arg): - """ - Given a whole number, returns the requested digit of it, where 1 is the - right-most digit, 2 is the second-right-most digit, etc. Returns the - original value for invalid input (if input or argument is not an integer, - or if argument is less than 1). Otherwise, output is always an integer. - """ - try: - arg = int(arg) - value = int(value) - except ValueError: - return value # Fail silently for an invalid argument - if arg < 1: - return value - try: - return int(str(value)[-arg]) - except IndexError: - return 0 - -################### -# DATES # -################### - -@register.filter(expects_localtime=True, is_safe=False) -def date(value, arg=None): - """Formats a date according to the given format.""" - if value in (None, ''): - return '' - if arg is None: - arg = settings.DATE_FORMAT - try: - return formats.date_format(value, arg) - except AttributeError: - try: - return format(value, arg) - except AttributeError: - return '' - -@register.filter(expects_localtime=True, is_safe=False) -def time(value, arg=None): - """Formats a time according to the given format.""" - if value in (None, ''): - return '' - if arg is None: - arg = settings.TIME_FORMAT - try: - return formats.time_format(value, arg) - except AttributeError: - try: - return time_format(value, arg) - except AttributeError: - return '' - -@register.filter("timesince", is_safe=False) -def timesince_filter(value, arg=None): - """Formats a date as the time since that date (i.e. "4 days, 6 hours").""" - if not value: - return '' - try: - if arg: - return timesince(value, arg) - return timesince(value) - except (ValueError, TypeError): - return '' - -@register.filter("timeuntil", is_safe=False) -def timeuntil_filter(value, arg=None): - """Formats a date as the time until that date (i.e. "4 days, 6 hours").""" - if not value: - return '' - try: - return timeuntil(value, arg) - except (ValueError, TypeError): - return '' - -################### -# LOGIC # -################### - -@register.filter(is_safe=False) -def default(value, arg): - """If value is unavailable, use given default.""" - return value or arg - -@register.filter(is_safe=False) -def default_if_none(value, arg): - """If value is None, use given default.""" - if value is None: - return arg - return value - -@register.filter(is_safe=False) -def divisibleby(value, arg): - """Returns True if the value is devisible by the argument.""" - return int(value) % int(arg) == 0 - -@register.filter(is_safe=False) -def yesno(value, arg=None): - """ - Given a string mapping values for true, false and (optionally) None, - returns one of those strings according to the value: - - ========== ====================== ================================== - Value Argument Outputs - ========== ====================== ================================== - ``True`` ``"yeah,no,maybe"`` ``yeah`` - ``False`` ``"yeah,no,maybe"`` ``no`` - ``None`` ``"yeah,no,maybe"`` ``maybe`` - ``None`` ``"yeah,no"`` ``"no"`` (converts None to False - if no mapping for None is given. - ========== ====================== ================================== - """ - if arg is None: - arg = ugettext('yes,no,maybe') - bits = arg.split(',') - if len(bits) < 2: - return value # Invalid arg. - try: - yes, no, maybe = bits - except ValueError: - # Unpack list of wrong size (no "maybe" value provided). - yes, no, maybe = bits[0], bits[1], bits[1] - if value is None: - return maybe - if value: - return yes - return no - -################### -# MISC # -################### - -@register.filter(is_safe=True) -def filesizeformat(bytes): - """ - Formats the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB, - 102 bytes, etc). - """ - try: - bytes = float(bytes) - except (TypeError,ValueError,UnicodeDecodeError): - value = ungettext("%(size)d byte", "%(size)d bytes", 0) % {'size': 0} - return avoid_wrapping(value) - - filesize_number_format = lambda value: formats.number_format(round(value, 1), 1) - - KB = 1<<10 - MB = 1<<20 - GB = 1<<30 - TB = 1<<40 - PB = 1<<50 - - if bytes < KB: - value = ungettext("%(size)d byte", "%(size)d bytes", bytes) % {'size': bytes} - elif bytes < MB: - value = ugettext("%s KB") % filesize_number_format(bytes / KB) - elif bytes < GB: - value = ugettext("%s MB") % filesize_number_format(bytes / MB) - elif bytes < TB: - value = ugettext("%s GB") % filesize_number_format(bytes / GB) - elif bytes < PB: - value = ugettext("%s TB") % filesize_number_format(bytes / TB) - else: - value = ugettext("%s PB") % filesize_number_format(bytes / PB) - - return avoid_wrapping(value) - -@register.filter(is_safe=False) -def pluralize(value, arg='s'): - """ - Returns a plural suffix if the value is not 1. By default, 's' is used as - the suffix: - - * If value is 0, vote{{ value|pluralize }} displays "0 votes". - * If value is 1, vote{{ value|pluralize }} displays "1 vote". - * If value is 2, vote{{ value|pluralize }} displays "2 votes". - - If an argument is provided, that string is used instead: - - * If value is 0, class{{ value|pluralize:"es" }} displays "0 classes". - * If value is 1, class{{ value|pluralize:"es" }} displays "1 class". - * If value is 2, class{{ value|pluralize:"es" }} displays "2 classes". - - If the provided argument contains a comma, the text before the comma is - used for the singular case and the text after the comma is used for the - plural case: - - * If value is 0, cand{{ value|pluralize:"y,ies" }} displays "0 candies". - * If value is 1, cand{{ value|pluralize:"y,ies" }} displays "1 candy". - * If value is 2, cand{{ value|pluralize:"y,ies" }} displays "2 candies". - """ - if not ',' in arg: - arg = ',' + arg - bits = arg.split(',') - if len(bits) > 2: - return '' - singular_suffix, plural_suffix = bits[:2] - - try: - if int(value) != 1: - return plural_suffix - except ValueError: # Invalid string that's not a number. - pass - except TypeError: # Value isn't a string or a number; maybe it's a list? - try: - if len(value) != 1: - return plural_suffix - except TypeError: # len() of unsized object. - pass - return singular_suffix - -@register.filter("phone2numeric", is_safe=True) -def phone2numeric_filter(value): - """Takes a phone number and converts it in to its numerical equivalent.""" - return phone2numeric(value) - -@register.filter(is_safe=True) -def pprint(value): - """A wrapper around pprint.pprint -- for debugging, really.""" - try: - return pformat(value) - except Exception as e: - return "Error in formatting: %s" % force_text(e, errors="replace") diff --git a/lib/python2.7/site-packages/django/template/defaulttags.py b/lib/python2.7/site-packages/django/template/defaulttags.py deleted file mode 100644 index 554c7bc..0000000 --- a/lib/python2.7/site-packages/django/template/defaulttags.py +++ /dev/null @@ -1,1409 +0,0 @@ -"""Default tags used by the template system, available to all templates.""" -from __future__ import unicode_literals - -import os -import sys -import re -from datetime import datetime -from itertools import groupby, cycle as itertools_cycle -import warnings - -from django.conf import settings -from django.template.base import (Node, NodeList, Template, Context, Library, - TemplateSyntaxError, VariableDoesNotExist, InvalidTemplateLibrary, - BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, - SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END, - VARIABLE_ATTRIBUTE_SEPARATOR, get_library, token_kwargs, kwarg_re, - render_value_in_context) -from django.template.smartif import IfParser, Literal -from django.template.defaultfilters import date -from django.utils.encoding import smart_text -from django.utils.safestring import mark_safe -from django.utils.html import format_html -from django.utils import six -from django.utils import timezone - -register = Library() - -class AutoEscapeControlNode(Node): - """Implements the actions of the autoescape tag.""" - def __init__(self, setting, nodelist): - self.setting, self.nodelist = setting, nodelist - - def render(self, context): - old_setting = context.autoescape - context.autoescape = self.setting - output = self.nodelist.render(context) - context.autoescape = old_setting - if self.setting: - return mark_safe(output) - else: - return output - -class CommentNode(Node): - def render(self, context): - return '' - -class CsrfTokenNode(Node): - def render(self, context): - csrf_token = context.get('csrf_token', None) - if csrf_token: - if csrf_token == 'NOTPROVIDED': - return format_html("") - else: - return format_html("<input type='hidden' name='csrfmiddlewaretoken' value='{0}' />", csrf_token) - else: - # It's very probable that the token is missing because of - # misconfiguration, so we raise a warning - from django.conf import settings - if settings.DEBUG: - warnings.warn("A {% csrf_token %} was used in a template, but the context did not provide the value. This is usually caused by not using RequestContext.") - return '' - -class CycleNode(Node): - def __init__(self, cyclevars, variable_name=None, silent=False, escape=False): - self.cyclevars = cyclevars - self.variable_name = variable_name - self.silent = silent - self.escape = escape # only while the "future" version exists - - def render(self, context): - if self not in context.render_context: - # First time the node is rendered in template - context.render_context[self] = itertools_cycle(self.cyclevars) - cycle_iter = context.render_context[self] - value = next(cycle_iter).resolve(context) - if self.variable_name: - context[self.variable_name] = value - if self.silent: - return '' - if not self.escape: - value = mark_safe(value) - return render_value_in_context(value, context) - -class DebugNode(Node): - def render(self, context): - from pprint import pformat - output = [pformat(val) for val in context] - output.append('\n\n') - output.append(pformat(sys.modules)) - return ''.join(output) - -class FilterNode(Node): - def __init__(self, filter_expr, nodelist): - self.filter_expr, self.nodelist = filter_expr, nodelist - - def render(self, context): - output = self.nodelist.render(context) - # Apply filters. - context.update({'var': output}) - filtered = self.filter_expr.resolve(context) - context.pop() - return filtered - -class FirstOfNode(Node): - def __init__(self, variables, escape=False): - self.vars = variables - self.escape = escape # only while the "future" version exists - - def render(self, context): - for var in self.vars: - value = var.resolve(context, True) - if value: - if not self.escape: - value = mark_safe(value) - return render_value_in_context(value, context) - return '' - -class ForNode(Node): - child_nodelists = ('nodelist_loop', 'nodelist_empty') - - def __init__(self, loopvars, sequence, is_reversed, nodelist_loop, nodelist_empty=None): - self.loopvars, self.sequence = loopvars, sequence - self.is_reversed = is_reversed - self.nodelist_loop = nodelist_loop - if nodelist_empty is None: - self.nodelist_empty = NodeList() - else: - self.nodelist_empty = nodelist_empty - - def __repr__(self): - reversed_text = ' reversed' if self.is_reversed else '' - return "<For Node: for %s in %s, tail_len: %d%s>" % \ - (', '.join(self.loopvars), self.sequence, len(self.nodelist_loop), - reversed_text) - - def __iter__(self): - for node in self.nodelist_loop: - yield node - for node in self.nodelist_empty: - yield node - - def render(self, context): - if 'forloop' in context: - parentloop = context['forloop'] - else: - parentloop = {} - context.push() - try: - values = self.sequence.resolve(context, True) - except VariableDoesNotExist: - values = [] - if values is None: - values = [] - if not hasattr(values, '__len__'): - values = list(values) - len_values = len(values) - if len_values < 1: - context.pop() - return self.nodelist_empty.render(context) - nodelist = NodeList() - if self.is_reversed: - values = reversed(values) - unpack = len(self.loopvars) > 1 - # Create a forloop value in the context. We'll update counters on each - # iteration just below. - loop_dict = context['forloop'] = {'parentloop': parentloop} - for i, item in enumerate(values): - # Shortcuts for current loop iteration number. - loop_dict['counter0'] = i - loop_dict['counter'] = i+1 - # Reverse counter iteration numbers. - loop_dict['revcounter'] = len_values - i - loop_dict['revcounter0'] = len_values - i - 1 - # Boolean values designating first and last times through loop. - loop_dict['first'] = (i == 0) - loop_dict['last'] = (i == len_values - 1) - - pop_context = False - if unpack: - # If there are multiple loop variables, unpack the item into - # them. - try: - unpacked_vars = dict(zip(self.loopvars, item)) - except TypeError: - pass - else: - pop_context = True - context.update(unpacked_vars) - else: - context[self.loopvars[0]] = item - # In TEMPLATE_DEBUG mode provide source of the node which - # actually raised the exception - if settings.TEMPLATE_DEBUG: - for node in self.nodelist_loop: - try: - nodelist.append(node.render(context)) - except Exception as e: - if not hasattr(e, 'django_template_source'): - e.django_template_source = node.source - raise - else: - for node in self.nodelist_loop: - nodelist.append(node.render(context)) - if pop_context: - # The loop variables were pushed on to the context so pop them - # off again. This is necessary because the tag lets the length - # of loopvars differ to the length of each set of items and we - # don't want to leave any vars from the previous loop on the - # context. - context.pop() - context.pop() - return nodelist.render(context) - -class IfChangedNode(Node): - child_nodelists = ('nodelist_true', 'nodelist_false') - - def __init__(self, nodelist_true, nodelist_false, *varlist): - self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false - self._varlist = varlist - - def render(self, context): - # Init state storage - state_frame = self._get_context_stack_frame(context) - if self not in state_frame: - state_frame[self] = None - - nodelist_true_output = None - try: - if self._varlist: - # Consider multiple parameters. This automatically behaves - # like an OR evaluation of the multiple variables. - compare_to = [var.resolve(context, True) for var in self._varlist] - else: - # The "{% ifchanged %}" syntax (without any variables) compares the rendered output. - compare_to = nodelist_true_output = self.nodelist_true.render(context) - except VariableDoesNotExist: - compare_to = None - - if compare_to != state_frame[self]: - state_frame[self] = compare_to - return nodelist_true_output or self.nodelist_true.render(context) # render true block if not already rendered - elif self.nodelist_false: - return self.nodelist_false.render(context) - return '' - - def _get_context_stack_frame(self, context): - # The Context object behaves like a stack where each template tag can create a new scope. - # Find the place where to store the state to detect changes. - if 'forloop' in context: - # Ifchanged is bound to the local for loop. - # When there is a loop-in-loop, the state is bound to the inner loop, - # so it resets when the outer loop continues. - return context['forloop'] - else: - # Using ifchanged outside loops. Effectively this is a no-op because the state is associated with 'self'. - return context.render_context - -class IfEqualNode(Node): - child_nodelists = ('nodelist_true', 'nodelist_false') - - def __init__(self, var1, var2, nodelist_true, nodelist_false, negate): - self.var1, self.var2 = var1, var2 - self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false - self.negate = negate - - def __repr__(self): - return "<IfEqualNode>" - - def render(self, context): - val1 = self.var1.resolve(context, True) - val2 = self.var2.resolve(context, True) - if (self.negate and val1 != val2) or (not self.negate and val1 == val2): - return self.nodelist_true.render(context) - return self.nodelist_false.render(context) - -class IfNode(Node): - - def __init__(self, conditions_nodelists): - self.conditions_nodelists = conditions_nodelists - - def __repr__(self): - return "<IfNode>" - - def __iter__(self): - for _, nodelist in self.conditions_nodelists: - for node in nodelist: - yield node - - @property - def nodelist(self): - return NodeList(node for _, nodelist in self.conditions_nodelists for node in nodelist) - - def render(self, context): - for condition, nodelist in self.conditions_nodelists: - - if condition is not None: # if / elif clause - try: - match = condition.eval(context) - except VariableDoesNotExist: - match = None - else: # else clause - match = True - - if match: - return nodelist.render(context) - - return '' - -class RegroupNode(Node): - def __init__(self, target, expression, var_name): - self.target, self.expression = target, expression - self.var_name = var_name - - def resolve_expression(self, obj, context): - # This method is called for each object in self.target. See regroup() - # for the reason why we temporarily put the object in the context. - context[self.var_name] = obj - return self.expression.resolve(context, True) - - def render(self, context): - obj_list = self.target.resolve(context, True) - if obj_list == None: - # target variable wasn't found in context; fail silently. - context[self.var_name] = [] - return '' - # List of dictionaries in the format: - # {'grouper': 'key', 'list': [list of contents]}. - context[self.var_name] = [ - {'grouper': key, 'list': list(val)} - for key, val in - groupby(obj_list, lambda obj: self.resolve_expression(obj, context)) - ] - return '' - -def include_is_allowed(filepath): - filepath = os.path.abspath(filepath) - for root in settings.ALLOWED_INCLUDE_ROOTS: - if filepath.startswith(root): - return True - return False - -class SsiNode(Node): - def __init__(self, filepath, parsed): - self.filepath = filepath - self.parsed = parsed - - def render(self, context): - filepath = self.filepath.resolve(context) - - if not include_is_allowed(filepath): - if settings.DEBUG: - return "[Didn't have permission to include file]" - else: - return '' # Fail silently for invalid includes. - try: - with open(filepath, 'r') as fp: - output = fp.read() - except IOError: - output = '' - if self.parsed: - try: - t = Template(output, name=filepath) - return t.render(context) - except TemplateSyntaxError as e: - if settings.DEBUG: - return "[Included template had syntax error: %s]" % e - else: - return '' # Fail silently for invalid included templates. - return output - -class LoadNode(Node): - def render(self, context): - return '' - -class NowNode(Node): - def __init__(self, format_string): - self.format_string = format_string - - def render(self, context): - tzinfo = timezone.get_current_timezone() if settings.USE_TZ else None - return date(datetime.now(tz=tzinfo), self.format_string) - -class SpacelessNode(Node): - def __init__(self, nodelist): - self.nodelist = nodelist - - def render(self, context): - from django.utils.html import strip_spaces_between_tags - return strip_spaces_between_tags(self.nodelist.render(context).strip()) - -class TemplateTagNode(Node): - mapping = {'openblock': BLOCK_TAG_START, - 'closeblock': BLOCK_TAG_END, - 'openvariable': VARIABLE_TAG_START, - 'closevariable': VARIABLE_TAG_END, - 'openbrace': SINGLE_BRACE_START, - 'closebrace': SINGLE_BRACE_END, - 'opencomment': COMMENT_TAG_START, - 'closecomment': COMMENT_TAG_END, - } - - def __init__(self, tagtype): - self.tagtype = tagtype - - def render(self, context): - return self.mapping.get(self.tagtype, '') - -class URLNode(Node): - def __init__(self, view_name, args, kwargs, asvar): - self.view_name = view_name - self.args = args - self.kwargs = kwargs - self.asvar = asvar - - def render(self, context): - from django.core.urlresolvers import reverse, NoReverseMatch - args = [arg.resolve(context) for arg in self.args] - kwargs = dict([(smart_text(k, 'ascii'), v.resolve(context)) - for k, v in self.kwargs.items()]) - - view_name = self.view_name.resolve(context) - - if not view_name: - raise NoReverseMatch("'url' requires a non-empty first argument. " - "The syntax changed in Django 1.5, see the docs.") - - # Try to look up the URL twice: once given the view name, and again - # relative to what we guess is the "main" app. If they both fail, - # re-raise the NoReverseMatch unless we're using the - # {% url ... as var %} construct in which case return nothing. - url = '' - try: - url = reverse(view_name, args=args, kwargs=kwargs, current_app=context.current_app) - except NoReverseMatch: - exc_info = sys.exc_info() - if settings.SETTINGS_MODULE: - project_name = settings.SETTINGS_MODULE.split('.')[0] - try: - url = reverse(project_name + '.' + view_name, - args=args, kwargs=kwargs, - current_app=context.current_app) - except NoReverseMatch: - if self.asvar is None: - # Re-raise the original exception, not the one with - # the path relative to the project. This makes a - # better error message. - six.reraise(*exc_info) - else: - if self.asvar is None: - raise - - if self.asvar: - context[self.asvar] = url - return '' - else: - return url - -class VerbatimNode(Node): - def __init__(self, content): - self.content = content - - def render(self, context): - return self.content - -class WidthRatioNode(Node): - def __init__(self, val_expr, max_expr, max_width): - self.val_expr = val_expr - self.max_expr = max_expr - self.max_width = max_width - - def render(self, context): - try: - value = self.val_expr.resolve(context) - max_value = self.max_expr.resolve(context) - max_width = int(self.max_width.resolve(context)) - except VariableDoesNotExist: - return '' - except (ValueError, TypeError): - raise TemplateSyntaxError("widthratio final argument must be a number") - try: - value = float(value) - max_value = float(max_value) - ratio = (value / max_value) * max_width - except ZeroDivisionError: - return '0' - except (ValueError, TypeError): - return '' - return str(int(round(ratio))) - -class WithNode(Node): - def __init__(self, var, name, nodelist, extra_context=None): - self.nodelist = nodelist - # var and name are legacy attributes, being left in case they are used - # by third-party subclasses of this Node. - self.extra_context = extra_context or {} - if name: - self.extra_context[name] = var - - def __repr__(self): - return "<WithNode>" - - def render(self, context): - values = dict([(key, val.resolve(context)) for key, val in - six.iteritems(self.extra_context)]) - context.update(values) - output = self.nodelist.render(context) - context.pop() - return output - -@register.tag -def autoescape(parser, token): - """ - Force autoescape behavior for this block. - """ - # token.split_contents() isn't useful here because this tag doesn't accept variable as arguments - args = token.contents.split() - if len(args) != 2: - raise TemplateSyntaxError("'autoescape' tag requires exactly one argument.") - arg = args[1] - if arg not in ('on', 'off'): - raise TemplateSyntaxError("'autoescape' argument should be 'on' or 'off'") - nodelist = parser.parse(('endautoescape',)) - parser.delete_first_token() - return AutoEscapeControlNode((arg == 'on'), nodelist) - -@register.tag -def comment(parser, token): - """ - Ignores everything between ``{% comment %}`` and ``{% endcomment %}``. - """ - parser.skip_past('endcomment') - return CommentNode() - -@register.tag -def cycle(parser, token, escape=False): - """ - Cycles among the given strings each time this tag is encountered. - - Within a loop, cycles among the given strings each time through - the loop:: - - {% for o in some_list %} - <tr class="{% cycle 'row1' 'row2' %}"> - ... - </tr> - {% endfor %} - - Outside of a loop, give the values a unique name the first time you call - it, then use that name each sucessive time through:: - - <tr class="{% cycle 'row1' 'row2' 'row3' as rowcolors %}">...</tr> - <tr class="{% cycle rowcolors %}">...</tr> - <tr class="{% cycle rowcolors %}">...</tr> - - You can use any number of values, separated by spaces. Commas can also - be used to separate values; if a comma is used, the cycle values are - interpreted as literal strings. - - The optional flag "silent" can be used to prevent the cycle declaration - from returning any value:: - - {% for o in some_list %} - {% cycle 'row1' 'row2' as rowcolors silent %} - <tr class="{{ rowcolors }}">{% include "subtemplate.html " %}</tr> - {% endfor %} - - """ - if not escape: - warnings.warn( - "'The `cycle` template tag is changing to escape its arguments; " - "the non-autoescaping version is deprecated. Load it " - "from the `future` tag library to start using the new behavior.", - PendingDeprecationWarning, stacklevel=2) - - # Note: This returns the exact same node on each {% cycle name %} call; - # that is, the node object returned from {% cycle a b c as name %} and the - # one returned from {% cycle name %} are the exact same object. This - # shouldn't cause problems (heh), but if it does, now you know. - # - # Ugly hack warning: This stuffs the named template dict into parser so - # that names are only unique within each template (as opposed to using - # a global variable, which would make cycle names have to be unique across - # *all* templates. - - args = token.split_contents() - - if len(args) < 2: - raise TemplateSyntaxError("'cycle' tag requires at least two arguments") - - if ',' in args[1]: - # Backwards compatibility: {% cycle a,b %} or {% cycle a,b as foo %} - # case. - args[1:2] = ['"%s"' % arg for arg in args[1].split(",")] - - if len(args) == 2: - # {% cycle foo %} case. - name = args[1] - if not hasattr(parser, '_namedCycleNodes'): - raise TemplateSyntaxError("No named cycles in template. '%s' is not defined" % name) - if not name in parser._namedCycleNodes: - raise TemplateSyntaxError("Named cycle '%s' does not exist" % name) - return parser._namedCycleNodes[name] - - as_form = False - - if len(args) > 4: - # {% cycle ... as foo [silent] %} case. - if args[-3] == "as": - if args[-1] != "silent": - raise TemplateSyntaxError("Only 'silent' flag is allowed after cycle's name, not '%s'." % args[-1]) - as_form = True - silent = True - args = args[:-1] - elif args[-2] == "as": - as_form = True - silent = False - - if as_form: - name = args[-1] - values = [parser.compile_filter(arg) for arg in args[1:-2]] - node = CycleNode(values, name, silent=silent, escape=escape) - if not hasattr(parser, '_namedCycleNodes'): - parser._namedCycleNodes = {} - parser._namedCycleNodes[name] = node - else: - values = [parser.compile_filter(arg) for arg in args[1:]] - node = CycleNode(values, escape=escape) - return node - -@register.tag -def csrf_token(parser, token): - return CsrfTokenNode() - -@register.tag -def debug(parser, token): - """ - Outputs a whole load of debugging information, including the current - context and imported modules. - - Sample usage:: - - <pre> - {% debug %} - </pre> - """ - return DebugNode() - -@register.tag('filter') -def do_filter(parser, token): - """ - Filters the contents of the block through variable filters. - - Filters can also be piped through each other, and they can have - arguments -- just like in variable syntax. - - Sample usage:: - - {% filter force_escape|lower %} - This text will be HTML-escaped, and will appear in lowercase. - {% endfilter %} - - Note that the ``escape`` and ``safe`` filters are not acceptable arguments. - Instead, use the ``autoescape`` tag to manage autoescaping for blocks of - template code. - """ - # token.split_contents() isn't useful here because this tag doesn't accept variable as arguments - _, rest = token.contents.split(None, 1) - filter_expr = parser.compile_filter("var|%s" % (rest)) - for func, unused in filter_expr.filters: - filter_name = getattr(func, '_filter_name', None) - if filter_name in ('escape', 'safe'): - raise TemplateSyntaxError('"filter %s" is not permitted. Use the "autoescape" tag instead.' % filter_name) - nodelist = parser.parse(('endfilter',)) - parser.delete_first_token() - return FilterNode(filter_expr, nodelist) - -@register.tag -def firstof(parser, token, escape=False): - """ - Outputs the first variable passed that is not False, without escaping. - - Outputs nothing if all the passed variables are False. - - Sample usage:: - - {% firstof var1 var2 var3 %} - - This is equivalent to:: - - {% if var1 %} - {{ var1|safe }} - {% elif var2 %} - {{ var2|safe }} - {% elif var3 %} - {{ var3|safe }} - {% endif %} - - but obviously much cleaner! - - You can also use a literal string as a fallback value in case all - passed variables are False:: - - {% firstof var1 var2 var3 "fallback value" %} - - If you want to escape the output, use a filter tag:: - - {% filter force_escape %} - {% firstof var1 var2 var3 "fallback value" %} - {% endfilter %} - - """ - if not escape: - warnings.warn( - "'The `firstof` template tag is changing to escape its arguments; " - "the non-autoescaping version is deprecated. Load it " - "from the `future` tag library to start using the new behavior.", - PendingDeprecationWarning, stacklevel=2) - - bits = token.split_contents()[1:] - if len(bits) < 1: - raise TemplateSyntaxError("'firstof' statement requires at least one argument") - return FirstOfNode([parser.compile_filter(bit) for bit in bits], escape=escape) - -@register.tag('for') -def do_for(parser, token): - """ - Loops over each item in an array. - - For example, to display a list of athletes given ``athlete_list``:: - - <ul> - {% for athlete in athlete_list %} - <li>{{ athlete.name }}</li> - {% endfor %} - </ul> - - You can loop over a list in reverse by using - ``{% for obj in list reversed %}``. - - You can also unpack multiple values from a two-dimensional array:: - - {% for key,value in dict.items %} - {{ key }}: {{ value }} - {% endfor %} - - The ``for`` tag can take an optional ``{% empty %}`` clause that will - be displayed if the given array is empty or could not be found:: - - <ul> - {% for athlete in athlete_list %} - <li>{{ athlete.name }}</li> - {% empty %} - <li>Sorry, no athletes in this list.</li> - {% endfor %} - <ul> - - The above is equivalent to -- but shorter, cleaner, and possibly faster - than -- the following:: - - <ul> - {% if althete_list %} - {% for athlete in athlete_list %} - <li>{{ athlete.name }}</li> - {% endfor %} - {% else %} - <li>Sorry, no athletes in this list.</li> - {% endif %} - </ul> - - The for loop sets a number of variables available within the loop: - - ========================== ================================================ - Variable Description - ========================== ================================================ - ``forloop.counter`` The current iteration of the loop (1-indexed) - ``forloop.counter0`` The current iteration of the loop (0-indexed) - ``forloop.revcounter`` The number of iterations from the end of the - loop (1-indexed) - ``forloop.revcounter0`` The number of iterations from the end of the - loop (0-indexed) - ``forloop.first`` True if this is the first time through the loop - ``forloop.last`` True if this is the last time through the loop - ``forloop.parentloop`` For nested loops, this is the loop "above" the - current one - ========================== ================================================ - - """ - bits = token.split_contents() - if len(bits) < 4: - raise TemplateSyntaxError("'for' statements should have at least four" - " words: %s" % token.contents) - - is_reversed = bits[-1] == 'reversed' - in_index = -3 if is_reversed else -2 - if bits[in_index] != 'in': - raise TemplateSyntaxError("'for' statements should use the format" - " 'for x in y': %s" % token.contents) - - loopvars = re.split(r' *, *', ' '.join(bits[1:in_index])) - for var in loopvars: - if not var or ' ' in var: - raise TemplateSyntaxError("'for' tag received an invalid argument:" - " %s" % token.contents) - - sequence = parser.compile_filter(bits[in_index+1]) - nodelist_loop = parser.parse(('empty', 'endfor',)) - token = parser.next_token() - if token.contents == 'empty': - nodelist_empty = parser.parse(('endfor',)) - parser.delete_first_token() - else: - nodelist_empty = None - return ForNode(loopvars, sequence, is_reversed, nodelist_loop, nodelist_empty) - -def do_ifequal(parser, token, negate): - bits = list(token.split_contents()) - if len(bits) != 3: - raise TemplateSyntaxError("%r takes two arguments" % bits[0]) - end_tag = 'end' + bits[0] - nodelist_true = parser.parse(('else', end_tag)) - token = parser.next_token() - if token.contents == 'else': - nodelist_false = parser.parse((end_tag,)) - parser.delete_first_token() - else: - nodelist_false = NodeList() - val1 = parser.compile_filter(bits[1]) - val2 = parser.compile_filter(bits[2]) - return IfEqualNode(val1, val2, nodelist_true, nodelist_false, negate) - -@register.tag -def ifequal(parser, token): - """ - Outputs the contents of the block if the two arguments equal each other. - - Examples:: - - {% ifequal user.id comment.user_id %} - ... - {% endifequal %} - - {% ifnotequal user.id comment.user_id %} - ... - {% else %} - ... - {% endifnotequal %} - """ - return do_ifequal(parser, token, False) - -@register.tag -def ifnotequal(parser, token): - """ - Outputs the contents of the block if the two arguments are not equal. - See ifequal. - """ - return do_ifequal(parser, token, True) - -class TemplateLiteral(Literal): - def __init__(self, value, text): - self.value = value - self.text = text # for better error messages - - def display(self): - return self.text - - def eval(self, context): - return self.value.resolve(context, ignore_failures=True) - -class TemplateIfParser(IfParser): - error_class = TemplateSyntaxError - - def __init__(self, parser, *args, **kwargs): - self.template_parser = parser - super(TemplateIfParser, self).__init__(*args, **kwargs) - - def create_var(self, value): - return TemplateLiteral(self.template_parser.compile_filter(value), value) - -@register.tag('if') -def do_if(parser, token): - """ - The ``{% if %}`` tag evaluates a variable, and if that variable is "true" - (i.e., exists, is not empty, and is not a false boolean value), the - contents of the block are output: - - :: - - {% if athlete_list %} - Number of athletes: {{ athlete_list|count }} - {% elif athlete_in_locker_room_list %} - Athletes should be out of the locker room soon! - {% else %} - No athletes. - {% endif %} - - In the above, if ``athlete_list`` is not empty, the number of athletes will - be displayed by the ``{{ athlete_list|count }}`` variable. - - As you can see, the ``if`` tag may take one or several `` {% elif %}`` - clauses, as well as an ``{% else %}`` clause that will be displayed if all - previous conditions fail. These clauses are optional. - - ``if`` tags may use ``or``, ``and`` or ``not`` to test a number of - variables or to negate a given variable:: - - {% if not athlete_list %} - There are no athletes. - {% endif %} - - {% if athlete_list or coach_list %} - There are some athletes or some coaches. - {% endif %} - - {% if athlete_list and coach_list %} - Both atheletes and coaches are available. - {% endif %} - - {% if not athlete_list or coach_list %} - There are no athletes, or there are some coaches. - {% endif %} - - {% if athlete_list and not coach_list %} - There are some athletes and absolutely no coaches. - {% endif %} - - Comparison operators are also available, and the use of filters is also - allowed, for example:: - - {% if articles|length >= 5 %}...{% endif %} - - Arguments and operators _must_ have a space between them, so - ``{% if 1>2 %}`` is not a valid if tag. - - All supported operators are: ``or``, ``and``, ``in``, ``not in`` - ``==`` (or ``=``), ``!=``, ``>``, ``>=``, ``<`` and ``<=``. - - Operator precedence follows Python. - """ - # {% if ... %} - bits = token.split_contents()[1:] - condition = TemplateIfParser(parser, bits).parse() - nodelist = parser.parse(('elif', 'else', 'endif')) - conditions_nodelists = [(condition, nodelist)] - token = parser.next_token() - - # {% elif ... %} (repeatable) - while token.contents.startswith('elif'): - bits = token.split_contents()[1:] - condition = TemplateIfParser(parser, bits).parse() - nodelist = parser.parse(('elif', 'else', 'endif')) - conditions_nodelists.append((condition, nodelist)) - token = parser.next_token() - - # {% else %} (optional) - if token.contents == 'else': - nodelist = parser.parse(('endif',)) - conditions_nodelists.append((None, nodelist)) - token = parser.next_token() - - # {% endif %} - assert token.contents == 'endif' - - return IfNode(conditions_nodelists) - - -@register.tag -def ifchanged(parser, token): - """ - Checks if a value has changed from the last iteration of a loop. - - The ``{% ifchanged %}`` block tag is used within a loop. It has two - possible uses. - - 1. Checks its own rendered contents against its previous state and only - displays the content if it has changed. For example, this displays a - list of days, only displaying the month if it changes:: - - <h1>Archive for {{ year }}</h1> - - {% for date in days %} - {% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %} - <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a> - {% endfor %} - - 2. If given one or more variables, check whether any variable has changed. - For example, the following shows the date every time it changes, while - showing the hour if either the hour or the date has changed:: - - {% for date in days %} - {% ifchanged date.date %} {{ date.date }} {% endifchanged %} - {% ifchanged date.hour date.date %} - {{ date.hour }} - {% endifchanged %} - {% endfor %} - """ - bits = token.split_contents() - nodelist_true = parser.parse(('else', 'endifchanged')) - token = parser.next_token() - if token.contents == 'else': - nodelist_false = parser.parse(('endifchanged',)) - parser.delete_first_token() - else: - nodelist_false = NodeList() - values = [parser.compile_filter(bit) for bit in bits[1:]] - return IfChangedNode(nodelist_true, nodelist_false, *values) - -@register.tag -def ssi(parser, token): - """ - Outputs the contents of a given file into the page. - - Like a simple "include" tag, the ``ssi`` tag includes the contents - of another file -- which must be specified using an absolute path -- - in the current page:: - - {% ssi "/home/html/ljworld.com/includes/right_generic.html" %} - - If the optional "parsed" parameter is given, the contents of the included - file are evaluated as template code, with the current context:: - - {% ssi "/home/html/ljworld.com/includes/right_generic.html" parsed %} - """ - bits = token.split_contents() - parsed = False - if len(bits) not in (2, 3): - raise TemplateSyntaxError("'ssi' tag takes one argument: the path to" - " the file to be included") - if len(bits) == 3: - if bits[2] == 'parsed': - parsed = True - else: - raise TemplateSyntaxError("Second (optional) argument to %s tag" - " must be 'parsed'" % bits[0]) - filepath = parser.compile_filter(bits[1]) - return SsiNode(filepath, parsed) - -@register.tag -def load(parser, token): - """ - Loads a custom template tag set. - - For example, to load the template tags in - ``django/templatetags/news/photos.py``:: - - {% load news.photos %} - - Can also be used to load an individual tag/filter from - a library:: - - {% load byline from news %} - - """ - # token.split_contents() isn't useful here because this tag doesn't accept variable as arguments - bits = token.contents.split() - if len(bits) >= 4 and bits[-2] == "from": - try: - taglib = bits[-1] - lib = get_library(taglib) - except InvalidTemplateLibrary as e: - raise TemplateSyntaxError("'%s' is not a valid tag library: %s" % - (taglib, e)) - else: - temp_lib = Library() - for name in bits[1:-2]: - if name in lib.tags: - temp_lib.tags[name] = lib.tags[name] - # a name could be a tag *and* a filter, so check for both - if name in lib.filters: - temp_lib.filters[name] = lib.filters[name] - elif name in lib.filters: - temp_lib.filters[name] = lib.filters[name] - else: - raise TemplateSyntaxError("'%s' is not a valid tag or filter in tag library '%s'" % - (name, taglib)) - parser.add_library(temp_lib) - else: - for taglib in bits[1:]: - # add the library to the parser - try: - lib = get_library(taglib) - parser.add_library(lib) - except InvalidTemplateLibrary as e: - raise TemplateSyntaxError("'%s' is not a valid tag library: %s" % - (taglib, e)) - return LoadNode() - -@register.tag -def now(parser, token): - """ - Displays the date, formatted according to the given string. - - Uses the same format as PHP's ``date()`` function; see http://php.net/date - for all the possible values. - - Sample usage:: - - It is {% now "jS F Y H:i" %} - """ - bits = token.split_contents() - if len(bits) != 2: - raise TemplateSyntaxError("'now' statement takes one argument") - format_string = bits[1][1:-1] - return NowNode(format_string) - -@register.tag -def regroup(parser, token): - """ - Regroups a list of alike objects by a common attribute. - - This complex tag is best illustrated by use of an example: say that - ``people`` is a list of ``Person`` objects that have ``first_name``, - ``last_name``, and ``gender`` attributes, and you'd like to display a list - that looks like: - - * Male: - * George Bush - * Bill Clinton - * Female: - * Margaret Thatcher - * Colendeeza Rice - * Unknown: - * Pat Smith - - The following snippet of template code would accomplish this dubious task:: - - {% regroup people by gender as grouped %} - <ul> - {% for group in grouped %} - <li>{{ group.grouper }} - <ul> - {% for item in group.list %} - <li>{{ item }}</li> - {% endfor %} - </ul> - {% endfor %} - </ul> - - As you can see, ``{% regroup %}`` populates a variable with a list of - objects with ``grouper`` and ``list`` attributes. ``grouper`` contains the - item that was grouped by; ``list`` contains the list of objects that share - that ``grouper``. In this case, ``grouper`` would be ``Male``, ``Female`` - and ``Unknown``, and ``list`` is the list of people with those genders. - - Note that ``{% regroup %}`` does not work when the list to be grouped is not - sorted by the key you are grouping by! This means that if your list of - people was not sorted by gender, you'd need to make sure it is sorted - before using it, i.e.:: - - {% regroup people|dictsort:"gender" by gender as grouped %} - - """ - bits = token.split_contents() - if len(bits) != 6: - raise TemplateSyntaxError("'regroup' tag takes five arguments") - target = parser.compile_filter(bits[1]) - if bits[2] != 'by': - raise TemplateSyntaxError("second argument to 'regroup' tag must be 'by'") - if bits[4] != 'as': - raise TemplateSyntaxError("next-to-last argument to 'regroup' tag must" - " be 'as'") - var_name = bits[5] - # RegroupNode will take each item in 'target', put it in the context under - # 'var_name', evaluate 'var_name'.'expression' in the current context, and - # group by the resulting value. After all items are processed, it will - # save the final result in the context under 'var_name', thus clearing the - # temporary values. This hack is necessary because the template engine - # doesn't provide a context-aware equivalent of Python's getattr. - expression = parser.compile_filter(var_name + - VARIABLE_ATTRIBUTE_SEPARATOR + - bits[3]) - return RegroupNode(target, expression, var_name) - -@register.tag -def spaceless(parser, token): - """ - Removes whitespace between HTML tags, including tab and newline characters. - - Example usage:: - - {% spaceless %} - <p> - <a href="foo/">Foo</a> - </p> - {% endspaceless %} - - This example would return this HTML:: - - <p><a href="foo/">Foo</a></p> - - Only space between *tags* is normalized -- not space between tags and text. - In this example, the space around ``Hello`` won't be stripped:: - - {% spaceless %} - <strong> - Hello - </strong> - {% endspaceless %} - """ - nodelist = parser.parse(('endspaceless',)) - parser.delete_first_token() - return SpacelessNode(nodelist) - -@register.tag -def templatetag(parser, token): - """ - Outputs one of the bits used to compose template tags. - - Since the template system has no concept of "escaping", to display one of - the bits used in template tags, you must use the ``{% templatetag %}`` tag. - - The argument tells which template bit to output: - - ================== ======= - Argument Outputs - ================== ======= - ``openblock`` ``{%`` - ``closeblock`` ``%}`` - ``openvariable`` ``{{`` - ``closevariable`` ``}}`` - ``openbrace`` ``{`` - ``closebrace`` ``}`` - ``opencomment`` ``{#`` - ``closecomment`` ``#}`` - ================== ======= - """ - # token.split_contents() isn't useful here because this tag doesn't accept variable as arguments - bits = token.contents.split() - if len(bits) != 2: - raise TemplateSyntaxError("'templatetag' statement takes one argument") - tag = bits[1] - if tag not in TemplateTagNode.mapping: - raise TemplateSyntaxError("Invalid templatetag argument: '%s'." - " Must be one of: %s" % - (tag, list(TemplateTagNode.mapping))) - return TemplateTagNode(tag) - -@register.tag -def url(parser, token): - """ - Returns an absolute URL matching given view with its parameters. - - This is a way to define links that aren't tied to a particular URL - configuration:: - - {% url "path.to.some_view" arg1 arg2 %} - - or - - {% url "path.to.some_view" name1=value1 name2=value2 %} - - The first argument is a path to a view. It can be an absolute Python path - or just ``app_name.view_name`` without the project name if the view is - located inside the project. - - Other arguments are space-separated values that will be filled in place of - positional and keyword arguments in the URL. Don't mix positional and - keyword arguments. - - All arguments for the URL should be present. - - For example if you have a view ``app_name.client`` taking client's id and - the corresponding line in a URLconf looks like this:: - - ('^client/(\d+)/$', 'app_name.client') - - and this app's URLconf is included into the project's URLconf under some - path:: - - ('^clients/', include('project_name.app_name.urls')) - - then in a template you can create a link for a certain client like this:: - - {% url "app_name.client" client.id %} - - The URL will look like ``/clients/client/123/``. - - The first argument can also be a named URL instead of the Python path to - the view callable. For example if the URLconf entry looks like this:: - - url('^client/(\d+)/$', name='client-detail-view') - - then in the template you can use:: - - {% url "client-detail-view" client.id %} - - There is even another possible value type for the first argument. It can be - the name of a template variable that will be evaluated to obtain the view - name or the URL name, e.g.:: - - {% with view_path="app_name.client" %} - {% url view_path client.id %} - {% endwith %} - - or, - - {% with url_name="client-detail-view" %} - {% url url_name client.id %} - {% endwith %} - - """ - bits = token.split_contents() - if len(bits) < 2: - raise TemplateSyntaxError("'%s' takes at least one argument" - " (path to a view)" % bits[0]) - try: - viewname = parser.compile_filter(bits[1]) - except TemplateSyntaxError as exc: - exc.args = (exc.args[0] + ". " - "The syntax of 'url' changed in Django 1.5, see the docs."), - raise - args = [] - kwargs = {} - asvar = None - bits = bits[2:] - if len(bits) >= 2 and bits[-2] == 'as': - asvar = bits[-1] - bits = bits[:-2] - - if len(bits): - for bit in bits: - match = kwarg_re.match(bit) - if not match: - raise TemplateSyntaxError("Malformed arguments to url tag") - name, value = match.groups() - if name: - kwargs[name] = parser.compile_filter(value) - else: - args.append(parser.compile_filter(value)) - - return URLNode(viewname, args, kwargs, asvar) - -@register.tag -def verbatim(parser, token): - """ - Stops the template engine from rendering the contents of this block tag. - - Usage:: - - {% verbatim %} - {% don't process this %} - {% endverbatim %} - - You can also designate a specific closing tag block (allowing the - unrendered use of ``{% endverbatim %}``):: - - {% verbatim myblock %} - ... - {% endverbatim myblock %} - """ - nodelist = parser.parse(('endverbatim',)) - parser.delete_first_token() - return VerbatimNode(nodelist.render(Context())) - -@register.tag -def widthratio(parser, token): - """ - For creating bar charts and such, this tag calculates the ratio of a given - value to a maximum value, and then applies that ratio to a constant. - - For example:: - - <img src='bar.gif' height='10' width='{% widthratio this_value max_value max_width %}' /> - - If ``this_value`` is 175, ``max_value`` is 200, and ``max_width`` is 100, - the image in the above example will be 88 pixels wide - (because 175/200 = .875; .875 * 100 = 87.5 which is rounded up to 88). - """ - bits = token.split_contents() - if len(bits) != 4: - raise TemplateSyntaxError("widthratio takes three arguments") - tag, this_value_expr, max_value_expr, max_width = bits - - return WidthRatioNode(parser.compile_filter(this_value_expr), - parser.compile_filter(max_value_expr), - parser.compile_filter(max_width)) - -@register.tag('with') -def do_with(parser, token): - """ - Adds one or more values to the context (inside of this block) for caching - and easy access. - - For example:: - - {% with total=person.some_sql_method %} - {{ total }} object{{ total|pluralize }} - {% endwith %} - - Multiple values can be added to the context:: - - {% with foo=1 bar=2 %} - ... - {% endwith %} - - The legacy format of ``{% with person.some_sql_method as total %}`` is - still accepted. - """ - bits = token.split_contents() - remaining_bits = bits[1:] - extra_context = token_kwargs(remaining_bits, parser, support_legacy=True) - if not extra_context: - raise TemplateSyntaxError("%r expected at least one variable " - "assignment" % bits[0]) - if remaining_bits: - raise TemplateSyntaxError("%r received an invalid token: %r" % - (bits[0], remaining_bits[0])) - nodelist = parser.parse(('endwith',)) - parser.delete_first_token() - return WithNode(None, None, nodelist, extra_context=extra_context) diff --git a/lib/python2.7/site-packages/django/template/loader.py b/lib/python2.7/site-packages/django/template/loader.py deleted file mode 100644 index 6df4e43..0000000 --- a/lib/python2.7/site-packages/django/template/loader.py +++ /dev/null @@ -1,188 +0,0 @@ -# Wrapper for loading templates from storage of some sort (e.g. filesystem, database). -# -# This uses the TEMPLATE_LOADERS setting, which is a list of loaders to use. -# Each loader is expected to have this interface: -# -# callable(name, dirs=[]) -# -# name is the template name. -# dirs is an optional list of directories to search instead of TEMPLATE_DIRS. -# -# The loader should return a tuple of (template_source, path). The path returned -# might be shown to the user for debugging purposes, so it should identify where -# the template was loaded from. -# -# A loader may return an already-compiled template instead of the actual -# template source. In that case the path returned should be None, since the -# path information is associated with the template during the compilation, -# which has already been done. -# -# Each loader should have an "is_usable" attribute set. This is a boolean that -# specifies whether the loader can be used in this Python installation. Each -# loader is responsible for setting this when it's initialized. -# -# For example, the eggs loader (which is capable of loading templates from -# Python eggs) sets is_usable to False if the "pkg_resources" module isn't -# installed, because pkg_resources is necessary to read eggs. - -from django.core.exceptions import ImproperlyConfigured -from django.template.base import Origin, Template, Context, TemplateDoesNotExist, add_to_builtins -from django.conf import settings -from django.utils.module_loading import import_by_path -from django.utils import six - -template_source_loaders = None - -class BaseLoader(object): - is_usable = False - - def __init__(self, *args, **kwargs): - pass - - def __call__(self, template_name, template_dirs=None): - return self.load_template(template_name, template_dirs) - - def load_template(self, template_name, template_dirs=None): - source, display_name = self.load_template_source(template_name, template_dirs) - origin = make_origin(display_name, self.load_template_source, template_name, template_dirs) - try: - template = get_template_from_string(source, origin, template_name) - return template, None - except TemplateDoesNotExist: - # If compiling the template we found raises TemplateDoesNotExist, back off to - # returning the source and display name for the template we were asked to load. - # This allows for correct identification (later) of the actual template that does - # not exist. - return source, display_name - - def load_template_source(self, template_name, template_dirs=None): - """ - Returns a tuple containing the source and origin for the given template - name. - - """ - raise NotImplementedError - - def reset(self): - """ - Resets any state maintained by the loader instance (e.g., cached - templates or cached loader modules). - - """ - pass - -class LoaderOrigin(Origin): - def __init__(self, display_name, loader, name, dirs): - super(LoaderOrigin, self).__init__(display_name) - self.loader, self.loadname, self.dirs = loader, name, dirs - - def reload(self): - return self.loader(self.loadname, self.dirs)[0] - -def make_origin(display_name, loader, name, dirs): - if settings.TEMPLATE_DEBUG and display_name: - return LoaderOrigin(display_name, loader, name, dirs) - else: - return None - -def find_template_loader(loader): - if isinstance(loader, (tuple, list)): - loader, args = loader[0], loader[1:] - else: - args = [] - if isinstance(loader, six.string_types): - TemplateLoader = import_by_path(loader) - - if hasattr(TemplateLoader, 'load_template_source'): - func = TemplateLoader(*args) - else: - # Try loading module the old way - string is full path to callable - if args: - raise ImproperlyConfigured("Error importing template source loader %s - can't pass arguments to function-based loader." % loader) - func = TemplateLoader - - if not func.is_usable: - import warnings - warnings.warn("Your TEMPLATE_LOADERS setting includes %r, but your Python installation doesn't support that type of template loading. Consider removing that line from TEMPLATE_LOADERS." % loader) - return None - else: - return func - else: - raise ImproperlyConfigured('Loader does not define a "load_template" callable template source loader') - -def find_template(name, dirs=None): - # Calculate template_source_loaders the first time the function is executed - # because putting this logic in the module-level namespace may cause - # circular import errors. See Django ticket #1292. - global template_source_loaders - if template_source_loaders is None: - loaders = [] - for loader_name in settings.TEMPLATE_LOADERS: - loader = find_template_loader(loader_name) - if loader is not None: - loaders.append(loader) - template_source_loaders = tuple(loaders) - for loader in template_source_loaders: - try: - source, display_name = loader(name, dirs) - return (source, make_origin(display_name, loader, name, dirs)) - except TemplateDoesNotExist: - pass - raise TemplateDoesNotExist(name) - -def get_template(template_name): - """ - Returns a compiled Template object for the given template name, - handling template inheritance recursively. - """ - template, origin = find_template(template_name) - if not hasattr(template, 'render'): - # template needs to be compiled - template = get_template_from_string(template, origin, template_name) - return template - -def get_template_from_string(source, origin=None, name=None): - """ - Returns a compiled Template object for the given template code, - handling template inheritance recursively. - """ - return Template(source, origin, name) - -def render_to_string(template_name, dictionary=None, context_instance=None): - """ - Loads the given template_name and renders it with the given dictionary as - context. The template_name may be a string to load a single template using - get_template, or it may be a tuple to use select_template to find one of - the templates in the list. Returns a string. - """ - dictionary = dictionary or {} - if isinstance(template_name, (list, tuple)): - t = select_template(template_name) - else: - t = get_template(template_name) - if not context_instance: - return t.render(Context(dictionary)) - # Add the dictionary to the context stack, ensuring it gets removed again - # to keep the context_instance in the same state it started in. - context_instance.update(dictionary) - try: - return t.render(context_instance) - finally: - context_instance.pop() - -def select_template(template_name_list): - "Given a list of template names, returns the first that can be loaded." - if not template_name_list: - raise TemplateDoesNotExist("No template names provided") - not_found = [] - for template_name in template_name_list: - try: - return get_template(template_name) - except TemplateDoesNotExist as e: - if e.args[0] not in not_found: - not_found.append(e.args[0]) - continue - # If we get here, none of the templates could be loaded - raise TemplateDoesNotExist(', '.join(not_found)) - -add_to_builtins('django.template.loader_tags') diff --git a/lib/python2.7/site-packages/django/template/loader_tags.py b/lib/python2.7/site-packages/django/template/loader_tags.py deleted file mode 100644 index 85ffcf1..0000000 --- a/lib/python2.7/site-packages/django/template/loader_tags.py +++ /dev/null @@ -1,265 +0,0 @@ -from collections import defaultdict - -from django.conf import settings -from django.template.base import TemplateSyntaxError, Library, Node, TextNode,\ - token_kwargs, Variable -from django.template.loader import get_template -from django.utils.safestring import mark_safe -from django.utils import six - -register = Library() - -BLOCK_CONTEXT_KEY = 'block_context' - -class ExtendsError(Exception): - pass - -class BlockContext(object): - def __init__(self): - # Dictionary of FIFO queues. - self.blocks = defaultdict(list) - - def add_blocks(self, blocks): - for name, block in six.iteritems(blocks): - self.blocks[name].insert(0, block) - - def pop(self, name): - try: - return self.blocks[name].pop() - except IndexError: - return None - - def push(self, name, block): - self.blocks[name].append(block) - - def get_block(self, name): - try: - return self.blocks[name][-1] - except IndexError: - return None - -class BlockNode(Node): - def __init__(self, name, nodelist, parent=None): - self.name, self.nodelist, self.parent = name, nodelist, parent - - def __repr__(self): - return "<Block Node: %s. Contents: %r>" % (self.name, self.nodelist) - - def render(self, context): - block_context = context.render_context.get(BLOCK_CONTEXT_KEY) - context.push() - if block_context is None: - context['block'] = self - result = self.nodelist.render(context) - else: - push = block = block_context.pop(self.name) - if block is None: - block = self - # Create new block so we can store context without thread-safety issues. - block = BlockNode(block.name, block.nodelist) - block.context = context - context['block'] = block - result = block.nodelist.render(context) - if push is not None: - block_context.push(self.name, push) - context.pop() - return result - - def super(self): - render_context = self.context.render_context - if (BLOCK_CONTEXT_KEY in render_context and - render_context[BLOCK_CONTEXT_KEY].get_block(self.name) is not None): - return mark_safe(self.render(self.context)) - return '' - -class ExtendsNode(Node): - must_be_first = True - - def __init__(self, nodelist, parent_name, template_dirs=None): - self.nodelist = nodelist - self.parent_name = parent_name - self.template_dirs = template_dirs - self.blocks = dict([(n.name, n) for n in nodelist.get_nodes_by_type(BlockNode)]) - - def __repr__(self): - return '<ExtendsNode: extends %s>' % self.parent_name.token - - def get_parent(self, context): - parent = self.parent_name.resolve(context) - if not parent: - error_msg = "Invalid template name in 'extends' tag: %r." % parent - if self.parent_name.filters or\ - isinstance(self.parent_name.var, Variable): - error_msg += " Got this from the '%s' variable." %\ - self.parent_name.token - raise TemplateSyntaxError(error_msg) - if hasattr(parent, 'render'): - return parent # parent is a Template object - return get_template(parent) - - def render(self, context): - compiled_parent = self.get_parent(context) - - if BLOCK_CONTEXT_KEY not in context.render_context: - context.render_context[BLOCK_CONTEXT_KEY] = BlockContext() - block_context = context.render_context[BLOCK_CONTEXT_KEY] - - # Add the block nodes from this node to the block context - block_context.add_blocks(self.blocks) - - # If this block's parent doesn't have an extends node it is the root, - # and its block nodes also need to be added to the block context. - for node in compiled_parent.nodelist: - # The ExtendsNode has to be the first non-text node. - if not isinstance(node, TextNode): - if not isinstance(node, ExtendsNode): - blocks = dict([(n.name, n) for n in - compiled_parent.nodelist.get_nodes_by_type(BlockNode)]) - block_context.add_blocks(blocks) - break - - # Call Template._render explicitly so the parser context stays - # the same. - return compiled_parent._render(context) - -class BaseIncludeNode(Node): - def __init__(self, *args, **kwargs): - self.extra_context = kwargs.pop('extra_context', {}) - self.isolated_context = kwargs.pop('isolated_context', False) - super(BaseIncludeNode, self).__init__(*args, **kwargs) - - def render_template(self, template, context): - values = dict([(name, var.resolve(context)) for name, var - in six.iteritems(self.extra_context)]) - if self.isolated_context: - return template.render(context.new(values)) - context.update(values) - output = template.render(context) - context.pop() - return output - -class ConstantIncludeNode(BaseIncludeNode): - def __init__(self, template_path, *args, **kwargs): - super(ConstantIncludeNode, self).__init__(*args, **kwargs) - try: - t = get_template(template_path) - self.template = t - except: - if settings.TEMPLATE_DEBUG: - raise - self.template = None - - def render(self, context): - if not self.template: - return '' - return self.render_template(self.template, context) - -class IncludeNode(BaseIncludeNode): - def __init__(self, template_name, *args, **kwargs): - super(IncludeNode, self).__init__(*args, **kwargs) - self.template_name = template_name - - def render(self, context): - try: - template_name = self.template_name.resolve(context) - template = get_template(template_name) - return self.render_template(template, context) - except: - if settings.TEMPLATE_DEBUG: - raise - return '' - -@register.tag('block') -def do_block(parser, token): - """ - Define a block that can be overridden by child templates. - """ - # token.split_contents() isn't useful here because this tag doesn't accept variable as arguments - bits = token.contents.split() - if len(bits) != 2: - raise TemplateSyntaxError("'%s' tag takes only one argument" % bits[0]) - block_name = bits[1] - # Keep track of the names of BlockNodes found in this template, so we can - # check for duplication. - try: - if block_name in parser.__loaded_blocks: - raise TemplateSyntaxError("'%s' tag with name '%s' appears more than once" % (bits[0], block_name)) - parser.__loaded_blocks.append(block_name) - except AttributeError: # parser.__loaded_blocks isn't a list yet - parser.__loaded_blocks = [block_name] - nodelist = parser.parse(('endblock',)) - - # This check is kept for backwards-compatibility. See #3100. - endblock = parser.next_token() - acceptable_endblocks = ('endblock', 'endblock %s' % block_name) - if endblock.contents not in acceptable_endblocks: - parser.invalid_block_tag(endblock, 'endblock', acceptable_endblocks) - - return BlockNode(block_name, nodelist) - -@register.tag('extends') -def do_extends(parser, token): - """ - Signal that this template extends a parent template. - - This tag may be used in two ways: ``{% extends "base" %}`` (with quotes) - uses the literal value "base" as the name of the parent template to extend, - or ``{% extends variable %}`` uses the value of ``variable`` as either the - name of the parent template to extend (if it evaluates to a string) or as - the parent template itself (if it evaluates to a Template object). - """ - bits = token.split_contents() - if len(bits) != 2: - raise TemplateSyntaxError("'%s' takes one argument" % bits[0]) - parent_name = parser.compile_filter(bits[1]) - nodelist = parser.parse() - if nodelist.get_nodes_by_type(ExtendsNode): - raise TemplateSyntaxError("'%s' cannot appear more than once in the same template" % bits[0]) - return ExtendsNode(nodelist, parent_name) - -@register.tag('include') -def do_include(parser, token): - """ - Loads a template and renders it with the current context. You can pass - additional context using keyword arguments. - - Example:: - - {% include "foo/some_include" %} - {% include "foo/some_include" with bar="BAZZ!" baz="BING!" %} - - Use the ``only`` argument to exclude the current context when rendering - the included template:: - - {% include "foo/some_include" only %} - {% include "foo/some_include" with bar="1" only %} - """ - bits = token.split_contents() - if len(bits) < 2: - raise TemplateSyntaxError("%r tag takes at least one argument: the name of the template to be included." % bits[0]) - options = {} - remaining_bits = bits[2:] - while remaining_bits: - option = remaining_bits.pop(0) - if option in options: - raise TemplateSyntaxError('The %r option was specified more ' - 'than once.' % option) - if option == 'with': - value = token_kwargs(remaining_bits, parser, support_legacy=False) - if not value: - raise TemplateSyntaxError('"with" in %r tag needs at least ' - 'one keyword argument.' % bits[0]) - elif option == 'only': - value = True - else: - raise TemplateSyntaxError('Unknown argument for %r tag: %r.' % - (bits[0], option)) - options[option] = value - isolated_context = options.get('only', False) - namemap = options.get('with', {}) - path = bits[1] - if path[0] in ('"', "'") and path[-1] == path[0]: - return ConstantIncludeNode(path[1:-1], extra_context=namemap, - isolated_context=isolated_context) - return IncludeNode(parser.compile_filter(bits[1]), extra_context=namemap, - isolated_context=isolated_context) diff --git a/lib/python2.7/site-packages/django/template/loaders/__init__.py b/lib/python2.7/site-packages/django/template/loaders/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/lib/python2.7/site-packages/django/template/loaders/__init__.py +++ /dev/null diff --git a/lib/python2.7/site-packages/django/template/loaders/app_directories.py b/lib/python2.7/site-packages/django/template/loaders/app_directories.py deleted file mode 100644 index c82817a..0000000 --- a/lib/python2.7/site-packages/django/template/loaders/app_directories.py +++ /dev/null @@ -1,63 +0,0 @@ -""" -Wrapper for loading templates from "templates" directories in INSTALLED_APPS -packages. -""" - -import os -import sys - -from django.conf import settings -from django.core.exceptions import ImproperlyConfigured -from django.template.base import TemplateDoesNotExist -from django.template.loader import BaseLoader -from django.utils._os import safe_join -from django.utils.importlib import import_module -from django.utils import six - -# At compile time, cache the directories to search. -if six.PY2: - fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() -app_template_dirs = [] -for app in settings.INSTALLED_APPS: - try: - mod = import_module(app) - except ImportError as e: - raise ImproperlyConfigured('ImportError %s: %s' % (app, e.args[0])) - template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates') - if os.path.isdir(template_dir): - if six.PY2: - template_dir = template_dir.decode(fs_encoding) - app_template_dirs.append(template_dir) - -# It won't change, so convert it to a tuple to save memory. -app_template_dirs = tuple(app_template_dirs) - -class Loader(BaseLoader): - is_usable = True - - def get_template_sources(self, template_name, template_dirs=None): - """ - Returns the absolute paths to "template_name", when appended to each - directory in "template_dirs". Any paths that don't lie inside one of the - template dirs are excluded from the result set, for security reasons. - """ - if not template_dirs: - template_dirs = app_template_dirs - for template_dir in template_dirs: - try: - yield safe_join(template_dir, template_name) - except UnicodeDecodeError: - # The template dir name was a bytestring that wasn't valid UTF-8. - raise - except ValueError: - # The joined path was located outside of template_dir. - pass - - def load_template_source(self, template_name, template_dirs=None): - for filepath in self.get_template_sources(template_name, template_dirs): - try: - with open(filepath, 'rb') as fp: - return (fp.read().decode(settings.FILE_CHARSET), filepath) - except IOError: - pass - raise TemplateDoesNotExist(template_name) diff --git a/lib/python2.7/site-packages/django/template/loaders/cached.py b/lib/python2.7/site-packages/django/template/loaders/cached.py deleted file mode 100644 index c61045d..0000000 --- a/lib/python2.7/site-packages/django/template/loaders/cached.py +++ /dev/null @@ -1,64 +0,0 @@ -""" -Wrapper class that takes a list of template loaders as an argument and attempts -to load templates from them in order, caching the result. -""" - -import hashlib -from django.template.base import TemplateDoesNotExist -from django.template.loader import BaseLoader, get_template_from_string, find_template_loader, make_origin -from django.utils.encoding import force_bytes - -class Loader(BaseLoader): - is_usable = True - - def __init__(self, loaders): - self.template_cache = {} - self._loaders = loaders - self._cached_loaders = [] - - @property - def loaders(self): - # Resolve loaders on demand to avoid circular imports - if not self._cached_loaders: - # Set self._cached_loaders atomically. Otherwise, another thread - # could see an incomplete list. See #17303. - cached_loaders = [] - for loader in self._loaders: - cached_loaders.append(find_template_loader(loader)) - self._cached_loaders = cached_loaders - return self._cached_loaders - - def find_template(self, name, dirs=None): - for loader in self.loaders: - try: - template, display_name = loader(name, dirs) - return (template, make_origin(display_name, loader, name, dirs)) - except TemplateDoesNotExist: - pass - raise TemplateDoesNotExist(name) - - def load_template(self, template_name, template_dirs=None): - key = template_name - if template_dirs: - # If template directories were specified, use a hash to differentiate - key = '-'.join([template_name, hashlib.sha1(force_bytes('|'.join(template_dirs))).hexdigest()]) - - try: - template = self.template_cache[key] - except KeyError: - template, origin = self.find_template(template_name, template_dirs) - if not hasattr(template, 'render'): - try: - template = get_template_from_string(template, origin, template_name) - except TemplateDoesNotExist: - # If compiling the template we found raises TemplateDoesNotExist, - # back off to returning the source and display name for the template - # we were asked to load. This allows for correct identification (later) - # of the actual template that does not exist. - return template, origin - self.template_cache[key] = template - return template, None - - def reset(self): - "Empty the template cache." - self.template_cache.clear() diff --git a/lib/python2.7/site-packages/django/template/loaders/eggs.py b/lib/python2.7/site-packages/django/template/loaders/eggs.py deleted file mode 100644 index 7da1803..0000000 --- a/lib/python2.7/site-packages/django/template/loaders/eggs.py +++ /dev/null @@ -1,33 +0,0 @@ -# Wrapper for loading templates from eggs via pkg_resources.resource_string. -from __future__ import unicode_literals - -try: - from pkg_resources import resource_string -except ImportError: - resource_string = None - -from django.conf import settings -from django.template.base import TemplateDoesNotExist -from django.template.loader import BaseLoader -from django.utils import six - -class Loader(BaseLoader): - is_usable = resource_string is not None - - def load_template_source(self, template_name, template_dirs=None): - """ - Loads templates from Python eggs via pkg_resource.resource_string. - - For every installed app, it tries to get the resource (app, template_name). - """ - if resource_string is not None: - pkg_name = 'templates/' + template_name - for app in settings.INSTALLED_APPS: - try: - resource = resource_string(app, pkg_name) - except Exception: - continue - if six.PY2: - resource = resource.decode(settings.FILE_CHARSET) - return (resource, 'egg:%s:%s' % (app, pkg_name)) - raise TemplateDoesNotExist(template_name) diff --git a/lib/python2.7/site-packages/django/template/loaders/filesystem.py b/lib/python2.7/site-packages/django/template/loaders/filesystem.py deleted file mode 100644 index 1a7f0d2..0000000 --- a/lib/python2.7/site-packages/django/template/loaders/filesystem.py +++ /dev/null @@ -1,46 +0,0 @@ -""" -Wrapper for loading templates from the filesystem. -""" - -from django.conf import settings -from django.template.base import TemplateDoesNotExist -from django.template.loader import BaseLoader -from django.utils._os import safe_join - -class Loader(BaseLoader): - is_usable = True - - def get_template_sources(self, template_name, template_dirs=None): - """ - Returns the absolute paths to "template_name", when appended to each - directory in "template_dirs". Any paths that don't lie inside one of the - template dirs are excluded from the result set, for security reasons. - """ - if not template_dirs: - template_dirs = settings.TEMPLATE_DIRS - for template_dir in template_dirs: - try: - yield safe_join(template_dir, template_name) - except UnicodeDecodeError: - # The template dir name was a bytestring that wasn't valid UTF-8. - raise - except ValueError: - # The joined path was located outside of this particular - # template_dir (it might be inside another one, so this isn't - # fatal). - pass - - def load_template_source(self, template_name, template_dirs=None): - tried = [] - for filepath in self.get_template_sources(template_name, template_dirs): - try: - with open(filepath, 'rb') as fp: - return (fp.read().decode(settings.FILE_CHARSET), filepath) - except IOError: - tried.append(filepath) - if tried: - error_msg = "Tried %s" % tried - else: - error_msg = "Your TEMPLATE_DIRS setting is empty. Change it to point to at least one template directory." - raise TemplateDoesNotExist(error_msg) - load_template_source.is_usable = True diff --git a/lib/python2.7/site-packages/django/template/response.py b/lib/python2.7/site-packages/django/template/response.py deleted file mode 100644 index 3b3b413..0000000 --- a/lib/python2.7/site-packages/django/template/response.py +++ /dev/null @@ -1,159 +0,0 @@ -from django.http import HttpResponse -from django.template import loader, Context, RequestContext -from django.utils import six - - -class ContentNotRenderedError(Exception): - pass - - -class SimpleTemplateResponse(HttpResponse): - rendering_attrs = ['template_name', 'context_data', '_post_render_callbacks'] - - def __init__(self, template, context=None, content_type=None, status=None, - mimetype=None): - # It would seem obvious to call these next two members 'template' and - # 'context', but those names are reserved as part of the test Client - # API. To avoid the name collision, we use tricky-to-debug problems - self.template_name = template - self.context_data = context - - self._post_render_callbacks = [] - - # content argument doesn't make sense here because it will be replaced - # with rendered template so we always pass empty string in order to - # prevent errors and provide shorter signature. - super(SimpleTemplateResponse, self).__init__('', content_type, status, - mimetype) - - # _is_rendered tracks whether the template and context has been baked - # into a final response. - # Super __init__ doesn't know any better than to set self.content to - # the empty string we just gave it, which wrongly sets _is_rendered - # True, so we initialize it to False after the call to super __init__. - self._is_rendered = False - - def __getstate__(self): - """Pickling support function. - - Ensures that the object can't be pickled before it has been - rendered, and that the pickled state only includes rendered - data, not the data used to construct the response. - """ - obj_dict = super(SimpleTemplateResponse, self).__getstate__() - if not self._is_rendered: - raise ContentNotRenderedError('The response content must be ' - 'rendered before it can be pickled.') - for attr in self.rendering_attrs: - if attr in obj_dict: - del obj_dict[attr] - - return obj_dict - - def resolve_template(self, template): - "Accepts a template object, path-to-template or list of paths" - if isinstance(template, (list, tuple)): - return loader.select_template(template) - elif isinstance(template, six.string_types): - return loader.get_template(template) - else: - return template - - def resolve_context(self, context): - """Converts context data into a full Context object - (assuming it isn't already a Context object). - """ - if isinstance(context, Context): - return context - else: - return Context(context) - - @property - def rendered_content(self): - """Returns the freshly rendered content for the template and context - described by the TemplateResponse. - - This *does not* set the final content of the response. To set the - response content, you must either call render(), or set the - content explicitly using the value of this property. - """ - template = self.resolve_template(self.template_name) - context = self.resolve_context(self.context_data) - content = template.render(context) - return content - - def add_post_render_callback(self, callback): - """Adds a new post-rendering callback. - - If the response has already been rendered, - invoke the callback immediately. - """ - if self._is_rendered: - callback(self) - else: - self._post_render_callbacks.append(callback) - - def render(self): - """Renders (thereby finalizing) the content of the response. - - If the content has already been rendered, this is a no-op. - - Returns the baked response instance. - """ - retval = self - if not self._is_rendered: - self.content = self.rendered_content - for post_callback in self._post_render_callbacks: - newretval = post_callback(retval) - if newretval is not None: - retval = newretval - return retval - - @property - def is_rendered(self): - return self._is_rendered - - def __iter__(self): - if not self._is_rendered: - raise ContentNotRenderedError('The response content must be ' - 'rendered before it can be iterated over.') - return super(SimpleTemplateResponse, self).__iter__() - - @property - def content(self): - if not self._is_rendered: - raise ContentNotRenderedError('The response content must be ' - 'rendered before it can be accessed.') - return super(SimpleTemplateResponse, self).content - - @content.setter - def content(self, value): - """Sets the content for the response - """ - HttpResponse.content.fset(self, value) - self._is_rendered = True - - -class TemplateResponse(SimpleTemplateResponse): - rendering_attrs = SimpleTemplateResponse.rendering_attrs + \ - ['_request', '_current_app'] - - def __init__(self, request, template, context=None, content_type=None, - status=None, mimetype=None, current_app=None): - # self.request gets over-written by django.test.client.Client - and - # unlike context_data and template_name the _request should not - # be considered part of the public API. - self._request = request - # As a convenience we'll allow callers to provide current_app without - # having to avoid needing to create the RequestContext directly - self._current_app = current_app - super(TemplateResponse, self).__init__( - template, context, content_type, status, mimetype) - - def resolve_context(self, context): - """Convert context data into a full RequestContext object - (assuming it isn't already a Context object). - """ - if isinstance(context, Context): - return context - return RequestContext(self._request, context, current_app=self._current_app) diff --git a/lib/python2.7/site-packages/django/template/smartif.py b/lib/python2.7/site-packages/django/template/smartif.py deleted file mode 100644 index e2ca395..0000000 --- a/lib/python2.7/site-packages/django/template/smartif.py +++ /dev/null @@ -1,205 +0,0 @@ -""" -Parser and utilities for the smart 'if' tag -""" - -# Using a simple top down parser, as described here: -# http://effbot.org/zone/simple-top-down-parsing.htm. -# 'led' = left denotation -# 'nud' = null denotation -# 'bp' = binding power (left = lbp, right = rbp) - -class TokenBase(object): - """ - Base class for operators and literals, mainly for debugging and for throwing - syntax errors. - """ - id = None # node/token type name - value = None # used by literals - first = second = None # used by tree nodes - - def nud(self, parser): - # Null denotation - called in prefix context - raise parser.error_class( - "Not expecting '%s' in this position in if tag." % self.id - ) - - def led(self, left, parser): - # Left denotation - called in infix context - raise parser.error_class( - "Not expecting '%s' as infix operator in if tag." % self.id - ) - - def display(self): - """ - Returns what to display in error messages for this node - """ - return self.id - - def __repr__(self): - out = [str(x) for x in [self.id, self.first, self.second] if x is not None] - return "(" + " ".join(out) + ")" - - -def infix(bp, func): - """ - Creates an infix operator, given a binding power and a function that - evaluates the node - """ - class Operator(TokenBase): - lbp = bp - - def led(self, left, parser): - self.first = left - self.second = parser.expression(bp) - return self - - def eval(self, context): - try: - return func(context, self.first, self.second) - except Exception: - # Templates shouldn't throw exceptions when rendering. We are - # most likely to get exceptions for things like {% if foo in bar - # %} where 'bar' does not support 'in', so default to False - return False - - return Operator - - -def prefix(bp, func): - """ - Creates a prefix operator, given a binding power and a function that - evaluates the node. - """ - class Operator(TokenBase): - lbp = bp - - def nud(self, parser): - self.first = parser.expression(bp) - self.second = None - return self - - def eval(self, context): - try: - return func(context, self.first) - except Exception: - return False - - return Operator - - -# Operator precedence follows Python. -# NB - we can get slightly more accurate syntax error messages by not using the -# same object for '==' and '='. -# We defer variable evaluation to the lambda to ensure that terms are -# lazily evaluated using Python's boolean parsing logic. -OPERATORS = { - 'or': infix(6, lambda context, x, y: x.eval(context) or y.eval(context)), - 'and': infix(7, lambda context, x, y: x.eval(context) and y.eval(context)), - 'not': prefix(8, lambda context, x: not x.eval(context)), - 'in': infix(9, lambda context, x, y: x.eval(context) in y.eval(context)), - 'not in': infix(9, lambda context, x, y: x.eval(context) not in y.eval(context)), - '=': infix(10, lambda context, x, y: x.eval(context) == y.eval(context)), - '==': infix(10, lambda context, x, y: x.eval(context) == y.eval(context)), - '!=': infix(10, lambda context, x, y: x.eval(context) != y.eval(context)), - '>': infix(10, lambda context, x, y: x.eval(context) > y.eval(context)), - '>=': infix(10, lambda context, x, y: x.eval(context) >= y.eval(context)), - '<': infix(10, lambda context, x, y: x.eval(context) < y.eval(context)), - '<=': infix(10, lambda context, x, y: x.eval(context) <= y.eval(context)), -} - -# Assign 'id' to each: -for key, op in OPERATORS.items(): - op.id = key - - -class Literal(TokenBase): - """ - A basic self-resolvable object similar to a Django template variable. - """ - # IfParser uses Literal in create_var, but TemplateIfParser overrides - # create_var so that a proper implementation that actually resolves - # variables, filters etc is used. - id = "literal" - lbp = 0 - - def __init__(self, value): - self.value = value - - def display(self): - return repr(self.value) - - def nud(self, parser): - return self - - def eval(self, context): - return self.value - - def __repr__(self): - return "(%s %r)" % (self.id, self.value) - - -class EndToken(TokenBase): - lbp = 0 - - def nud(self, parser): - raise parser.error_class("Unexpected end of expression in if tag.") - -EndToken = EndToken() - - -class IfParser(object): - error_class = ValueError - - def __init__(self, tokens): - # pre-pass necessary to turn 'not','in' into single token - l = len(tokens) - mapped_tokens = [] - i = 0 - while i < l: - token = tokens[i] - if token == "not" and i + 1 < l and tokens[i+1] == "in": - token = "not in" - i += 1 # skip 'in' - mapped_tokens.append(self.translate_token(token)) - i += 1 - - self.tokens = mapped_tokens - self.pos = 0 - self.current_token = self.next_token() - - def translate_token(self, token): - try: - op = OPERATORS[token] - except (KeyError, TypeError): - return self.create_var(token) - else: - return op() - - def next_token(self): - if self.pos >= len(self.tokens): - return EndToken - else: - retval = self.tokens[self.pos] - self.pos += 1 - return retval - - def parse(self): - retval = self.expression() - # Check that we have exhausted all the tokens - if self.current_token is not EndToken: - raise self.error_class("Unused '%s' at end of if expression." % - self.current_token.display()) - return retval - - def expression(self, rbp=0): - t = self.current_token - self.current_token = self.next_token() - left = t.nud(self) - while rbp < self.current_token.lbp: - t = self.current_token - self.current_token = self.next_token() - left = t.led(left, self) - return left - - def create_var(self, value): - return Literal(value) |