simplified undefined behavior for better compile time processing
--HG--
branch : trunk
diff --git a/jinja2/nodes.py b/jinja2/nodes.py
index dc8cc0b..6c16c8b 100644
--- a/jinja2/nodes.py
+++ b/jinja2/nodes.py
@@ -16,6 +16,7 @@
from itertools import chain, izip
from collections import deque
from copy import copy
+from jinja2.runtime import Undefined, subscribe
_binop_to_func = {
@@ -286,6 +287,18 @@
def as_const(self):
return self.value
+ @classmethod
+ def from_untrusted(cls, value, lineno=None, silent=False):
+ """Return a const object if the value is representable as
+ constant value in the generated code, otherwise it will raise
+ an `Impossible` exception."""
+ from compiler import has_safe_repr
+ if not has_safe_repr(value):
+ if silent:
+ return
+ raise Impossible()
+ return cls(value, lineno=lineno)
+
class Tuple(Literal):
"""For loop unpacking and some other things like multiple arguments
@@ -361,14 +374,35 @@
"""{{ foo(bar) }}"""
fields = ('node', 'args', 'kwargs', 'dyn_args', 'dyn_kwargs')
+ def as_const(self):
+ obj = self.node.as_const()
+ args = [x.as_const() for x in self.args]
+ kwargs = dict(x.as_const() for x in self.kwargs)
+ if self.dyn_args is not None:
+ try:
+ args.extend(self.dyn_args.as_const())
+ except:
+ raise Impossible()
+ if self.dyn_kwargs is not None:
+ try:
+ dyn_kwargs.update(self.dyn_kwargs.as_const())
+ except:
+ raise Impossible()
+ try:
+ return obj(*args, **kwargs)
+ except:
+ raise nodes.Impossible()
+
class Subscript(Expr):
"""{{ foo.bar }} and {{ foo['bar'] }} etc."""
fields = ('node', 'arg', 'ctx')
def as_const(self):
+ if self.ctx != 'load':
+ raise Impossible()
try:
- return self.node.as_const()[self.node.as_const()]
+ return subscribe(self.node.as_const(), self.arg.as_const())
except:
raise Impossible()
@@ -380,6 +414,13 @@
"""1:2:3 etc."""
fields = ('start', 'stop', 'step')
+ def as_const(self):
+ def const(obj):
+ if obj is None:
+ return obj
+ return obj.as_const()
+ return slice(const(self.start), const(self.stop), const(self.step))
+
class Concat(Expr):
"""For {{ foo ~ bar }}. Concatenates strings."""