.. autoclass:: jinja2.Template
- :members: render, stream, generate, module
+ :members: render, stream, generate, make_module, module
.. attribute:: globals
* jinja2._speedups
* ~~~~~~~~~~~~~~~~
*
- * This module implements a few functions in C for better performance.
+ * This module implements a few functions in C for better performance. It
+ * also defines a `tb_set_next` function that is used to patch the debug
+ * traceback. If the speedups module is not compiled a ctypes implementation
+ * is used.
*
* :copyright: 2008 by Armin Ronacher.
* :license: BSD.
/* we don't have to escape integers, bools or floats */
if (PyInt_CheckExact(text) || PyLong_CheckExact(text) ||
PyFloat_CheckExact(text) || PyBool_Check(text) ||
- text == Py_None) {
- PyObject *args = PyTuple_New(1);
- if (!args) {
- Py_DECREF(s);
- return NULL;
- }
- PyTuple_SET_ITEM(args, 0, text);
- return PyObject_CallObject(markup, args);
- }
+ text == Py_None)
+ return PyObject_CallFunctionObjArgs(markup, text, NULL);
/* if the object has an __html__ method that performs the escaping */
PyObject *html = PyObject_GetAttrString(text, "__html__");
s = escape_unicode((PyUnicodeObject*)text);
/* convert the unicode string into a markup object. */
- return PyObject_CallFunctionObjArgs(markup, (PyObject*)s, NULL);
+ rv = PyObject_CallFunctionObjArgs(markup, (PyObject*)s, NULL);
+ Py_DECREF(s);
+ return rv;
}
from jinja2 import nodes
from jinja2.visitor import NodeVisitor, NodeTransformer
from jinja2.exceptions import TemplateAssertionError
-from jinja2.runtime import concat
-from jinja2.utils import Markup
+from jinja2.utils import Markup, concat
operators = {
from jinja2.parser import Parser
from jinja2.optimizer import optimize
from jinja2.compiler import generate
-from jinja2.runtime import Undefined, Context, concat
+from jinja2.runtime import Undefined, Context
from jinja2.debug import translate_exception, translate_syntax_error
from jinja2.exceptions import TemplateSyntaxError
-from jinja2.utils import import_string, LRUCache, Markup, missing
+from jinja2.utils import import_string, LRUCache, Markup, missing, concat
# for direct template usage we have up to ten living environments
return Context(self.environment, parent, self.name, self.blocks)
def make_module(self, vars=None, shared=False):
- """Like the `module` property but always reevaluates the template
- and it's possible to provide a context.
+ """This method works like the :attr:`module` attribute when called
+ without arguments but it will evaluate the template every call
+ rather then caching the template. It's also possible to provide
+ a dict which is then used as context. The arguments are the same
+ as fo the :meth:`new_context` method.
"""
return TemplateModule(self, self.new_context(vars, shared))
# compiler too. The Include without context passing directly
# uses the mangled name. The reason why we use a mangled one
# is to avoid name clashes with macros with those names.
- self.__body_stream = tuple(template.root_render_func(context))
+ self.__body_stream = list(template.root_render_func(context))
self.__dict__.update(context.get_exported())
self.__name__ = template.name
import re
import math
from random import choice
-try:
- from operator import itemgetter
-except ImportError:
- itemgetter = lambda a: lambda b: b[a]
-from urllib import urlencode, quote
+from operator import itemgetter
from itertools import imap, groupby
from jinja2.utils import Markup, escape, pformat, urlize, soft_unicode
from jinja2.runtime import Undefined
:license: BSD, see LICENSE for more details.
"""
import operator
+from copy import copy
from types import FunctionType
from itertools import chain, izip
from collections import deque
-from copy import copy
from jinja2.utils import Markup
"""
from jinja2 import nodes
from jinja2.visitor import NodeVisitor, NodeTransformer
-from jinja2.runtime import LoopContext, concat
+from jinja2.runtime import LoopContext
+from jinja2.utils import concat
def optimize(node, environment, context_hint=None):
import sys
from types import FunctionType
from itertools import chain, imap
-from jinja2.utils import Markup, partial, soft_unicode, escape, missing
+from jinja2.utils import Markup, partial, soft_unicode, escape, missing, concat
from jinja2.exceptions import UndefinedError, TemplateRuntimeError
'markup_join', 'unicode_join']
-# concatenate a list of strings and convert them to unicode.
-# unfortunately there is a bug in python 2.4 and lower that causes
-# unicode.join trash the traceback.
-try:
- def _test_gen_bug():
- raise TypeError(_test_gen_bug)
- yield None
- u''.join(_test_gen_bug())
-except TypeError, _error:
- if _error.args and _error.args[0] is _test_gen_bug:
- concat = u''.join
- else:
- def concat(gen):
- try:
- return u''.join(list(gen))
- except:
- exc_type, exc_value, tb = sys.exc_info()
- raise exc_type, exc_value, tb.tb_next
- del _test_gen_bug, _error
-
-
def markup_join(*args):
"""Concatenation that escapes if necessary and converts to unicode."""
buf = []
def safe_range(*args):
"""A range that can't generate ranges with a length of more than
- MAX_RANGE items."""
+ MAX_RANGE items.
+ """
rng = xrange(*args)
if len(rng) > MAX_RANGE:
raise OverflowError('range too big')
def is_safe_callable(self, obj):
"""Check if an object is safely callable. Per default a function is
considered safe unless the `unsafe_callable` attribute exists and is
- truish. Override this method to alter the behavior, but this won't
+ True. Override this method to alter the behavior, but this won't
affect the `unsafe` decorator from this module.
"""
- return not getattr(obj, 'unsafe_callable', False)
+ return not (getattr(obj, 'unsafe_callable', False) or \
+ getattr(obj, 'alters_data', False))
def subscribe(self, obj, argument):
"""Subscribe an object from sandboxed code."""
missing = type('MissingType', (), {'__repr__': lambda x: 'missing'})()
+# concatenate a list of strings and convert them to unicode.
+# unfortunately there is a bug in python 2.4 and lower that causes
+# unicode.join trash the traceback.
+try:
+ def _test_gen_bug():
+ raise TypeError(_test_gen_bug)
+ yield None
+ u''.join(_test_gen_bug())
+except TypeError, _error:
+ if _error.args and _error.args[0] is _test_gen_bug:
+ concat = u''.join
+ else:
+ def concat(gen):
+ try:
+ return u''.join(list(gen))
+ except:
+ # this hack is needed so that the current frame
+ # does not show up in the traceback.
+ exc_type, exc_value, tb = sys.exc_info()
+ raise exc_type, exc_value, tb.tb_next
+ del _test_gen_bug, _error
+
+
def contextfunction(f):
"""This decorator can be used to mark a callable as context callable. A
context callable is passed the active context as first argument if it
],
packages=['jinja2'],
data_files=[
- ('docs/html', list(list_files('docs/html'))),
- ('docs/txt', list(list_files('docs/src')))
+ ##('docs', list(list_files('docs/_build/html')))
],
features={
'speedups': Feature("optional C speed-enhancements",
module='{% macro test() %}[{{ foo }}|{{ bar }}]{% endmacro %}',
header='[{{ foo }}|{{ 23 }}]'
)))
-test_env.globals['bar'] = '23'
+test_env.globals['bar'] = 23
def test_context_imports():
test_env.from_string('{% from "foo" import bar, baz with context %}')
test_env.from_string('{% from "foo" import bar, baz, with context %}')
test_env.from_string('{% from "foo" import bar, with context %}')
+ test_env.from_string('{% from "foo" import bar, with, context %}')
+ test_env.from_string('{% from "foo" import bar, with with context %}')