Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: third_party/jinja2/runtime.py

Issue 23506004: Update Jinja2 (Python template library) to 2.7.1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/jinja2/parser.py ('k') | third_party/jinja2/sandbox.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 """ 2 """
3 jinja2.runtime 3 jinja2.runtime
4 ~~~~~~~~~~~~~~ 4 ~~~~~~~~~~~~~~
5 5
6 Runtime helpers. 6 Runtime helpers.
7 7
8 :copyright: (c) 2010 by the Jinja Team. 8 :copyright: (c) 2010 by the Jinja Team.
9 :license: BSD. 9 :license: BSD.
10 """ 10 """
11 from itertools import chain, imap 11 from itertools import chain
12 from jinja2.nodes import EvalContext, _context_function_types 12 from jinja2.nodes import EvalContext, _context_function_types
13 from jinja2.utils import Markup, partial, soft_unicode, escape, missing, \ 13 from jinja2.utils import Markup, soft_unicode, escape, missing, concat, \
14 concat, internalcode, next, object_type_repr 14 internalcode, object_type_repr
15 from jinja2.exceptions import UndefinedError, TemplateRuntimeError, \ 15 from jinja2.exceptions import UndefinedError, TemplateRuntimeError, \
16 TemplateNotFound 16 TemplateNotFound
17 from jinja2._compat import next, imap, text_type, iteritems, \
18 implements_iterator, implements_to_string, string_types, PY2
17 19
18 20
19 # these variables are exported to the template runtime 21 # these variables are exported to the template runtime
20 __all__ = ['LoopContext', 'TemplateReference', 'Macro', 'Markup', 22 __all__ = ['LoopContext', 'TemplateReference', 'Macro', 'Markup',
21 'TemplateRuntimeError', 'missing', 'concat', 'escape', 23 'TemplateRuntimeError', 'missing', 'concat', 'escape',
22 'markup_join', 'unicode_join', 'to_string', 'identity', 24 'markup_join', 'unicode_join', 'to_string', 'identity',
23 'TemplateNotFound'] 25 'TemplateNotFound']
24 26
25 #: the name of the function that is used to convert something into 27 #: the name of the function that is used to convert something into
26 #: a string. 2to3 will adopt that automatically and the generated 28 #: a string. We can just use the text type here.
27 #: code can take advantage of it. 29 to_string = text_type
28 to_string = unicode
29 30
30 #: the identity function. Useful for certain things in the environment 31 #: the identity function. Useful for certain things in the environment
31 identity = lambda x: x 32 identity = lambda x: x
32 33
34 _last_iteration = object()
35
33 36
34 def markup_join(seq): 37 def markup_join(seq):
35 """Concatenation that escapes if necessary and converts to unicode.""" 38 """Concatenation that escapes if necessary and converts to unicode."""
36 buf = [] 39 buf = []
37 iterator = imap(soft_unicode, seq) 40 iterator = imap(soft_unicode, seq)
38 for arg in iterator: 41 for arg in iterator:
39 buf.append(arg) 42 buf.append(arg)
40 if hasattr(arg, '__html__'): 43 if hasattr(arg, '__html__'):
41 return Markup(u'').join(chain(buf, iterator)) 44 return Markup(u'').join(chain(buf, iterator))
42 return concat(buf) 45 return concat(buf)
43 46
44 47
45 def unicode_join(seq): 48 def unicode_join(seq):
46 """Simple args to unicode conversion and concatenation.""" 49 """Simple args to unicode conversion and concatenation."""
47 return concat(imap(unicode, seq)) 50 return concat(imap(text_type, seq))
48 51
49 52
50 def new_context(environment, template_name, blocks, vars=None, 53 def new_context(environment, template_name, blocks, vars=None,
51 shared=None, globals=None, locals=None): 54 shared=None, globals=None, locals=None):
52 """Internal helper to for context creation.""" 55 """Internal helper to for context creation."""
53 if vars is None: 56 if vars is None:
54 vars = {} 57 vars = {}
55 if shared: 58 if shared:
56 parent = vars 59 parent = vars
57 else: 60 else:
58 parent = dict(globals or (), **vars) 61 parent = dict(globals or (), **vars)
59 if locals: 62 if locals:
60 # if the parent is shared a copy should be created because 63 # if the parent is shared a copy should be created because
61 # we don't want to modify the dict passed 64 # we don't want to modify the dict passed
62 if shared: 65 if shared:
63 parent = dict(parent) 66 parent = dict(parent)
64 for key, value in locals.iteritems(): 67 for key, value in iteritems(locals):
65 if key[:2] == 'l_' and value is not missing: 68 if key[:2] == 'l_' and value is not missing:
66 parent[key[2:]] = value 69 parent[key[2:]] = value
67 return Context(environment, parent, template_name, blocks) 70 return Context(environment, parent, template_name, blocks)
68 71
69 72
70 class TemplateReference(object): 73 class TemplateReference(object):
71 """The `self` in templates.""" 74 """The `self` in templates."""
72 75
73 def __init__(self, context): 76 def __init__(self, context):
74 self.__context = context 77 self.__context = context
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 self.parent = parent 113 self.parent = parent
111 self.vars = {} 114 self.vars = {}
112 self.environment = environment 115 self.environment = environment
113 self.eval_ctx = EvalContext(self.environment, name) 116 self.eval_ctx = EvalContext(self.environment, name)
114 self.exported_vars = set() 117 self.exported_vars = set()
115 self.name = name 118 self.name = name
116 119
117 # create the initial mapping of blocks. Whenever template inheritance 120 # create the initial mapping of blocks. Whenever template inheritance
118 # takes place the runtime will update this mapping with the new blocks 121 # takes place the runtime will update this mapping with the new blocks
119 # from the template. 122 # from the template.
120 self.blocks = dict((k, [v]) for k, v in blocks.iteritems()) 123 self.blocks = dict((k, [v]) for k, v in iteritems(blocks))
121 124
122 def super(self, name, current): 125 def super(self, name, current):
123 """Render a parent block.""" 126 """Render a parent block."""
124 try: 127 try:
125 blocks = self.blocks[name] 128 blocks = self.blocks[name]
126 index = blocks.index(current) + 1 129 index = blocks.index(current) + 1
127 blocks[index] 130 blocks[index]
128 except LookupError: 131 except LookupError:
129 return self.environment.undefined('there is no parent block ' 132 return self.environment.undefined('there is no parent block '
130 'called %r.' % name, 133 'called %r.' % name,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 165
163 @internalcode 166 @internalcode
164 def call(__self, __obj, *args, **kwargs): 167 def call(__self, __obj, *args, **kwargs):
165 """Call the callable with the arguments and keyword arguments 168 """Call the callable with the arguments and keyword arguments
166 provided but inject the active context or environment as first 169 provided but inject the active context or environment as first
167 argument if the callable is a :func:`contextfunction` or 170 argument if the callable is a :func:`contextfunction` or
168 :func:`environmentfunction`. 171 :func:`environmentfunction`.
169 """ 172 """
170 if __debug__: 173 if __debug__:
171 __traceback_hide__ = True 174 __traceback_hide__ = True
175
176 # Allow callable classes to take a context
177 fn = __obj.__call__
178 for fn_type in ('contextfunction',
179 'evalcontextfunction',
180 'environmentfunction'):
181 if hasattr(fn, fn_type):
182 __obj = fn
183 break
184
172 if isinstance(__obj, _context_function_types): 185 if isinstance(__obj, _context_function_types):
173 if getattr(__obj, 'contextfunction', 0): 186 if getattr(__obj, 'contextfunction', 0):
174 args = (__self,) + args 187 args = (__self,) + args
175 elif getattr(__obj, 'evalcontextfunction', 0): 188 elif getattr(__obj, 'evalcontextfunction', 0):
176 args = (__self.eval_ctx,) + args 189 args = (__self.eval_ctx,) + args
177 elif getattr(__obj, 'environmentfunction', 0): 190 elif getattr(__obj, 'environmentfunction', 0):
178 args = (__self.environment,) + args 191 args = (__self.environment,) + args
179 try: 192 try:
180 return __obj(*args, **kwargs) 193 return __obj(*args, **kwargs)
181 except StopIteration: 194 except StopIteration:
182 return __self.environment.undefined('value was undefined because ' 195 return __self.environment.undefined('value was undefined because '
183 'a callable raised a ' 196 'a callable raised a '
184 'StopIteration exception') 197 'StopIteration exception')
185 198
186 def derived(self, locals=None): 199 def derived(self, locals=None):
187 """Internal helper function to create a derived context.""" 200 """Internal helper function to create a derived context."""
188 context = new_context(self.environment, self.name, {}, 201 context = new_context(self.environment, self.name, {},
189 self.parent, True, None, locals) 202 self.parent, True, None, locals)
190 context.vars.update(self.vars) 203 context.vars.update(self.vars)
191 context.eval_ctx = self.eval_ctx 204 context.eval_ctx = self.eval_ctx
192 context.blocks.update((k, list(v)) for k, v in self.blocks.iteritems()) 205 context.blocks.update((k, list(v)) for k, v in iteritems(self.blocks))
193 return context 206 return context
194 207
195 def _all(meth): 208 def _all(meth):
196 proxy = lambda self: getattr(self.get_all(), meth)() 209 proxy = lambda self: getattr(self.get_all(), meth)()
197 proxy.__doc__ = getattr(dict, meth).__doc__ 210 proxy.__doc__ = getattr(dict, meth).__doc__
198 proxy.__name__ = meth 211 proxy.__name__ = meth
199 return proxy 212 return proxy
200 213
201 keys = _all('keys') 214 keys = _all('keys')
202 values = _all('values') 215 values = _all('values')
203 items = _all('items') 216 items = _all('items')
204 217
205 # not available on python 3 218 # not available on python 3
206 if hasattr(dict, 'iterkeys'): 219 if PY2:
207 iterkeys = _all('iterkeys') 220 iterkeys = _all('iterkeys')
208 itervalues = _all('itervalues') 221 itervalues = _all('itervalues')
209 iteritems = _all('iteritems') 222 iteritems = _all('iteritems')
210 del _all 223 del _all
211 224
212 def __contains__(self, name): 225 def __contains__(self, name):
213 return name in self.vars or name in self.parent 226 return name in self.vars or name in self.parent
214 227
215 def __getitem__(self, key): 228 def __getitem__(self, key):
216 """Lookup a variable or raise `KeyError` if the variable is 229 """Lookup a variable or raise `KeyError` if the variable is
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 def __call__(self): 273 def __call__(self):
261 rv = concat(self._stack[self._depth](self._context)) 274 rv = concat(self._stack[self._depth](self._context))
262 if self._context.eval_ctx.autoescape: 275 if self._context.eval_ctx.autoescape:
263 rv = Markup(rv) 276 rv = Markup(rv)
264 return rv 277 return rv
265 278
266 279
267 class LoopContext(object): 280 class LoopContext(object):
268 """A loop context for dynamic iteration.""" 281 """A loop context for dynamic iteration."""
269 282
270 def __init__(self, iterable, recurse=None): 283 def __init__(self, iterable, recurse=None, depth0=0):
271 self._iterator = iter(iterable) 284 self._iterator = iter(iterable)
272 self._recurse = recurse 285 self._recurse = recurse
286 self._after = self._safe_next()
273 self.index0 = -1 287 self.index0 = -1
288 self.depth0 = depth0
274 289
275 # try to get the length of the iterable early. This must be done 290 # try to get the length of the iterable early. This must be done
276 # here because there are some broken iterators around where there 291 # here because there are some broken iterators around where there
277 # __len__ is the number of iterations left (i'm looking at your 292 # __len__ is the number of iterations left (i'm looking at your
278 # listreverseiterator!). 293 # listreverseiterator!).
279 try: 294 try:
280 self._length = len(iterable) 295 self._length = len(iterable)
281 except (TypeError, AttributeError): 296 except (TypeError, AttributeError):
282 self._length = None 297 self._length = None
283 298
284 def cycle(self, *args): 299 def cycle(self, *args):
285 """Cycles among the arguments with the current loop index.""" 300 """Cycles among the arguments with the current loop index."""
286 if not args: 301 if not args:
287 raise TypeError('no items for cycling given') 302 raise TypeError('no items for cycling given')
288 return args[self.index0 % len(args)] 303 return args[self.index0 % len(args)]
289 304
290 first = property(lambda x: x.index0 == 0) 305 first = property(lambda x: x.index0 == 0)
291 last = property(lambda x: x.index0 + 1 == x.length) 306 last = property(lambda x: x._after is _last_iteration)
292 index = property(lambda x: x.index0 + 1) 307 index = property(lambda x: x.index0 + 1)
293 revindex = property(lambda x: x.length - x.index0) 308 revindex = property(lambda x: x.length - x.index0)
294 revindex0 = property(lambda x: x.length - x.index) 309 revindex0 = property(lambda x: x.length - x.index)
310 depth = property(lambda x: x.depth0 + 1)
295 311
296 def __len__(self): 312 def __len__(self):
297 return self.length 313 return self.length
298 314
299 def __iter__(self): 315 def __iter__(self):
300 return LoopContextIterator(self) 316 return LoopContextIterator(self)
301 317
318 def _safe_next(self):
319 try:
320 return next(self._iterator)
321 except StopIteration:
322 return _last_iteration
323
302 @internalcode 324 @internalcode
303 def loop(self, iterable): 325 def loop(self, iterable):
304 if self._recurse is None: 326 if self._recurse is None:
305 raise TypeError('Tried to call non recursive loop. Maybe you ' 327 raise TypeError('Tried to call non recursive loop. Maybe you '
306 "forgot the 'recursive' modifier.") 328 "forgot the 'recursive' modifier.")
307 return self._recurse(iterable, self._recurse) 329 return self._recurse(iterable, self._recurse, self.depth0 + 1)
308 330
309 # a nifty trick to enhance the error message if someone tried to call 331 # a nifty trick to enhance the error message if someone tried to call
310 # the the loop without or with too many arguments. 332 # the the loop without or with too many arguments.
311 __call__ = loop 333 __call__ = loop
312 del loop 334 del loop
313 335
314 @property 336 @property
315 def length(self): 337 def length(self):
316 if self._length is None: 338 if self._length is None:
317 # if was not possible to get the length of the iterator when 339 # if was not possible to get the length of the iterator when
318 # the loop context was created (ie: iterating over a generator) 340 # the loop context was created (ie: iterating over a generator)
319 # we have to convert the iterable into a sequence and use the 341 # we have to convert the iterable into a sequence and use the
320 # length of that. 342 # length of that.
321 iterable = tuple(self._iterator) 343 iterable = tuple(self._iterator)
322 self._iterator = iter(iterable) 344 self._iterator = iter(iterable)
323 self._length = len(iterable) + self.index0 + 1 345 self._length = len(iterable) + self.index0 + 1
324 return self._length 346 return self._length
325 347
326 def __repr__(self): 348 def __repr__(self):
327 return '<%s %r/%r>' % ( 349 return '<%s %r/%r>' % (
328 self.__class__.__name__, 350 self.__class__.__name__,
329 self.index, 351 self.index,
330 self.length 352 self.length
331 ) 353 )
332 354
333 355
356 @implements_iterator
334 class LoopContextIterator(object): 357 class LoopContextIterator(object):
335 """The iterator for a loop context.""" 358 """The iterator for a loop context."""
336 __slots__ = ('context',) 359 __slots__ = ('context',)
337 360
338 def __init__(self, context): 361 def __init__(self, context):
339 self.context = context 362 self.context = context
340 363
341 def __iter__(self): 364 def __iter__(self):
342 return self 365 return self
343 366
344 def next(self): 367 def __next__(self):
345 ctx = self.context 368 ctx = self.context
346 ctx.index0 += 1 369 ctx.index0 += 1
347 return next(ctx._iterator), ctx 370 if ctx._after is _last_iteration:
371 raise StopIteration()
372 next_elem = ctx._after
373 ctx._after = ctx._safe_next()
374 return next_elem, ctx
348 375
349 376
350 class Macro(object): 377 class Macro(object):
351 """Wraps a macro function.""" 378 """Wraps a macro function."""
352 379
353 def __init__(self, environment, func, name, arguments, defaults, 380 def __init__(self, environment, func, name, arguments, defaults,
354 catch_kwargs, catch_varargs, caller): 381 catch_kwargs, catch_varargs, caller):
355 self._environment = environment 382 self._environment = environment
356 self._func = func 383 self._func = func
357 self._argument_count = len(arguments) 384 self._argument_count = len(arguments)
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 (self.name, len(self.arguments))) 431 (self.name, len(self.arguments)))
405 return self._func(*arguments) 432 return self._func(*arguments)
406 433
407 def __repr__(self): 434 def __repr__(self):
408 return '<%s %s>' % ( 435 return '<%s %s>' % (
409 self.__class__.__name__, 436 self.__class__.__name__,
410 self.name is None and 'anonymous' or repr(self.name) 437 self.name is None and 'anonymous' or repr(self.name)
411 ) 438 )
412 439
413 440
441 @implements_to_string
414 class Undefined(object): 442 class Undefined(object):
415 """The default undefined type. This undefined type can be printed and 443 """The default undefined type. This undefined type can be printed and
416 iterated over, but every other access will raise an :exc:`UndefinedError`: 444 iterated over, but every other access will raise an :exc:`UndefinedError`:
417 445
418 >>> foo = Undefined(name='foo') 446 >>> foo = Undefined(name='foo')
419 >>> str(foo) 447 >>> str(foo)
420 '' 448 ''
421 >>> not foo 449 >>> not foo
422 True 450 True
423 >>> foo + 42 451 >>> foo + 42
(...skipping 11 matching lines...) Expand all
435 self._undefined_exception = exc 463 self._undefined_exception = exc
436 464
437 @internalcode 465 @internalcode
438 def _fail_with_undefined_error(self, *args, **kwargs): 466 def _fail_with_undefined_error(self, *args, **kwargs):
439 """Regular callback function for undefined objects that raises an 467 """Regular callback function for undefined objects that raises an
440 `UndefinedError` on call. 468 `UndefinedError` on call.
441 """ 469 """
442 if self._undefined_hint is None: 470 if self._undefined_hint is None:
443 if self._undefined_obj is missing: 471 if self._undefined_obj is missing:
444 hint = '%r is undefined' % self._undefined_name 472 hint = '%r is undefined' % self._undefined_name
445 elif not isinstance(self._undefined_name, basestring): 473 elif not isinstance(self._undefined_name, string_types):
446 hint = '%s has no element %r' % ( 474 hint = '%s has no element %r' % (
447 object_type_repr(self._undefined_obj), 475 object_type_repr(self._undefined_obj),
448 self._undefined_name 476 self._undefined_name
449 ) 477 )
450 else: 478 else:
451 hint = '%r has no attribute %r' % ( 479 hint = '%r has no attribute %r' % (
452 object_type_repr(self._undefined_obj), 480 object_type_repr(self._undefined_obj),
453 self._undefined_name 481 self._undefined_name
454 ) 482 )
455 else: 483 else:
456 hint = self._undefined_hint 484 hint = self._undefined_hint
457 raise self._undefined_exception(hint) 485 raise self._undefined_exception(hint)
458 486
459 @internalcode 487 @internalcode
460 def __getattr__(self, name): 488 def __getattr__(self, name):
461 if name[:2] == '__': 489 if name[:2] == '__':
462 raise AttributeError(name) 490 raise AttributeError(name)
463 return self._fail_with_undefined_error() 491 return self._fail_with_undefined_error()
464 492
465 __add__ = __radd__ = __mul__ = __rmul__ = __div__ = __rdiv__ = \ 493 __add__ = __radd__ = __mul__ = __rmul__ = __div__ = __rdiv__ = \
466 __truediv__ = __rtruediv__ = __floordiv__ = __rfloordiv__ = \ 494 __truediv__ = __rtruediv__ = __floordiv__ = __rfloordiv__ = \
467 __mod__ = __rmod__ = __pos__ = __neg__ = __call__ = \ 495 __mod__ = __rmod__ = __pos__ = __neg__ = __call__ = \
468 __getitem__ = __lt__ = __le__ = __gt__ = __ge__ = __int__ = \ 496 __getitem__ = __lt__ = __le__ = __gt__ = __ge__ = __int__ = \
469 __float__ = __complex__ = __pow__ = __rpow__ = \ 497 __float__ = __complex__ = __pow__ = __rpow__ = \
470 _fail_with_undefined_error 498 _fail_with_undefined_error
471 499
500 def __eq__(self, other):
501 return type(self) is type(other)
502
503 def __ne__(self, other):
504 return not self.__eq__(other)
505
506 def __hash__(self):
507 return id(type(self))
508
472 def __str__(self): 509 def __str__(self):
473 return unicode(self).encode('utf-8')
474
475 # unicode goes after __str__ because we configured 2to3 to rename
476 # __unicode__ to __str__. because the 2to3 tree is not designed to
477 # remove nodes from it, we leave the above __str__ around and let
478 # it override at runtime.
479 def __unicode__(self):
480 return u'' 510 return u''
481 511
482 def __len__(self): 512 def __len__(self):
483 return 0 513 return 0
484 514
485 def __iter__(self): 515 def __iter__(self):
486 if 0: 516 if 0:
487 yield None 517 yield None
488 518
489 def __nonzero__(self): 519 def __nonzero__(self):
490 return False 520 return False
491 521
492 def __repr__(self): 522 def __repr__(self):
493 return 'Undefined' 523 return 'Undefined'
494 524
495 525
526 @implements_to_string
496 class DebugUndefined(Undefined): 527 class DebugUndefined(Undefined):
497 """An undefined that returns the debug info when printed. 528 """An undefined that returns the debug info when printed.
498 529
499 >>> foo = DebugUndefined(name='foo') 530 >>> foo = DebugUndefined(name='foo')
500 >>> str(foo) 531 >>> str(foo)
501 '{{ foo }}' 532 '{{ foo }}'
502 >>> not foo 533 >>> not foo
503 True 534 True
504 >>> foo + 42 535 >>> foo + 42
505 Traceback (most recent call last): 536 Traceback (most recent call last):
506 ... 537 ...
507 UndefinedError: 'foo' is undefined 538 UndefinedError: 'foo' is undefined
508 """ 539 """
509 __slots__ = () 540 __slots__ = ()
510 541
511 def __unicode__(self): 542 def __str__(self):
512 if self._undefined_hint is None: 543 if self._undefined_hint is None:
513 if self._undefined_obj is missing: 544 if self._undefined_obj is missing:
514 return u'{{ %s }}' % self._undefined_name 545 return u'{{ %s }}' % self._undefined_name
515 return '{{ no such element: %s[%r] }}' % ( 546 return '{{ no such element: %s[%r] }}' % (
516 object_type_repr(self._undefined_obj), 547 object_type_repr(self._undefined_obj),
517 self._undefined_name 548 self._undefined_name
518 ) 549 )
519 return u'{{ undefined value printed: %s }}' % self._undefined_hint 550 return u'{{ undefined value printed: %s }}' % self._undefined_hint
520 551
521 552
553 @implements_to_string
522 class StrictUndefined(Undefined): 554 class StrictUndefined(Undefined):
523 """An undefined that barks on print and iteration as well as boolean 555 """An undefined that barks on print and iteration as well as boolean
524 tests and all kinds of comparisons. In other words: you can do nothing 556 tests and all kinds of comparisons. In other words: you can do nothing
525 with it except checking if it's defined using the `defined` test. 557 with it except checking if it's defined using the `defined` test.
526 558
527 >>> foo = StrictUndefined(name='foo') 559 >>> foo = StrictUndefined(name='foo')
528 >>> str(foo) 560 >>> str(foo)
529 Traceback (most recent call last): 561 Traceback (most recent call last):
530 ... 562 ...
531 UndefinedError: 'foo' is undefined 563 UndefinedError: 'foo' is undefined
532 >>> not foo 564 >>> not foo
533 Traceback (most recent call last): 565 Traceback (most recent call last):
534 ... 566 ...
535 UndefinedError: 'foo' is undefined 567 UndefinedError: 'foo' is undefined
536 >>> foo + 42 568 >>> foo + 42
537 Traceback (most recent call last): 569 Traceback (most recent call last):
538 ... 570 ...
539 UndefinedError: 'foo' is undefined 571 UndefinedError: 'foo' is undefined
540 """ 572 """
541 __slots__ = () 573 __slots__ = ()
542 __iter__ = __unicode__ = __str__ = __len__ = __nonzero__ = __eq__ = \ 574 __iter__ = __str__ = __len__ = __nonzero__ = __eq__ = \
543 __ne__ = __bool__ = Undefined._fail_with_undefined_error 575 __ne__ = __bool__ = __hash__ = \
576 Undefined._fail_with_undefined_error
544 577
545 578
546 # remove remaining slots attributes, after the metaclass did the magic they 579 # remove remaining slots attributes, after the metaclass did the magic they
547 # are unneeded and irritating as they contain wrong data for the subclasses. 580 # are unneeded and irritating as they contain wrong data for the subclasses.
548 del Undefined.__slots__, DebugUndefined.__slots__, StrictUndefined.__slots__ 581 del Undefined.__slots__, DebugUndefined.__slots__, StrictUndefined.__slots__
OLDNEW
« no previous file with comments | « third_party/jinja2/parser.py ('k') | third_party/jinja2/sandbox.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698