runtime.py (12237B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\jinja2\runtime.py 2 from itertools import chain, imap 3 from jinja2.nodes import EvalContext, _context_function_types 4 from jinja2.utils import Markup, partial, soft_unicode, escape, missing, concat, internalcode, next, object_type_repr 5 from jinja2.exceptions import UndefinedError, TemplateRuntimeError, TemplateNotFound 6 __all__ = ['LoopContext', 7 'TemplateReference', 8 'Macro', 9 'Markup', 10 'TemplateRuntimeError', 11 'missing', 12 'concat', 13 'escape', 14 'markup_join', 15 'unicode_join', 16 'to_string', 17 'identity', 18 'TemplateNotFound'] 19 to_string = unicode 20 identity = lambda x: x 21 _last_iteration = object() 22 23 def markup_join(seq): 24 buf = [] 25 iterator = imap(soft_unicode, seq) 26 for arg in iterator: 27 buf.append(arg) 28 if hasattr(arg, '__html__'): 29 return Markup(u'').join(chain(buf, iterator)) 30 31 return concat(buf) 32 33 34 def unicode_join(seq): 35 return concat(imap(unicode, seq)) 36 37 38 def new_context(environment, template_name, blocks, vars = None, shared = None, globals = None, locals = None): 39 if vars is None: 40 vars = {} 41 if shared: 42 parent = vars 43 else: 44 parent = dict((globals or ()), **vars) 45 if locals: 46 if shared: 47 parent = dict(parent) 48 for key, value in locals.iteritems(): 49 if key[:2] == 'l_' and value is not missing: 50 parent[key[2:]] = value 51 52 return Context(environment, parent, template_name, blocks) 53 54 55 class TemplateReference(object): 56 57 def __init__(self, context): 58 self.__context = context 59 60 def __getitem__(self, name): 61 blocks = self.__context.blocks[name] 62 return BlockReference(name, self.__context, blocks, 0) 63 64 def __repr__(self): 65 return '<%s %r>' % (self.__class__.__name__, self.__context.name) 66 67 68 class Context(object): 69 __slots__ = ('parent', 'vars', 'environment', 'eval_ctx', 'exported_vars', 'name', 'blocks', '__weakref__') 70 71 def __init__(self, environment, parent, name, blocks): 72 self.parent = parent 73 self.vars = {} 74 self.environment = environment 75 self.eval_ctx = EvalContext(self.environment, name) 76 self.exported_vars = set() 77 self.name = name 78 self.blocks = dict(((k, [v]) for k, v in blocks.iteritems())) 79 80 def super(self, name, current): 81 try: 82 blocks = self.blocks[name] 83 index = blocks.index(current) + 1 84 blocks[index] 85 except LookupError: 86 return self.environment.undefined('there is no parent block called %r.' % name, name='super') 87 88 return BlockReference(name, self, blocks, index) 89 90 def get(self, key, default = None): 91 try: 92 return self[key] 93 except KeyError: 94 return default 95 96 def resolve(self, key): 97 if key in self.vars: 98 return self.vars[key] 99 if key in self.parent: 100 return self.parent[key] 101 return self.environment.undefined(name=key) 102 103 def get_exported(self): 104 return dict(((k, self.vars[k]) for k in self.exported_vars)) 105 106 def get_all(self): 107 return dict(self.parent, **self.vars) 108 109 @internalcode 110 def call(_Context__self, _Context__obj, *args, **kwargs): 111 if isinstance(__obj, _context_function_types): 112 if getattr(__obj, 'contextfunction', 0): 113 args = (__self,) + args 114 elif getattr(__obj, 'evalcontextfunction', 0): 115 args = (__self.eval_ctx,) + args 116 elif getattr(__obj, 'environmentfunction', 0): 117 args = (__self.environment,) + args 118 try: 119 return __obj(*args, **kwargs) 120 except StopIteration: 121 return __self.environment.undefined('value was undefined because a callable raised a StopIteration exception') 122 123 def derived(self, locals = None): 124 context = new_context(self.environment, self.name, {}, self.parent, True, None, locals) 125 context.vars.update(self.vars) 126 context.eval_ctx = self.eval_ctx 127 context.blocks.update(((k, list(v)) for k, v in self.blocks.iteritems())) 128 return context 129 130 def _all(meth): 131 proxy = lambda self: getattr(self.get_all(), meth)() 132 proxy.__doc__ = getattr(dict, meth).__doc__ 133 proxy.__name__ = meth 134 return proxy 135 136 keys = _all('keys') 137 values = _all('values') 138 items = _all('items') 139 if hasattr(dict, 'iterkeys'): 140 iterkeys = _all('iterkeys') 141 itervalues = _all('itervalues') 142 iteritems = _all('iteritems') 143 del _all 144 145 def __contains__(self, name): 146 return name in self.vars or name in self.parent 147 148 def __getitem__(self, key): 149 item = self.resolve(key) 150 if isinstance(item, Undefined): 151 raise KeyError(key) 152 return item 153 154 def __repr__(self): 155 return '<%s %s of %r>' % (self.__class__.__name__, repr(self.get_all()), self.name) 156 157 158 try: 159 from collections import Mapping 160 Mapping.register(Context) 161 except ImportError: 162 pass 163 164 class BlockReference(object): 165 166 def __init__(self, name, context, stack, depth): 167 self.name = name 168 self._context = context 169 self._stack = stack 170 self._depth = depth 171 172 @property 173 def super(self): 174 if self._depth + 1 >= len(self._stack): 175 return self._context.environment.undefined('there is no parent block called %r.' % self.name, name='super') 176 return BlockReference(self.name, self._context, self._stack, self._depth + 1) 177 178 @internalcode 179 def __call__(self): 180 rv = concat(self._stack[self._depth](self._context)) 181 if self._context.eval_ctx.autoescape: 182 rv = Markup(rv) 183 return rv 184 185 186 class LoopContext(object): 187 188 def __init__(self, iterable, recurse = None): 189 self._iterator = iter(iterable) 190 self._recurse = recurse 191 self._after = self._safe_next() 192 self.index0 = -1 193 try: 194 self._length = len(iterable) 195 except (TypeError, AttributeError): 196 self._length = None 197 198 def cycle(self, *args): 199 if not args: 200 raise TypeError('no items for cycling given') 201 return args[self.index0 % len(args)] 202 203 first = property(lambda x: x.index0 == 0) 204 last = property(lambda x: x._after is _last_iteration) 205 index = property(lambda x: x.index0 + 1) 206 revindex = property(lambda x: x.length - x.index0) 207 revindex0 = property(lambda x: x.length - x.index) 208 209 def __len__(self): 210 return self.length 211 212 def __iter__(self): 213 return LoopContextIterator(self) 214 215 def _safe_next(self): 216 try: 217 return next(self._iterator) 218 except StopIteration: 219 return _last_iteration 220 221 @internalcode 222 def loop(self, iterable): 223 if self._recurse is None: 224 raise TypeError("Tried to call non recursive loop. Maybe you forgot the 'recursive' modifier.") 225 return self._recurse(iterable, self._recurse) 226 227 __call__ = loop 228 del loop 229 230 @property 231 def length(self): 232 if self._length is None: 233 iterable = tuple(self._iterator) 234 self._iterator = iter(iterable) 235 self._length = len(iterable) + self.index0 + 1 236 return self._length 237 238 def __repr__(self): 239 return '<%s %r/%r>' % (self.__class__.__name__, self.index, self.length) 240 241 242 class LoopContextIterator(object): 243 __slots__ = ('context',) 244 245 def __init__(self, context): 246 self.context = context 247 248 def __iter__(self): 249 return self 250 251 def next(self): 252 ctx = self.context 253 ctx.index0 += 1 254 if ctx._after is _last_iteration: 255 raise StopIteration() 256 next_elem = ctx._after 257 ctx._after = ctx._safe_next() 258 return (next_elem, ctx) 259 260 261 class Macro(object): 262 263 def __init__(self, environment, func, name, arguments, defaults, catch_kwargs, catch_varargs, caller): 264 self._environment = environment 265 self._func = func 266 self._argument_count = len(arguments) 267 self.name = name 268 self.arguments = arguments 269 self.defaults = defaults 270 self.catch_kwargs = catch_kwargs 271 self.catch_varargs = catch_varargs 272 self.caller = caller 273 274 @internalcode 275 def __call__(self, *args, **kwargs): 276 arguments = list(args[:self._argument_count]) 277 off = len(arguments) 278 if off != self._argument_count: 279 for idx, name in enumerate(self.arguments[len(arguments):]): 280 try: 281 value = kwargs.pop(name) 282 except KeyError: 283 try: 284 value = self.defaults[idx - self._argument_count + off] 285 except IndexError: 286 value = self._environment.undefined('parameter %r was not provided' % name, name=name) 287 288 arguments.append(value) 289 290 if self.caller: 291 caller = kwargs.pop('caller', None) 292 if caller is None: 293 caller = self._environment.undefined('No caller defined', name='caller') 294 arguments.append(caller) 295 if self.catch_kwargs: 296 arguments.append(kwargs) 297 elif kwargs: 298 raise TypeError('macro %r takes no keyword argument %r' % (self.name, next(iter(kwargs)))) 299 if self.catch_varargs: 300 arguments.append(args[self._argument_count:]) 301 elif len(args) > self._argument_count: 302 raise TypeError('macro %r takes not more than %d argument(s)' % (self.name, len(self.arguments))) 303 return self._func(*arguments) 304 305 def __repr__(self): 306 return '<%s %s>' % (self.__class__.__name__, self.name is None and 'anonymous' or repr(self.name)) 307 308 309 class Undefined(object): 310 __slots__ = ('_undefined_hint', '_undefined_obj', '_undefined_name', '_undefined_exception') 311 312 def __init__(self, hint = None, obj = missing, name = None, exc = UndefinedError): 313 self._undefined_hint = hint 314 self._undefined_obj = obj 315 self._undefined_name = name 316 self._undefined_exception = exc 317 318 @internalcode 319 def _fail_with_undefined_error(self, *args, **kwargs): 320 if self._undefined_hint is None: 321 if self._undefined_obj is missing: 322 hint = '%r is undefined' % self._undefined_name 323 elif not isinstance(self._undefined_name, basestring): 324 hint = '%s has no element %r' % (object_type_repr(self._undefined_obj), self._undefined_name) 325 else: 326 hint = '%r has no attribute %r' % (object_type_repr(self._undefined_obj), self._undefined_name) 327 else: 328 hint = self._undefined_hint 329 raise self._undefined_exception(hint) 330 331 @internalcode 332 def __getattr__(self, name): 333 if name[:2] == '__': 334 raise AttributeError(name) 335 return self._fail_with_undefined_error() 336 337 __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__ = _fail_with_undefined_error 338 339 def __str__(self): 340 return unicode(self).encode('utf-8') 341 342 def __unicode__(self): 343 return u'' 344 345 def __len__(self): 346 return 0 347 348 def __iter__(self): 349 pass 350 351 def __nonzero__(self): 352 return False 353 354 def __repr__(self): 355 return 'Undefined' 356 357 358 class DebugUndefined(Undefined): 359 __slots__ = () 360 361 def __unicode__(self): 362 if self._undefined_hint is None: 363 if self._undefined_obj is missing: 364 return u'{{ %s }}' % self._undefined_name 365 return '{{ no such element: %s[%r] }}' % (object_type_repr(self._undefined_obj), self._undefined_name) 366 return u'{{ undefined value printed: %s }}' % self._undefined_hint 367 368 369 class StrictUndefined(Undefined): 370 __slots__ = () 371 __iter__ = __unicode__ = __str__ = __len__ = __nonzero__ = __eq__ = __ne__ = __bool__ = Undefined._fail_with_undefined_error 372 373 374 del Undefined.__slots__ 375 del DebugUndefined.__slots__ 376 del StrictUndefined.__slots__