diff options
Diffstat (limited to 'lib/python2.7/site-packages/django/template/smartif.py')
-rw-r--r-- | lib/python2.7/site-packages/django/template/smartif.py | 205 |
1 files changed, 0 insertions, 205 deletions
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) |