a clean restart

--HG--
branch : trunk
rename : jinja/__init__.py => jinja2/__init__.py
rename : jinja/_debugger.c => jinja2/_debugger.c
rename : jinja/_native.py => jinja2/_native.py
rename : jinja/_speedups.c => jinja2/_speedups.c
rename : jinja/constants.py => jinja2/constants.py
rename : jinja/contrib/__init__.py => jinja2/contrib/__init__.py
rename : jinja/contrib/_djangosupport.py => jinja2/contrib/_djangosupport.py
rename : jinja/contrib/djangosupport.py => jinja2/contrib/djangosupport.py
rename : jinja/datastructure.py => jinja2/datastructure.py
rename : jinja/defaults.py => jinja2/defaults.py
rename : jinja/environment.py => jinja2/environment.py
rename : jinja/exceptions.py => jinja2/exceptions.py
rename : jinja/filters.py => jinja2/filters.py
rename : jinja/lexer.py => jinja2/lexer.py
rename : jinja/loaders.py => jinja2/loaders.py
rename : jinja/nodes.py => jinja2/nodes.py
rename : jinja/parser.py => jinja2/parser.py
rename : jinja/tests.py => jinja2/tests.py
rename : jinja/translators/__init__.py => jinja2/translators/__init__.py
rename : jinja/translators/python.py => jinja2/translators/python.py
rename : jinja/utils.py => jinja2/utils.py
diff --git a/jinja2/nodes.py b/jinja2/nodes.py
new file mode 100644
index 0000000..1e20096
--- /dev/null
+++ b/jinja2/nodes.py
@@ -0,0 +1,494 @@
+# -*- coding: utf-8 -*-
+"""
+    jinja2.nodes
+    ~~~~~~~~~~~~
+
+    This module implements additional nodes derived from the ast base node.
+
+    It also provides some node tree helper functions like `in_lineno` and
+    `get_nodes` used by the parser and translator in order to normalize
+    python and jinja nodes.
+
+    :copyright: 2007 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+import operator
+from itertools import chain, izip
+from copy import copy
+
+
+_binop_to_func = {
+    '*':        operator.mul,
+    '/':        operator.truediv,
+    '//':       operator.floordiv,
+    '**':       operator.pow,
+    '%':        operator.mod,
+    '+':        operator.add,
+    '-':        operator.sub
+}
+
+_uaop_to_func = {
+    'not':      operator.not_,
+    '+':        operator.pos,
+    '-':        operator.neg
+}
+
+
+class Impossible(Exception):
+    """
+    Raised if the node could not perform a requested action.
+    """
+
+
+class NodeType(type):
+
+    def __new__(cls, name, bases, d):
+        for attr in '_fields', '_attributes':
+            storage = []
+            for base in bases:
+                storage.extend(getattr(base, attr, ()))
+            storage.extend(d.get(attr, ()))
+            assert len(storage) == len(set(storage))
+            d[attr] = tuple(storage)
+        return type.__new__(cls, name, bases, d)
+
+
+class Node(object):
+    """
+    Base jinja node.
+    """
+    __metaclass__ = NodeType
+    _fields = ()
+    _attributes = ('lineno',)
+
+    def __init__(self, *args, **kw):
+        if args:
+            if len(args) != len(self._fields):
+                if not self._fields:
+                    raise TypeError('%r takes 0 arguments' %
+                                    self.__class__.__name__)
+                raise TypeError('%r takes 0 or %d argument%s' % (
+                    self.__class__.__name__,
+                    len(self._fields),
+                    len(self._fields) != 1 and 's' or ''
+                ))
+            for name, arg in izip(self._fields, args):
+                setattr(self, name, arg)
+        for attr in self._attributes:
+            setattr(self, attr, kw.pop(attr, None))
+        if kw:
+            raise TypeError('unknown keyword argument %r' %
+                            iter(kw).next())
+
+    def iter_fields(self):
+        for name in self._fields:
+            try:
+                yield name, getattr(self, name)
+            except AttributeError:
+                pass
+
+    def iter_child_nodes(self):
+        for field, item in self.iter_fields():
+            if isinstance(item, list):
+                for n in item:
+                    if isinstance(n, Node):
+                        yield n
+            elif isinstance(item, Node):
+                yield item
+
+    def __repr__(self):
+        return '%s(%s)' % (
+            self.__class__.__name__,
+            ', '.join('%s=%r' % (arg, getattr(self, arg, None)) for
+                      arg in self._fields)
+        )
+
+
+class Stmt(Node):
+    """
+    Base node for all statements.
+    """
+
+
+class Helper(Node):
+    """
+    Nodes that exist in a specific context only.
+    """
+
+
+class Template(Node):
+    """
+    Node that represents a template.
+    """
+    _fields = ('extends', 'body')
+
+
+class Output(Stmt):
+    """
+    A node that holds multiple expressions which are then printed out.  This
+    is used both for the `print` statement and the regular template data.
+    """
+    _fields = ('nodes',)
+
+
+class Extends(Stmt):
+    """
+    Represents an extends statement.
+    """
+    _fields = ('extends',)
+
+
+class For(Stmt):
+    """
+    A node that represents a for loop
+    """
+    _fields = ('item', 'seq', 'body', 'else_', 'recursive')
+
+
+class If(Stmt):
+    """
+    A node that represents an if condition.
+    """
+    _fields = ('test', 'body', 'else_')
+
+
+class Macro(Stmt):
+    """
+    A node that represents a macro.
+    """
+    _fields = ('name', 'arguments', 'body')
+
+
+class CallBlock(Stmt):
+    """
+    A node that represents am extended macro call.
+    """
+    _fields = ('expr', 'body')
+
+
+class Set(Stmt):
+    """
+    Allows defining own variables.
+    """
+    _fields = ('name', 'expr')
+
+
+class FilterBlock(Stmt):
+    """
+    Node for filter sections.
+    """
+    _fields = ('body', 'filters')
+
+
+class Block(Stmt):
+    """
+    A node that represents a block.
+    """
+    _fields = ('name', 'body')
+
+
+class Include(Stmt):
+    """
+    A node that represents the include tag.
+    """
+    _fields = ('template',)
+
+
+class Trans(Stmt):
+    """
+    A node for translatable sections.
+    """
+    _fields = ('singular', 'plural', 'indicator', 'replacements')
+
+
+class ExprStmt(Stmt):
+    """
+    A statement that evaluates an expression to None.
+    """
+    _fields = ('node',)
+
+
+class Expr(Node):
+    """
+    Baseclass for all expressions.
+    """
+
+    def as_const(self):
+        """
+        Return the value of the expression as constant or raise `Impossible`
+        if this was not possible.
+        """
+        raise Impossible()
+
+    def can_assign(self):
+        """
+        Check if it's possible to assign something to this node.
+        """
+        return False
+
+
+class BinExpr(Expr):
+    """
+    Baseclass for all binary expressions.
+    """
+    _fields = ('left', 'right')
+    operator = None
+
+    def as_const(self):
+        f = _binop_to_func[self.operator]
+        try:
+            return f(self.left.as_const(), self.right.as_const())
+        except:
+            print self.left, f, self.right
+            raise Impossible()
+
+
+class UnaryExpr(Expr):
+    """
+    Baseclass for all unary expressions.
+    """
+    _fields = ('node',)
+    operator = None
+
+    def as_const(self):
+        f = _uaop_to_func[self.operator]
+        try:
+            return f(self.node.as_const())
+        except:
+            raise Impossible()
+
+
+class Name(Expr):
+    """
+    any name such as {{ foo }}
+    """
+    _fields = ('name',)
+
+    def can_assign(self):
+        return True
+
+
+class Literal(Expr):
+    """
+    Baseclass for literals.
+    """
+
+
+class Const(Literal):
+    """
+    any constat such as {{ "foo" }}
+    """
+    _fields = ('value',)
+
+    def as_const(self):
+        return self.value
+
+
+class Tuple(Literal):
+    """
+    For loop unpacking and some other things like multiple arguments
+    for subscripts.
+    """
+    _fields = ('items',)
+
+    def as_const(self):
+        return tuple(x.as_const() for x in self.items)
+
+    def can_assign(self):
+        for item in self.items:
+            if not item.can_assign():
+                return False
+        return True
+
+
+class List(Literal):
+    """
+    any list literal such as {{ [1, 2, 3] }}
+    """
+    _fields = ('items',)
+
+    def as_const(self):
+        return [x.as_const() for x in self.items]
+
+
+class Dict(Literal):
+    """
+    any dict literal such as {{ {1: 2, 3: 4} }}
+    """
+    _fields = ('items',)
+
+    def as_const(self):
+        return dict(x.as_const() for x in self.items)
+
+
+class Pair(Helper):
+    """
+    A key, value pair for dicts.
+    """
+    _fields = ('key', 'value')
+
+    def as_const(self):
+        return self.key.as_const(), self.value.as_const()
+
+
+class CondExpr(Expr):
+    """
+    {{ foo if bar else baz }}
+    """
+    _fields = ('test', 'expr1', 'expr2')
+
+    def as_const(self):
+        if self.test.as_const():
+            return self.expr1.as_const()
+        return self.expr2.as_const()
+
+
+class Filter(Expr):
+    """
+    {{ foo|bar|baz }}
+    """
+    _fields = ('node', 'filters')
+
+
+class Test(Expr):
+    """
+    {{ foo is lower }}
+    """
+    _fields = ('node', 'name', 'args')
+
+
+class Call(Expr):
+    """
+    {{ foo(bar) }}
+    """
+    _fields = ('node', 'args', 'kwargs', 'dyn_args', 'dyn_kwargs')
+
+
+class Subscript(Expr):
+    """
+    {{ foo.bar }} and {{ foo['bar'] }} etc.
+    """
+    _fields = ('node', 'arg')
+
+    def as_const(self):
+        try:
+            return self.node.as_const()[self.node.as_const()]
+        except:
+            raise Impossible()
+
+    def can_assign(self):
+        return True
+
+
+class Slice(Expr):
+    """
+    1:2:3 etc.
+    """
+    _fields = ('start', 'stop', 'step')
+
+
+class Concat(Expr):
+    """
+    For {{ foo ~ bar }}.  Concatenates strings.
+    """
+    _fields = ('nodes',)
+
+    def as_const(self):
+        return ''.join(unicode(x.as_const()) for x in self.nodes)
+
+
+class Compare(Expr):
+    """
+    {{ foo == bar }}, {{ foo >= bar }} etc.
+    """
+    _fields = ('expr', 'ops')
+
+
+class Mul(BinExpr):
+    """
+    {{ foo * bar }}
+    """
+    operator = '*'
+
+
+class Div(BinExpr):
+    """
+    {{ foo / bar }}
+    """
+    operator = '/'
+
+
+class FloorDiv(BinExpr):
+    """
+    {{ foo // bar }}
+    """
+    operator = '//'
+
+
+class Add(BinExpr):
+    """
+    {{ foo + bar }}
+    """
+    operator = '+'
+
+
+class Sub(BinExpr):
+    """
+    {{ foo - bar }}
+    """
+    operator = '-'
+
+
+class Mod(BinExpr):
+    """
+    {{ foo % bar }}
+    """
+    operator = '%'
+
+
+class Pow(BinExpr):
+    """
+    {{ foo ** bar }}
+    """
+    operator = '**'
+
+
+class And(BinExpr):
+    """
+    {{ foo and bar }}
+    """
+    operator = 'and'
+
+    def as_const(self):
+        return self.left.as_const() and self.right.as_const()
+
+
+class Or(BinExpr):
+    """
+    {{ foo or bar }}
+    """
+    operator = 'or'
+
+    def as_const(self):
+        return self.left.as_const() or self.right.as_const()
+
+
+class Not(UnaryExpr):
+    """
+    {{ not foo }}
+    """
+    operator = 'not'
+
+
+class NegExpr(UnaryExpr):
+    """
+    {{ -foo }}
+    """
+    operator = '-'
+
+
+class PosExpr(UnaryExpr):
+    """
+    {{ +foo }}
+    """
+    operator = '+'