-
Notifications
You must be signed in to change notification settings - Fork 0
/
runtime.py
116 lines (92 loc) · 3.3 KB
/
runtime.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
from utils import missing
from nodes import EvalContext
from exceptions import UndefinedError
def resolve_or_missing(context, key, missing=missing):
if key in context.vars:
return context.vars[key]
if key in context.parent:
return context.parent[key]
return missing
class Context:
def __init__(self, environment, parent, name, blocks):
self.parent = parent
self.vars = {}
self.environment = environment
self.eval_ctx = EvalContext(self.environment, name)
self.name = name
self.blocks = dict(blocks)
def __contains__(self, name):
return name in self.vars or name in self.parent
def __getitem__(self, key):
item = self.resolve_or_missing(key)
if item is missing:
raise KeyError(key)
return item
def get(self, key, default=None):
try:
return self[key]
except KeyError:
return default
def resolve(self, key):
rv = resolve_or_missing(self, key)
if rv is missing:
return self.environment.undefined(name=key)
return rv
def resolve_or_missing(self, key):
rv = self.resolve(key)
if isinstance(rv, self.environment.undefined):
rv = missing
return rv
def get_all(self):
if not self.vars:
return self.parent
if not self.parent:
return self.vars
return dict(self.parent, **self.vars)
def call(self, obj, *args, **kwargs):
try:
return obj(*args, **kwargs)
except StopIteration:
return self.environment.undefined('value was undefined because '
'a callable raised a '
'StopIteration exception.')
def new_context(environment, template_name, blocks, vars=None):
if vars is None:
vars = {}
parent = vars
return Context(environment, parent, template_name, blocks)
class Undefined:
def __init__(self, hint=None, obj=missing, name=None):
self._undefined_hint = hint
self._undefined_obj = obj
self._undefined_name = name
def __getattr__(self, name):
return self.fail_with_undefined_error()
def __eq__(self, other):
return type(self) is type(other)
def __ne__(self, other):
return not self.__eq__(other)
def __str__(self):
return u''
def __repr__(self):
return 'Undefined'
def __bool__(self):
return False
__nonzero__ = __bool__
def fail_with_undefined_error(self, *args, **kwargs):
if not self._undefined_hint:
if self._undefined_name:
hint = '%r is undefined' % self._undefined_name
else:
hint = ''
# TODO: write something here
else:
hint = self._undefined_hint
raise UndefinedError(hint)
__add__ = __radd__ = __mul__ = __rmul__ = __div__ = __rdiv__ = \
__truediv__ = __rtruediv__ = __floordiv__ = __rfloordiv__ = \
__mod__ = __rmod__ = __pos__ = __neg__ = __call__ = \
__getitem__ = __lt__ = __le__ = __gt__ = __ge__ = __int__ = \
__float__ = __complex__ = __pow__ = __rpow__ = __sub__ = \
__rsub__ = fail_with_undefined_error
__all__ = ['missing']