summaryrefslogtreecommitdiff
path: root/lib/python2.7/site-packages/django/template/smartif.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/site-packages/django/template/smartif.py')
-rw-r--r--lib/python2.7/site-packages/django/template/smartif.py205
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)