small performance improvements
[jinja2.git] / jinja2 / environment.py
1 # -*- coding: utf-8 -*-
2 """
3     jinja2.environment
4     ~~~~~~~~~~~~~~~~~~
5
6     Provides a class that holds runtime and parsing time options.
7
8     :copyright: 2008 by Armin Ronacher.
9     :license: BSD, see LICENSE for more details.
10 """
11 import sys
12 from jinja2.defaults import *
13 from jinja2.lexer import Lexer
14 from jinja2.parser import Parser
15 from jinja2.optimizer import optimize
16 from jinja2.compiler import generate
17 from jinja2.runtime import Undefined, Context, concat
18 from jinja2.debug import translate_exception
19 from jinja2.utils import import_string, LRUCache, Markup, missing
20
21
22 # for direct template usage we have up to ten living environments
23 _spontaneous_environments = LRUCache(10)
24
25
26 def get_spontaneous_environment(*args):
27     """Return a new spontaneus environment.  A spontaneus environment is an
28     unnamed and unaccessable (in theory) environment that is used for
29     template generated from a string and not from the file system.
30     """
31     try:
32         env = _spontaneous_environments.get(args)
33     except TypeError:
34         return Environment(*args)
35     if env is not None:
36         return env
37     _spontaneous_environments[args] = env = Environment(*args)
38     env.shared = True
39     return env
40
41
42 def create_cache(size):
43     """Return the cache class for the given size."""
44     if size == 0:
45         return None
46     if size < 0:
47         return {}
48     return LRUCache(size)
49
50
51 def load_extensions(environment, extensions):
52     """Load the extensions from the list and bind it to the environment.
53     Returns a new list of instanciated environments.
54     """
55     result = []
56     for extension in extensions:
57         if isinstance(extension, basestring):
58             extension = import_string(extension)
59         result.append(extension(environment))
60     return result
61
62
63 def _environment_sanity_check(environment):
64     """Perform a sanity check on the environment."""
65     assert issubclass(environment.undefined, Undefined), 'undefined must ' \
66            'be a subclass of undefined because filters depend on it.'
67     assert environment.block_start_string != \
68            environment.variable_start_string != \
69            environment.comment_start_string, 'block, variable and comment ' \
70            'start strings must be different'
71     return environment
72
73
74 class Environment(object):
75     """The core component of Jinja is the `Environment`.  It contains
76     important shared variables like configuration, filters, tests,
77     globals and others.  Instances of this class may be modified if
78     they are not shared and if no template was loaded so far.
79     Modifications on environments after the first template was loaded
80     will lead to surprising effects and undefined behavior.
81
82     Here the possible initialization parameters:
83
84     `block_start_string`
85         The string marking the begin of a block.  Defaults to ``'{%'``.
86
87     `block_end_string`
88         The string marking the end of a block.  Defaults to ``'%}'``.
89
90     `variable_start_string`
91         The string marking the begin of a print statement.
92         Defaults to ``'{{'``.
93
94     `comment_start_string`
95         The string marking the begin of a comment.  Defaults to ``'{#'``.
96
97     `comment_end_string`
98         The string marking the end of a comment.  Defaults to ``'#}'``.
99
100     `line_statement_prefix`
101         If given and a string, this will be used as prefix for line based
102         statements.
103
104     `trim_blocks`
105         If this is set to ``True`` the first newline after a block is
106         removed (block, not variable tag!).  Defaults to `False`.
107
108     `extensions`
109         List of Jinja extensions to use.  This can either be import paths
110         as strings or extension classes.
111
112     `optimized`
113         should the optimizer be enabled?  Default is `True`.
114
115     `undefined`
116         :class:`Undefined` or a subclass of it that is used to represent
117         undefined values in the template.
118
119     `finalize`
120         A callable that finalizes the variable.  Per default no finalizing
121         is applied.
122
123     `autoescape`
124         If set to true the XML/HTML autoescaping feature is enabled.
125
126     `loader`
127         The template loader for this environment.
128
129     `cache_size`
130         The size of the cache.  Per default this is ``50`` which means that if
131         more than 50 templates are loaded the loader will clean out the least
132         recently used template.  If the cache size is set to ``0`` templates are
133         recompiled all the time, if the cache size is ``-1`` the cache will not
134         be cleaned.
135
136     `auto_reload`
137         Some loaders load templates from locations where the template sources
138         may change (ie: file system or database).  If `auto_reload` is set to
139         `True` (default) every time a template is requested the loader checks
140         if the source changed and if yes, it will reload the template.  For
141         higher performance it's possible to disable that.
142     """
143
144     #: if this environment is sandboxed.  Modifying this variable won't make
145     #: the environment sandboxed though.  For a real sandboxed environment
146     #: have a look at jinja2.sandbox
147     sandboxed = False
148
149     #: True if the environment is just an overlay
150     overlay = False
151
152     #: the environment this environment is linked to if it is an overlay
153     linked_to = None
154
155     #: shared environments have this set to `True`.  A shared environment
156     #: must not be modified
157     shared = False
158
159     def __init__(self,
160                  block_start_string=BLOCK_START_STRING,
161                  block_end_string=BLOCK_END_STRING,
162                  variable_start_string=VARIABLE_START_STRING,
163                  variable_end_string=VARIABLE_END_STRING,
164                  comment_start_string=COMMENT_START_STRING,
165                  comment_end_string=COMMENT_END_STRING,
166                  line_statement_prefix=LINE_STATEMENT_PREFIX,
167                  trim_blocks=False,
168                  extensions=(),
169                  optimized=True,
170                  undefined=Undefined,
171                  finalize=None,
172                  autoescape=False,
173                  loader=None,
174                  cache_size=50,
175                  auto_reload=True):
176         # !!Important notice!!
177         #   The constructor accepts quite a few arguments that should be
178         #   passed by keyword rather than position.  However it's important to
179         #   not change the order of arguments because it's used at least
180         #   internally in those cases:
181         #       -   spontaneus environments (i18n extension and Template)
182         #       -   unittests
183         #   If parameter changes are required only add parameters at the end
184         #   and don't change the arguments (or the defaults!) of the arguments
185         #   existing already.
186
187         # lexer / parser information
188         self.block_start_string = block_start_string
189         self.block_end_string = block_end_string
190         self.variable_start_string = variable_start_string
191         self.variable_end_string = variable_end_string
192         self.comment_start_string = comment_start_string
193         self.comment_end_string = comment_end_string
194         self.line_statement_prefix = line_statement_prefix
195         self.trim_blocks = trim_blocks
196
197         # runtime information
198         self.undefined = undefined
199         self.optimized = optimized
200         self.finalize = finalize
201         self.autoescape = autoescape
202
203         # defaults
204         self.filters = DEFAULT_FILTERS.copy()
205         self.tests = DEFAULT_TESTS.copy()
206         self.globals = DEFAULT_NAMESPACE.copy()
207
208         # set the loader provided
209         self.loader = loader
210         self.cache = create_cache(cache_size)
211         self.auto_reload = auto_reload
212
213         # load extensions
214         self.extensions = load_extensions(self, extensions)
215
216         _environment_sanity_check(self)
217
218     def overlay(self, block_start_string=missing, block_end_string=missing,
219                 variable_start_string=missing, variable_end_string=missing,
220                 comment_start_string=missing, comment_end_string=missing,
221                 line_statement_prefix=missing, trim_blocks=missing,
222                 extensions=missing, optimized=missing, undefined=missing,
223                 finalize=missing, autoescape=missing, loader=missing,
224                 cache_size=missing, auto_reload=missing):
225         """Create a new overlay environment that shares all the data with the
226         current environment except of cache and the overriden attributes.
227         Extensions cannot be removed for a overlayed environment.  A overlayed
228         environment automatically gets all the extensions of the environment it
229         is linked to plus optional extra extensions.
230
231         Creating overlays should happen after the initial environment was set
232         up completely.  Not all attributes are truly linked, some are just
233         copied over so modifications on the original environment may not shine
234         through.
235         """
236         args = dict(locals())
237         del args['self'], args['cache_size'], args['extensions']
238
239         rv = object.__new__(self.__class__)
240         rv.__dict__.update(self.__dict__)
241         rv.overlay = True
242         rv.linked_to = self
243
244         for key, value in args.iteritems():
245             if value is not missing:
246                 setattr(rv, key, value)
247
248         if cache_size is not missing:
249             rv.cache = create_cache(cache_size)
250
251         rv.extensions = []
252         for extension in self.extensions:
253             rv.extensions.append(extension.bind(self))
254         if extensions is not missing:
255             rv.extensions.extend(load_extensions(extensions))
256
257         return _environment_sanity_check(rv)
258
259     @property
260     def lexer(self):
261         """Return a fresh lexer for the environment."""
262         return Lexer(self)
263
264     def subscribe(self, obj, argument):
265         """Get an item or attribute of an object."""
266         try:
267             return getattr(obj, str(argument))
268         except (AttributeError, UnicodeError):
269             try:
270                 return obj[argument]
271             except (TypeError, LookupError):
272                 return self.undefined(obj=obj, name=argument)
273
274     def parse(self, source, name=None):
275         """Parse the sourcecode and return the abstract syntax tree.  This
276         tree of nodes is used by the compiler to convert the template into
277         executable source- or bytecode.  This is useful for debugging or to
278         extract information from templates.
279         """
280         return Parser(self, source, name).parse()
281
282     def lex(self, source, name=None):
283         """Lex the given sourcecode and return a generator that yields
284         tokens as tuples in the form ``(lineno, token_type, value)``.
285         """
286         return self.lexer.tokeniter(source, name)
287
288     def compile(self, source, name=None, filename=None, globals=None,
289                 raw=False):
290         """Compile a node or template source code.  The `name` parameter is
291         the load name of the template after it was joined using
292         :meth:`join_path` if necessary, not the filename on the file system.
293         the `filename` parameter is the estimated filename of the template on
294         the file system.  If the template came from a database or memory this
295         can be omitted.  The `globals` parameter can be used to provide extra
296         variables at compile time for the template.  In the future the
297         optimizer will be able to evaluate parts of the template at compile
298         time based on those variables.
299
300         The return value of this method is a python code object.  If the `raw`
301         parameter is `True` the return value will be a string with python
302         code equivalent to the bytecode returned otherwise.  This method is
303         mainly used internally.
304         """
305         if isinstance(source, basestring):
306             source = self.parse(source, name)
307         if self.optimized:
308             node = optimize(source, self, globals or {})
309         source = generate(node, self, name, filename)
310         if raw:
311             return source
312         if filename is None:
313             filename = '<template>'
314         elif isinstance(filename, unicode):
315             filename = filename.encode('utf-8')
316         return compile(source, filename, 'exec')
317
318     def join_path(self, template, parent):
319         """Join a template with the parent.  By default all the lookups are
320         relative to the loader root so this method returns the `template`
321         parameter unchanged, but if the paths should be relative to the
322         parent template, this function can be used to calculate the real
323         template name.
324
325         Subclasses may override this method and implement template path
326         joining here.
327         """
328         return template
329
330     def get_template(self, name, parent=None, globals=None):
331         """Load a template from the loader.  If a loader is configured this
332         method ask the loader for the template and returns a :class:`Template`.
333         If the `parent` parameter is not `None`, :meth:`join_path` is called
334         to get the real template name before loading.
335
336         The `globals` parameter can be used to provide compile-time globals.
337         In the future this will allow the optimizer to render parts of the
338         templates at compile-time.
339
340         If the template does not exist a :exc:`TemplateNotFound` exception is
341         raised.
342         """
343         if self.loader is None:
344             raise TypeError('no loader for this environment specified')
345         if parent is not None:
346             name = self.join_path(name, parent)
347
348         if self.cache is not None:
349             template = self.cache.get(name)
350             if template is not None and (not self.auto_reload or \
351                                          template.is_up_to_date):
352                 return template
353
354         template = self.loader.load(self, name, self.make_globals(globals))
355         if self.cache is not None:
356             self.cache[name] = template
357         return template
358
359     def from_string(self, source, globals=None, template_class=None):
360         """Load a template from a string.  This parses the source given and
361         returns a :class:`Template` object.
362         """
363         globals = self.make_globals(globals)
364         cls = template_class or self.template_class
365         return cls.from_code(self, self.compile(source, globals=globals),
366                              globals, None)
367
368     def make_globals(self, d):
369         """Return a dict for the globals."""
370         if d is None:
371             return self.globals
372         return dict(self.globals, **d)
373
374
375 class Template(object):
376     """The central template object.  This class represents a compiled template
377     and is used to evaluate it.
378
379     Normally the template object is generated from an :class:`Environment` but
380     it also has a constructor that makes it possible to create a template
381     instance directly using the constructor.  It takes the same arguments as
382     the environment constructor but it's not possible to specify a loader.
383
384     Every template object has a few methods and members that are guaranteed
385     to exist.  However it's important that a template object should be
386     considered immutable.  Modifications on the object are not supported.
387
388     Template objects created from the constructor rather than an environment
389     do have an `environment` attribute that points to a temporary environment
390     that is probably shared with other templates created with the constructor
391     and compatible settings.
392
393     >>> template = Template('Hello {{ name }}!')
394     >>> template.render(name='John Doe')
395     u'Hello John Doe!'
396
397     >>> stream = template.stream(name='John Doe')
398     >>> stream.next()
399     u'Hello John Doe!'
400     >>> stream.next()
401     Traceback (most recent call last):
402         ...
403     StopIteration
404     """
405
406     def __new__(cls, source,
407                 block_start_string='{%',
408                 block_end_string='%}',
409                 variable_start_string='{{',
410                 variable_end_string='}}',
411                 comment_start_string='{#',
412                 comment_end_string='#}',
413                 line_statement_prefix=None,
414                 trim_blocks=False,
415                 extensions=(),
416                 optimized=True,
417                 undefined=Undefined,
418                 finalize=None,
419                 autoescape=False):
420         env = get_spontaneous_environment(
421             block_start_string, block_end_string, variable_start_string,
422             variable_end_string, comment_start_string, comment_end_string,
423             line_statement_prefix, trim_blocks, tuple(extensions), optimized,
424             undefined, finalize, autoescape, None, 0, False)
425         return env.from_string(source, template_class=cls)
426
427     @classmethod
428     def from_code(cls, environment, code, globals, uptodate=None):
429         """Creates a template object from compiled code and the globals.  This
430         is used by the loaders and environment to create a template object.
431         """
432         t = object.__new__(cls)
433         namespace = {
434             'environment':          environment,
435             '__jinja_template__':   t
436         }
437         exec code in namespace
438         t.environment = environment
439         t.name = namespace['name']
440         t.filename = code.co_filename
441         t.root_render_func = namespace['root']
442         t.blocks = namespace['blocks']
443         t.globals = globals
444
445         # debug and loader helpers
446         t._debug_info = namespace['debug_info']
447         t._uptodate = uptodate
448
449         return t
450
451     def render(self, *args, **kwargs):
452         """This method accepts the same arguments as the `dict` constructor:
453         A dict, a dict subclass or some keyword arguments.  If no arguments
454         are given the context will be empty.  These two calls do the same::
455
456             template.render(knights='that say nih')
457             template.render({'knights': 'that say nih'})
458
459         This will return the rendered template as unicode string.
460         """
461         try:
462             return concat(self._generate(*args, **kwargs))
463         except:
464             exc_type, exc_value, tb = translate_exception(sys.exc_info())
465             raise exc_type, exc_value, tb
466
467     def stream(self, *args, **kwargs):
468         """Works exactly like :meth:`generate` but returns a
469         :class:`TemplateStream`.
470         """
471         return TemplateStream(self.generate(*args, **kwargs))
472
473     def generate(self, *args, **kwargs):
474         """For very large templates it can be useful to not render the whole
475         template at once but evaluate each statement after another and yield
476         piece for piece.  This method basically does exactly that and returns
477         a generator that yields one item after another as unicode strings.
478
479         It accepts the same arguments as :meth:`render`.
480         """
481         try:
482             for item in self._generate(*args, **kwargs):
483                 yield item
484         except:
485             exc_type, exc_value, tb = translate_exception(sys.exc_info())
486             raise exc_type, exc_value, tb
487
488     def _generate(self, *args, **kwargs):
489         # assemble the context
490         context = dict(*args, **kwargs)
491
492         # if the environment is using the optimizer locals may never
493         # override globals as optimizations might have happened
494         # depending on values of certain globals.  This assertion goes
495         # away if the python interpreter is started with -O
496         if __debug__ and self.environment.optimized:
497             overrides = set(context) & set(self.globals)
498             if overrides:
499                 plural = len(overrides) != 1 and 's' or ''
500                 raise AssertionError('the per template variable%s %s '
501                                      'override%s global variable%s. '
502                                      'With an enabled optimizer this '
503                                      'will lead to unexpected results.' %
504                     (plural, ', '.join(overrides), plural or ' a', plural))
505
506         return self.root_render_func(self.new_context(context))
507
508     def new_context(self, vars=None, shared=False):
509         """Create a new template context for this template.  The vars
510         provided will be passed to the template.  Per default the globals
511         are added to the context, if shared is set to `True` the data
512         provided is used as parent namespace.  This is used to share the
513         same globals in multiple contexts without consuming more memory.
514         (This works because the context does not modify the parent dict)
515         """
516         if vars is None:
517             vars = {}
518         if shared:
519             parent = vars
520         else:
521             parent = dict(self.globals, **vars)
522         return Context(self.environment, parent, self.name, self.blocks)
523
524     @property
525     def module(self):
526         """The template as module.  This is used for imports in the
527         template runtime but is also useful if one wants to access
528         exported template variables from the Python layer:
529
530         >>> t = Template('{% macro foo() %}42{% endmacro %}23')
531         >>> unicode(t.module)
532         u'23'
533         >>> t.module.foo()
534         u'42'
535         """
536         if hasattr(self, '_module'):
537             return self._module
538         self._module = rv = TemplateModule(self, self.new_context())
539         return rv
540
541     def get_corresponding_lineno(self, lineno):
542         """Return the source line number of a line number in the
543         generated bytecode as they are not in sync.
544         """
545         for template_line, code_line in reversed(self.debug_info):
546             if code_line <= lineno:
547                 return template_line
548         return 1
549
550     @property
551     def is_up_to_date(self):
552         """If this variable is `False` there is a newer version available."""
553         if self._uptodate is None:
554             return True
555         return self._uptodate()
556
557     @property
558     def debug_info(self):
559         """The debug info mapping."""
560         return [tuple(map(int, x.split('='))) for x in
561                 self._debug_info.split('&')]
562
563     def __repr__(self):
564         if self.name is None:
565             name = 'memory:%x' % id(self)
566         else:
567             name = repr(self.name)
568         return '<%s %s>' % (self.__class__.__name__, name)
569
570
571 class TemplateModule(object):
572     """Represents an imported template.  All the exported names of the
573     template are available as attributes on this object.  Additionally
574     converting it into an unicode- or bytestrings renders the contents.
575     """
576
577     def __init__(self, template, context):
578         self.__body_stream = tuple(template.root_render_func(context))
579         self.__dict__.update(context.get_exported())
580         self.__name__ = template.name
581
582     __html__ = lambda x: Markup(concat(x.__body_stream))
583     __unicode__ = lambda x: unicode(concat(x.__body_stream))
584
585     def __str__(self):
586         return unicode(self).encode('utf-8')
587
588     def __repr__(self):
589         if self.__name__ is None:
590             name = 'memory:%x' % id(self)
591         else:
592             name = repr(self.name)
593         return '<%s %s>' % (self.__class__.__name__, name)
594
595
596 class TemplateStream(object):
597     """A template stream works pretty much like an ordinary python generator
598     but it can buffer multiple items to reduce the number of total iterations.
599     Per default the output is unbuffered which means that for every unbuffered
600     instruction in the template one unicode string is yielded.
601
602     If buffering is enabled with a buffer size of 5, five items are combined
603     into a new unicode string.  This is mainly useful if you are streaming
604     big templates to a client via WSGI which flushes after each iteration.
605     """
606
607     def __init__(self, gen):
608         self._gen = gen
609         self._next = gen.next
610         self.buffered = False
611
612     def disable_buffering(self):
613         """Disable the output buffering."""
614         self._next = self._gen.next
615         self.buffered = False
616
617     def enable_buffering(self, size=5):
618         """Enable buffering.  Buffer `size` items before yielding them."""
619         if size <= 1:
620             raise ValueError('buffer size too small')
621
622         def generator():
623             buf = []
624             c_size = 0
625             push = buf.append
626             next = self._gen.next
627
628             while 1:
629                 try:
630                     while c_size < size:
631                         push(next())
632                         c_size += 1
633                 except StopIteration:
634                     if not c_size:
635                         return
636                 yield concat(buf)
637                 del buf[:]
638                 c_size = 0
639
640         self.buffered = True
641         self._next = generator().next
642
643     def __iter__(self):
644         return self
645
646     def next(self):
647         return self._next()
648
649
650 # hook in default template class.  if anyone reads this comment: ignore that
651 # it's possible to use custom templates ;-)
652 Environment.template_class = Template