Jason Pellerin avatar Jason Pellerin committed 2c00822 Merge

Merged from upstream

Comments (0)

Files changed (34)

 - Cameron Knight
 - Peter van Dijk (Habbie)
 - Stefan Ebner
+- Rene Leonhardt
   *before* the loop.  (#331)
 - Added support for optional `scoped` modifier to blocks.
 - Added support for line-comments.
+- Added the `meta` module.
+- Renamed (undocumented) attribute overlay to overlayed on the environment
+  because it was clashing with a method of the same name.  The new attribute
+  is called "overlayed".
 
 Version 2.1.1
 -------------
+test:
+	cd tests; nosetests -v
+
+.PHONY: test
     change it in a backwards incompatible way but modifications in the Jinja2
     core may shine through.  For example if Jinja2 introduces a new AST node
     in later versions that may be returned by :meth:`~Environment.parse`.
+
+The Meta API
+------------
+
+.. versionadded:: 2.2
+
+The meta API returns some information about abstract syntax trees that
+could help applications to implement more advanced template concepts.  All
+the functions of the meta API operate on an abstract syntax tree as
+returned by the :meth:`Environment.parse` method.
+
+.. autofunction:: jinja2.meta.find_undeclared_variables
+
+.. autofunction:: jinja2.meta.find_referenced_templates

docs/changelog.rst

-Changelog
-=========
+.. module:: jinja2
 
-.. jinjachangelog::
+.. include:: ../CHANGES
 # typographically correct entities.
 #html_use_smartypants = True
 
-# use jinja2 for templates
-template_bridge = 'jinjaext.Jinja2Bridge'
-
 # no modindex
 html_use_modindex = False
 
     }
 
 
-class Jinja2Bridge(TemplateBridge):
-
-    def init(self, builder):
-        path = builder.config.templates_path
-        self.env = Environment(loader=FileSystemLoader(path))
-
-    def render(self, template, context):
-        return self.env.get_template(template).render(context)
-
-
 _sig_re = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*(\(.*?\))')
 
 
     return directive
 
 
-def jinja_changelog(dirname, arguments, options, content, lineno,
-                    content_offset, block_text, state, state_machine):
-    doc = ViewList()
-    changelog = file(os.path.join(os.path.dirname(jinja2.__file__), '..',
-                                  'CHANGES'))
-    try:
-        for line in islice(changelog, 3, None):
-            doc.append(line.rstrip().decode('utf-8'), '<jinjaext>')
-    finally:
-        changelog.close()
-    return parse_rst(state, content_offset, doc)
-
-
 from jinja2.defaults import DEFAULT_FILTERS, DEFAULT_TESTS
 jinja_filters = dump_functions(DEFAULT_FILTERS)
 jinja_tests = dump_functions(DEFAULT_TESTS)
 def setup(app):
     app.add_directive('jinjafilters', jinja_filters, 0, (0, 0, 0))
     app.add_directive('jinjatests', jinja_tests, 0, (0, 0, 0))
-    app.add_directive('jinjachangelog', jinja_changelog, 0, (0, 0, 0))
     app.add_directive('jinjanodes', jinja_nodes, 0, (0, 0, 0))
     # uncomment for inline toc.  links are broken unfortunately
     ##app.connect('doctree-resolved', inject_toc)

ext/django2jinja/django2jinja.py

 _newline_re = re.compile(r'(?:\r\n|\r|\n)')
 
 
-# don't ask....
+# Django stores an itertools object on the cycle node.  Not only is this
+# thread unsafe but also a problem for the converter which needs the raw
+# string values passed to the constructor to create a jinja loop.cycle()
+# call from it.
 _old_cycle_init = core_tags.CycleNode.__init__
 def _fixed_cycle_init(self, cyclevars, variable_name=None):
     self.raw_cycle_vars = map(Variable, cyclevars)

fabfile.py

-# -*- coding: utf-8 -*-
-"""
-    Jinja fabfile
-    ~~~~~~~~~~~~~
-
-    Shortcuts for various tasks.
-
-    :copyright: Copyright 2008 by Armin Ronacher.
-    :license: BSD.
-"""
-
-
-def test():
-    """Run the testsuite."""
-    local("cd tests; py.test")
-
-
-def pylint():
-    """Run pylint."""
-    local("pylint --rcfile scripts/pylintrc jinja")
-
-
-def release(**kwargs):
-    """Release, tag and upload Jinja2 to the Cheeseshop."""
-    import re
-    _version_re = re.compile(r'VERSION\s*=\s["\'](.*?)["\']')
-    f = file("setup.py")
-    try:
-        for line in f:
-            match = _version_re.match(line)
-            if match is not None:
-                version = match.group(1)
-                break
-        else:
-            raise RuntimeError('no version def in setup.py :-/')
-    finally:
-        f.close()
-
-    local('hg tag -m "%s" "%s"' % ('tagged %r' % version, version))
-    local('python setup.py release sdist upload')

jinja2/environment.py

     sandboxed = False
 
     #: True if the environment is just an overlay
-    overlay = False
+    overlayed = False
 
     #: the environment this environment is linked to if it is an overlay
     linked_to = None
 
         rv = object.__new__(self.__class__)
         rv.__dict__.update(self.__dict__)
-        rv.overlay = True
+        rv.overlayed = True
         rv.linked_to = self
 
         for key, value in args.iteritems():
+# -*- coding: utf-8 -*-
+"""
+    jinja2.meta
+    ~~~~~~~~~~~
+
+    This module implements various functions that exposes information about
+    templates that might be interesting for various kinds of applications.
+
+    :copyright: (c) 2009 by the Jinja2 Team, see AUTHORS for more details.
+    :license: BSD, see LICENSE for more details.
+"""
+from jinja2 import nodes
+from jinja2.compiler import CodeGenerator
+
+
+class TrackingCodeGenerator(CodeGenerator):
+    """We abuse the code generator for introspection."""
+
+    def __init__(self, environment):
+        CodeGenerator.__init__(self, environment, '<introspection>',
+                               '<introspection>')
+        self.undeclared_identifiers = set()
+
+    def write(self, x):
+        """Don't write."""
+
+    def pull_locals(self, frame):
+        """Remember all undeclared identifiers."""
+        self.undeclared_identifiers.update(frame.identifiers.undeclared)
+
+
+def find_undeclared_variables(ast):
+    """Returns a set of all variables in the AST that will be looked up from
+    the context at runtime.  Because at compile time it's not known which
+    variables will be used depending on the path the execution takes at
+    runtime, all variables are returned.
+
+    >>> from jinja2 import Environment, meta
+    >>> env = Environment()
+    >>> ast = env.parse('{% set foo = 42 %}{{ bar + foo }}')
+    >>> meta.find_undeclared_variables(ast)
+    set(['bar'])
+
+    .. admonition:: Implementation
+
+       Internally the code generator is used for finding undeclared variables.
+       This is good to know because the code generator might raise a
+       :exc:`TemplateAssertionError` during compilation and as a matter of
+       fact this function can currently raise that exception as well.
+    """
+    codegen = TrackingCodeGenerator(ast.environment)
+    codegen.visit(ast)
+    return codegen.undeclared_identifiers
+
+
+def find_referenced_templates(ast):
+    """Finds all the referenced templates from the AST.  This will return an
+    iterator over all the hardcoded template extensions, inclusions and
+    imports.  If dynamic inheritance or inclusion is used, `None` will be
+    yielded.
+
+    >>> from jinja2 import Environment, meta
+    >>> env = Environment()
+    >>> ast = env.parse('{% extends "layout.html" %}{% include helper %}')
+    >>> list(meta.find_referenced_templates(ast))
+    ['layout.html', None]
+
+    This function is useful for dependency tracking.  For example if you want
+    to rebuild parts of the website after a layout template has changed.
+    """
+    for node in ast.find_all((nodes.Extends, nodes.FromImport, nodes.Import,
+                              nodes.Include)):
+        if isinstance(node.template, nodes.Const) and \
+           isinstance(node.template.value, basestring):
+            yield node.template.value
+        else:
+            yield None
             return result
 
     def find_all(self, node_type):
-        """Find all the nodes of a given type."""
+        """Find all the nodes of a given type.  If the type is a tuple,
+        the check is performed for any of the tuple items.
+        """
         for child in self.iter_child_nodes():
             if isinstance(child, node_type):
                 yield child
 
 [aliases]
 release = egg_info -RDb ''
+
+[nosetests]
+#verbosity=2
+detailed-errors=1
+cover-package=nose
+where=tests

tests/conftest.py

-# -*- coding: utf-8 -*-
-"""
-    conftest
-    ~~~~~~~~
-
-    Configure py.test for support stuff.
-
-    :copyright: (c) 2009 by the Jinja Team.
-    :license: BSD, see LICENSE for more details.
-"""
-
-import os
-import sys
-sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
-
-import py
-from jinja2 import Environment
-from jinja2.loaders import BaseLoader
-from jinja2.exceptions import TemplateNotFound
-
-
-try:
-    # This code adds support for coverage.py (see
-    # http://nedbatchelder.com/code/modules/coverage.html).
-    # It prints a coverage report for the modules specified in all
-    # module globals (of the test modules) named "coverage_modules".
-
-    import coverage, atexit
-
-    IGNORED_MODULES = ['jinja2._speedups', 'jinja2.defaults',
-                       'jinja2.translators']
-
-    def report_coverage():
-        coverage.stop()
-        module_list = [
-            mod for name, mod in sys.modules.copy().iteritems() if
-            getattr(mod, '__file__', None) and
-            name.startswith('jinja2.') and
-            name not in IGNORED_MODULES
-        ]
-        module_list.sort()
-        coverage.report(module_list)
-
-    def callback(option, opt_str, value, parser):
-        atexit.register(report_coverage)
-        coverage.erase()
-        coverage.start()
-
-    py.test.config.addoptions('Test options', py.test.config.Option('-C',
-        '--coverage', action='callback', callback=callback,
-        help='Output information about code coverage (slow!)'))
-
-except ImportError:
-    coverage = None
-
-
-class GlobalLoader(BaseLoader):
-    scope = globals()
-
-    def get_source(self, environment, name):
-        try:
-            return self.scope[name.upper() + 'TEMPLATE'], None, None
-        except KeyError:
-            raise TemplateNotFound(name)
-
-
-loader = GlobalLoader()
-simple_env = Environment(trim_blocks=True, loader=loader, cache_size=0)
-
-
-class Directory(py.test.collect.Directory):
-
-    def run(self):
-        rv = super(Directory, self).run()
-        if self.fspath.basename == 'tests':
-            rv.append('doctests')
-        return rv
-
-    def join(self, name):
-        if name == 'doctests':
-            return JinjaDocTestModule(name, parent=self)
-        return super(Directory, self).join(name)
-
-
-class Module(py.test.collect.Module):
-
-    def __init__(self, *args, **kwargs):
-        self.env = simple_env
-        super(Module, self).__init__(*args, **kwargs)
-
-    def makeitem(self, name, obj, usefilters=True):
-        if name.startswith('test_'):
-            if hasattr(obj, 'func_code'):
-                return JinjaTestFunction(name, parent=self)
-            elif isinstance(obj, basestring):
-                return JinjaDocTest(name, parent=self)
-
-
-class JinjaTestFunction(py.test.collect.Function):
-
-    def execute(self, target, *args):
-        loader.scope = target.func_globals
-        co = target.func_code
-        if 'env' in co.co_varnames[:co.co_argcount]:
-            target(self.parent.env, *args)
-        else:
-            target(*args)
-
-
-class JinjaDocTest(py.test.collect.Item):
-
-    def __init__(self, *args, **kwargs):
-        realmod = kwargs.pop('realmod', False)
-        super(JinjaDocTest, self).__init__(*args, **kwargs)
-        self.realmod = realmod
-
-    def run(self):
-        if self.realmod:
-            mod = __import__(self.name, None, None, [''])
-        else:
-            mod = py.std.types.ModuleType(self.name)
-            mod.__doc__ = self.obj
-            mod.env = self.parent.env
-            mod.MODULE = self.parent.obj
-        self.execute(mod)
-
-    def execute(self, mod):
-        failed, tot = py.compat.doctest.testmod(mod, verbose=True)
-        if failed:
-            py.test.fail('doctest %s: %s failed out of %s' % (
-                         self.fspath, failed, tot))
-
-
-class JinjaDocTestModule(py.test.collect.Module):
-
-    def __init__(self, *args, **kwargs):
-        super(JinjaDocTestModule, self).__init__(*args, **kwargs)
-        self.doctest_modules = [
-            'jinja2.environment', 'jinja2.compiler', 'jinja2.parser',
-            'jinja2.lexer', 'jinja2.ext', 'jinja2.sandbox',
-            'jinja2.filters', 'jinja2.tests', 'jinja2.utils',
-            'jinja2.runtime'
-        ]
-
-    def run(self):
-        return self.doctest_modules
-
-    def join(self, name):
-        return JinjaDocTest(name, parent=self, realmod=True)

tests/test_debug.py

 from jinja2 import Environment
 from test_loaders import filesystem_loader
 
-
 env = Environment(loader=filesystem_loader)
 
 
-test_runtime_error = '''
->>> tmpl = MODULE.env.get_template('broken.html')
+def test_runtime_error():
+    '''
+>>> tmpl = env.get_template('broken.html')
 >>> tmpl.render(fail=lambda: 1 / 0)
 Traceback (most recent call last):
   File "loaderres/templates/broken.html", line 2, in top-level template code
 '''
 
 
-test_syntax_error = '''
->>> tmpl = MODULE.env.get_template('syntaxerror.html')
+def test_syntax_error():
+    '''
+>>> tmpl = env.get_template('syntaxerror.html')
 Traceback (most recent call last):
   ...
-  File "loaderres/templates/syntaxerror.html", line 4
+TemplateSyntaxError: unknown tag 'endif'
+  File "loaderres/templates\\syntaxerror.html", line 4
     {% endif %}
-TemplateSyntaxError: unknown tag 'endif'
 '''
 
 
-test_regular_syntax_error = '''
+def test_regular_syntax_error():
+    '''
 >>> from jinja2.exceptions import TemplateSyntaxError
 >>> raise TemplateSyntaxError('wtf', 42)
 Traceback (most recent call last):

tests/test_filters.py

 """
 from jinja2 import Markup, Environment
 
+env = Environment()
+
 
 CAPITALIZE = '''{{ "foo bar"|capitalize }}'''
 CENTER = '''{{ "foo"|center(9) }}'''
 {{ 2.1234|round(2, 'floor') }}|{{ 2.1|round(0, 'ceil') }}'''
 XMLATTR = '''{{ {'foo': 42, 'bar': 23, 'fish': none,
 'spam': missing, 'blub:blub': '<?>'}|xmlattr }}'''
-SORT = '''{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}'''
+SORT1 = '''{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}'''
 GROUPBY = '''{% for grouper, list in [{'foo': 1, 'bar': 2},
                  {'foo': 2, 'bar': 3},
                  {'foo': 1, 'bar': 1},
 {{ grouper }}: {{ list|join(', ') }}
 {% endfor %}'''
 FILTERTAG = '''{% filter upper|replace('FOO', 'foo') %}foobar{% endfilter %}'''
-SORT = '''{{ ['foo', 'Bar', 'blah']|sort }}'''
+SORT2 = '''{{ ['foo', 'Bar', 'blah']|sort }}'''
 
 
-def test_capitalize(env):
+def test_capitalize():
     tmpl = env.from_string(CAPITALIZE)
     assert tmpl.render() == 'Foo bar'
 
 
-def test_center(env):
+def test_center():
     tmpl = env.from_string(CENTER)
     assert tmpl.render() == '   foo   '
 
 
-def test_default(env):
+def test_default():
     tmpl = env.from_string(DEFAULT)
     assert tmpl.render(given='yes') == 'no|False|no|yes'
 
 
-def test_dictsort(env):
+def test_dictsort():
     tmpl = env.from_string(DICTSORT)
     out = tmpl.render(foo={"a": 0, "b": 1, "c": 2, "A": 3})
     assert out == ("[('a', 0), ('A', 3), ('b', 1), ('c', 2)]|"
                    "[('a', 0), ('b', 1), ('c', 2), ('A', 3)]")
 
 
-def test_batch(env):
+def test_batch():
     tmpl = env.from_string(BATCH)
     out = tmpl.render(foo=range(10))
     assert out == ("[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]|"
                    "[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 'X', 'X']]")
 
 
-def test_slice(env):
+def test_slice():
     tmpl = env.from_string(SLICE)
     out = tmpl.render(foo=range(10))
     assert out == ("[[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]|"
                    "[[0, 1, 2, 3], [4, 5, 6, 'X'], [7, 8, 9, 'X']]")
 
 
-def test_escape(env):
+def test_escape():
     tmpl = env.from_string(ESCAPE)
     out = tmpl.render()
     assert out == '&lt;&#34;&gt;&amp;'
 
 
-def test_striptags(env):
+def test_striptags():
     tmpl = env.from_string(STRIPTAGS)
     out = tmpl.render(foo='  <p>just a small   \n <a href="#">'
                       'example</a> link</p>\n<p>to a webpage</p> '
     assert out == 'just a small example link to a webpage'
 
 
-def test_filesizeformat(env):
+def test_filesizeformat():
     tmpl = env.from_string(FILESIZEFORMAT)
     out = tmpl.render()
     assert out == (
     )
 
 
-def test_first(env):
+def test_first():
     tmpl = env.from_string(FIRST)
     out = tmpl.render(foo=range(10))
     assert out == '0'
 
 
-def test_float(env):
+def test_float():
     tmpl = env.from_string(FLOAT)
     out = tmpl.render()
     assert out == '42.0|0.0|32.32'
 
 
-def test_format(env):
+def test_format():
     tmpl = env.from_string(FORMAT)
     out = tmpl.render()
     assert out == 'a|b'
 
 
-def test_indent(env):
+def test_indent():
     tmpl = env.from_string(INDENT)
     text = '\n'.join([' '.join(['foo', 'bar'] * 2)] * 2)
     out = tmpl.render(foo=text)
                    'foo bar foo bar\n  foo bar foo bar')
 
 
-def test_int(env):
+def test_int():
     tmpl = env.from_string(INT)
     out = tmpl.render()
     assert out == '42|0|32'
 
 
-def test_join(env):
+def test_join():
     tmpl = env.from_string(JOIN)
     out = tmpl.render()
     assert out == '1|2|3'
     assert tmpl.render() == '&lt;foo&gt;<span>foo</span>'
 
 
-def test_last(env):
+def test_last():
     tmpl = env.from_string(LAST)
     out = tmpl.render(foo=range(10))
     assert out == '9'
 
 
-def test_length(env):
+def test_length():
     tmpl = env.from_string(LENGTH)
     out = tmpl.render()
     assert out == '11'
 
 
-def test_lower(env):
+def test_lower():
     tmpl = env.from_string(LOWER)
     out = tmpl.render()
     assert out == 'foo'
 
 
-def test_pprint(env):
+def test_pprint():
     from pprint import pformat
     tmpl = env.from_string(PPRINT)
     data = range(1000)
     assert tmpl.render(data=data) == pformat(data)
 
 
-def test_random(env):
+def test_random():
     tmpl = env.from_string(RANDOM)
     seq = range(100)
     for _ in range(10):
         assert int(tmpl.render(seq=seq)) in seq
 
 
-def test_reverse(env):
+def test_reverse():
     tmpl = env.from_string(REVERSE)
     assert tmpl.render() == 'raboof|[3, 2, 1]'
 
 
-def test_string(env):
+def test_string():
     tmpl = env.from_string(STRING)
     assert tmpl.render(foo=range(10)) == unicode(xrange(10))
 
 
-def test_title(env):
+def test_title():
     tmpl = env.from_string(TITLE)
     assert tmpl.render() == "Foo Bar"
 
 
-def test_truncate(env):
-    tmpl = env.from_string(TRUNCATE)
-    assert tmpl.render() == 'foo'
-
-
-def test_truncate(env):
+def test_truncate():
     tmpl = env.from_string(TRUNCATE)
     out = tmpl.render(data='foobar baz bar' * 1000,
                       smalldata='foobar baz bar')
     assert out == 'foobar baz barf>>>|foobar baz >>>|foobar baz bar'
 
 
-def test_upper(env):
+def test_upper():
     tmpl = env.from_string(UPPER)
     assert tmpl.render() == 'FOO'
 
 
-def test_urlize(env):
+def test_urlize():
     tmpl = env.from_string(URLIZE)
     assert tmpl.render() == 'foo <a href="http://www.example.com/">'\
                             'http://www.example.com/</a> bar'
 
 
-def test_wordcount(env):
+def test_wordcount():
     tmpl = env.from_string(WORDCOUNT)
     assert tmpl.render() == '3'
 
 
-def test_block(env):
+def test_block():
     tmpl = env.from_string(BLOCK)
     assert tmpl.render() == '&lt;hehe&gt;'
 
 
-def test_chaining(env):
+def test_chaining():
     tmpl = env.from_string(CHAINING)
     assert tmpl.render() == '&lt;FOO&gt;'
 
 
-def test_sum(env):
+def test_sum():
     tmpl = env.from_string(SUM)
     assert tmpl.render() == '21'
 
 
-def test_abs(env):
+def test_abs():
     tmpl = env.from_string(ABS)
     return tmpl.render() == '1|1'
 
 
-def test_round(env):
+def test_round():
     tmpl = env.from_string(ROUND)
     return tmpl.render() == '3.0|2.0|2.1|3.0'
 
 
-def test_xmlattr(env):
+def test_xmlattr():
     tmpl = env.from_string(XMLATTR)
     out = tmpl.render().split()
     assert len(out) == 3
     assert 'blub:blub="&lt;?&gt;"' in out
 
 
-def test_sort(env):
-    tmpl = env.from_string(SORT)
+def test_sort1():
+    tmpl = env.from_string(SORT1)
     assert tmpl.render() == '[1, 2, 3]|[3, 2, 1]'
 
 
-def test_groupby(env):
+def test_groupby():
     tmpl = env.from_string(GROUPBY)
     assert tmpl.render().splitlines() == [
         "1: {'foo': 1, 'bar': 2}, {'foo': 1, 'bar': 1}",
     ]
 
 
-def test_filtertag(env):
+def test_filtertag():
     tmpl = env.from_string(FILTERTAG)
     assert tmpl.render() == 'fooBAR'
 
     assert tmpl.render(string=Markup('foo')) == 'f&gt;x&lt;&gt;x&lt;'
 
 
-def test_forceescape(env):
+def test_forceescape():
     tmpl = env.from_string('{{ x|forceescape }}')
     assert tmpl.render(x=Markup('<div />')) == u'&lt;div /&gt;'
 
     assert tmpl.render() == '&lt;div&gt;foo&lt;/div&gt;'
 
 
-def test_sort(env):
-    assert env.from_string(SORT).render() == "['Bar', 'blah', 'foo']"
+def test_sort2():
+    assert env.from_string(SORT2).render() == "['Bar', 'blah', 'foo']"

tests/test_forloop.py

     :copyright: (c) 2009 by the Jinja Team.
     :license: BSD, see LICENSE for more details.
 """
-from py.test import raises
+from jinja2 import Environment
 from jinja2.exceptions import UndefinedError, TemplateSyntaxError
 from jinja2 import contextfilter, contextfunction
 
+from nose.tools import assert_raises
+
+env = Environment()
+
 
 SIMPLE = '''{% for item in seq %}{{ item }}{% endfor %}'''
 ELSE = '''{% for item in seq %}XXX{% else %}...{% endfor %}'''
 {% for loop in seq %}...{% endfor %}'''
 
 
-def test_simple(env):
+def test_simple():
     tmpl = env.from_string(SIMPLE)
     assert tmpl.render(seq=range(10)) == '0123456789'
 
 
-def test_else(env):
+def test_else():
     tmpl = env.from_string(ELSE)
     assert tmpl.render() == '...'
 
 
-def test_empty_blocks(env):
+def test_empty_blocks():
     tmpl = env.from_string(EMPTYBLOCKS)
     assert tmpl.render() == '<>'
 
 
-def test_context_vars(env):
+def test_context_vars():
     tmpl = env.from_string(CONTEXTVARS)
     one, two, _ = tmpl.render(seq=[0, 1]).split('###')
     (one_index, one_index0, one_revindex, one_revindex0, one_first,
     assert one_length == two_length == '2'
 
 
-def test_cycling(env):
+def test_cycling():
     tmpl = env.from_string(CYCLING)
     output = tmpl.render(seq=range(4), through=('<1>', '<2>'))
     assert output == '<1><2>' * 4
 
 
-def test_scope(env):
+def test_scope():
     tmpl = env.from_string(SCOPE)
     output = tmpl.render(seq=range(10))
     assert not output
 
 
-def test_varlen(env):
+def test_varlen():
     def inner():
         for item in range(5):
             yield item
     assert output == '01234'
 
 
-def test_noniter(env):
+def test_noniter():
     tmpl = env.from_string(NONITER)
-    raises(TypeError, tmpl.render)
+    assert_raises(TypeError, tmpl.render)
 
 
-def test_recursive(env):
+def test_recursive():
     tmpl = env.from_string(RECURSIVE)
     assert tmpl.render(seq=[
         dict(a=1, b=[dict(a=1), dict(a=2)]),
     ]) == '[1<[1][2]>][2<[1][2]>][3<[a]>]'
 
 
-def test_looploop(env):
+def test_looploop():
     tmpl = env.from_string(LOOPLOOP)
     assert tmpl.render(table=['ab', 'cd']) == '[1|1][1|2][2|1][2|2]'
 
 
-def test_reversed_bug(env):
+def test_reversed_bug():
     tmpl = env.from_string('{% for i in items %}{{ i }}{% if not loop.last %}'
                            ',{% endif %}{% endfor %}')
     assert tmpl.render(items=reversed([3, 2, 1])) == '1,2,3'
 
 
-def test_loop_errors(env):
+def test_loop_errors():
     tmpl = env.from_string(LOOPERROR1)
-    raises(UndefinedError, tmpl.render)
+    assert_raises(UndefinedError, tmpl.render)
     tmpl = env.from_string(LOOPERROR2)
     assert tmpl.render() == ''
 
 
-def test_loop_filter(env):
+def test_loop_filter():
     tmpl = env.from_string(LOOPFILTER)
     assert tmpl.render() == '[0][2][4][6][8]'
     tmpl = env.from_string(EXTENDEDLOOPFILTER)
     assert tmpl.render() == '[1:0][2:2][3:4][4:6][5:8]'
 
 
-def test_loop_unassignable(env):
-    raises(TemplateSyntaxError, env.from_string, LOOPUNASSIGNABLE)
+def test_loop_unassignable():
+    assert_raises(TemplateSyntaxError, env.from_string, LOOPUNASSIGNABLE)
 
 
-def test_scoped_special_var(env):
+def test_scoped_special_var():
     t = env.from_string('{% for s in seq %}[{{ loop.first }}{% for c in s %}'
                         '|{{ loop.first }}{% endfor %}]{% endfor %}')
     assert t.render(seq=('ab', 'cd')) == '[True|True|False][False|True|False]'
 
 
-def test_scoped_loop_var(env):
+def test_scoped_loop_var():
     t = env.from_string('{% for x in seq %}{{ loop.first }}'
                         '{% for y in seq %}{% endfor %}{% endfor %}')
     assert t.render(seq='ab') == 'TrueFalse'
     assert t.render(seq='ab') == 'TrueFalseTrueFalse'
 
 
-def test_recursive_empty_loop_iter(env):
+def test_recursive_empty_loop_iter():
     t = env.from_string('''
     {%- for item in foo recursive -%}{%- endfor -%}
     ''')
     assert t.render(dict(foo=[])) == ''
 
 
-def test_call_in_loop(env):
+def test_call_in_loop():
     t = env.from_string('''
     {%- macro do_something() -%}
         [{{ caller() }}]
     assert t.render() == '[1][2][3]'
 
 
-def test_scoping_bug(env):
+def test_scoping_bug():
     t = env.from_string('''
     {%- for item in foo %}...{{ item }}...{% endfor %}
     {%- macro item(a) %}...{{ a }}...{% endmacro %}

tests/test_heavy.py

     :copyright: Copyright 2009 by the Jinja Team.
     :license: BSD.
 """
+from jinja2 import Environment
+env = Environment()
 
 
-def test_assigned_scoping(env):
+def test_assigned_scoping():
     t = env.from_string('''
     {%- for item in (1, 2, 3, 4) -%}
         [{{ item }}]
     assert t.render() == '[1][2][3][4]42'
 
 
-def test_closure_scoping(env):
+def test_closure_scoping():
     t = env.from_string('''
     {%- set wrapper = "<FOO>" %}
     {%- for item in (1, 2, 3, 4) %}

tests/test_i18n.py

     :copyright: (c) 2009 by the Jinja Team.
     :license: BSD, see LICENSE for more details.
 """
-from py.test import raises
 from jinja2 import Environment, DictLoader, contextfunction
 from jinja2.exceptions import TemplateAssertionError
 
+from nose.tools import assert_raises
+
 templates = {
     'master.html': '<title>{{ page_title|default(_("missing")) }}</title>'
                    '{% block body %}{% endblock %}',
     tmpl = i18n_env.from_string('{% trans foo=42, count=2 %}{{ count }} item{% '
                                 'pluralize count %}{{ count }} items{% endtrans %}')
     assert tmpl.render() == '2 items'
-    raises(TemplateAssertionError, i18n_env.from_string,
-           '{% trans foo %}...{% pluralize bar %}...{% endtrans %}')
+    assert_raises(TemplateAssertionError, i18n_env.from_string,
+                 '{% trans foo %}...{% pluralize bar %}...{% endtrans %}')
 
 
 def test_trans_stringformatting():

tests/test_ifcondition.py

     :license: BSD, see LICENSE for more details.
 """
 
+from jinja2 import Environment
+env = Environment()
+
+
 SIMPLE = '''{% if true %}...{% endif %}'''
 ELIF = '''{% if false %}XXX{% elif true %}...{% else %}XXX{% endif %}'''
 ELSE = '''{% if false %}XXX{% else %}...{% endif %}'''
 EMPTY = '''[{% if true %}{% else %}{% endif %}]'''
 
 
-def test_simple(env):
+def test_simple():
     tmpl = env.from_string(SIMPLE)
     assert tmpl.render() == '...'
 
 
-def test_elif(env):
+def test_elif():
     tmpl = env.from_string(ELIF)
     assert tmpl.render() == '...'
 
 
-def test_else(env):
+def test_else():
     tmpl = env.from_string(ELSE)
     assert tmpl.render() == '...'
 
 
-def test_empty(env):
+def test_empty():
     tmpl = env.from_string(EMPTY)
     assert tmpl.render() == '[]'
 
 
-def test_complete(env):
+def test_complete():
     tmpl = env.from_string('{% if a %}A{% elif b %}B{% elif c == d %}'
                            'C{% else %}D{% endif %}')
     assert tmpl.render(a=0, b=False, c=42, d=42.0) == 'C'
 
 
-def test_no_scope(env):
+def test_no_scope():
     tmpl = env.from_string('{% if a %}{% set foo = 1 %}{% endif %}{{ foo }}')
     assert tmpl.render(a=True) == '1'
     tmpl = env.from_string('{% if true %}{% set foo = 1 %}{% endif %}{{ foo }}')

tests/test_imports.py

     :copyright: (c) 2009 by the Jinja Team.
     :license: BSD, see LICENSE for more details.
 """
-from py.test import raises
 from jinja2 import Environment, DictLoader
 from jinja2.exceptions import TemplateNotFound
 
+from nose.tools import assert_raises
+
 
 test_env = Environment(loader=DictLoader(dict(
     module='{% macro test() %}[{{ foo }}|{{ bar }}]{% endmacro %}',
 
 def test_include_ignoring_missing():
     t = test_env.from_string('{% include "missing" %}')
-    raises(TemplateNotFound, t.render)
+    assert_raises(TemplateNotFound, t.render)
     for extra in '', 'with context', 'without context':
         t = test_env.from_string('{% include "missing" ignore missing ' +
                                  extra + ' %}')

tests/test_inheritance.py

     :copyright: (c) 2009 by the Jinja Team.
     :license: BSD, see LICENSE for more details.
 """
+
 from jinja2 import Environment, DictLoader
 from jinja2.exceptions import TemplateSyntaxError
 
+
 LAYOUTTEMPLATE = '''\
 |{% block block1 %}block 1 from layout{% endblock %}
 |{% block block2 %}block 2 from layout{% endblock %}
 {% endblock %}
 '''
 
-def test_layout(env):
+env = Environment(loader=DictLoader({
+    'layout':       LAYOUTTEMPLATE,
+    'level1':       LEVEL1TEMPLATE,
+    'level2':       LEVEL2TEMPLATE,
+    'level3':       LEVEL3TEMPLATE,
+    'level4':       LEVEL4TEMPLATE,
+    'working':      WORKINGTEMPLATE
+}), trim_blocks=True)
+
+def test_layout():
     tmpl = env.get_template('layout')
     assert tmpl.render() == ('|block 1 from layout|block 2 from '
                              'layout|nested block 4 from layout|')
 
 
-def test_level1(env):
+def test_level1():
     tmpl = env.get_template('level1')
     assert tmpl.render() == ('|block 1 from level1|block 2 from '
                              'layout|nested block 4 from layout|')
 
 
-def test_level2(env):
+def test_level2():
     tmpl = env.get_template('level2')
     assert tmpl.render() == ('|block 1 from level1|nested block 5 from '
                              'level2|nested block 4 from layout|')
 
 
-def test_level3(env):
+def test_level3():
     tmpl = env.get_template('level3')
     assert tmpl.render() == ('|block 1 from level1|block 5 from level3|'
                              'block 4 from level3|')
 
 
-def test_level4(env):
+def test_level4():
     tmpl = env.get_template('level4')
     assert tmpl.render() == ('|block 1 from level1|block 5 from '
                              'level3|block 3 from level4|')
     assert tmpl.render() == '--INTRO--|BEFORE|[(INNER)]|AFTER'
 
 
-def test_working(env):
+def test_working():
     tmpl = env.get_template('working')
 
 
-def test_reuse_blocks(env):
+def test_reuse_blocks():
     tmpl = env.from_string('{{ self.foo() }}|{% block foo %}42{% endblock %}|{{ self.foo() }}')
     assert tmpl.render() == '42|42|42'
 

tests/test_lexer.py

     :copyright: (c) 2009 by the Jinja Team.
     :license: BSD, see LICENSE for more details.
 """
+from jinja2 import Environment
+
+env = Environment()
+
 
 RAW = '{% raw %}foo{% endraw %}|{%raw%}{{ bar }}|{% baz %}{%       endraw    %}'
 BALANCING = '''{% for item in seq %}${{'foo': item}|upper}{% endfor %}'''
 BYTEFALLBACK = u'''{{ 'foo'|pprint }}|{{ 'bär'|pprint }}'''
 
 
-def test_raw(env):
+def test_raw():
     tmpl = env.from_string(RAW)
     assert tmpl.render() == 'foo|{{ bar }}|{% baz %}'
 
                                          "<li>1</li>\n  <li>2</li>\n</ul>")
 
 
-def test_string_escapes(env):
+def test_string_escapes():
     for char in u'\0', u'\u2668', u'\xe4', u'\t', u'\r', u'\n':
         tmpl = env.from_string('{{ %s }}' % repr(char)[1:])
         assert tmpl.render() == char
     assert env.from_string('{{ "\N{HOT SPRINGS}" }}').render() == u'\u2668'
 
 
-def test_bytefallback(env):
+def test_bytefallback():
     tmpl = env.from_string(BYTEFALLBACK)
     assert tmpl.render() == u"'foo'|u'b\\xe4r'"
 
 
-def test_operators(env):
+def test_operators():
     from jinja2.lexer import operators
     for test, expect in operators.iteritems():
         if test in '([{}])':

tests/test_loaders.py

     :license: BSD, see LICENSE for more details.
 """
 
-from py.test import raises
 import time
 import tempfile
 from jinja2 import Environment, loaders
 from jinja2.loaders import split_template_path
 from jinja2.exceptions import TemplateNotFound
 
+from nose.tools import assert_raises
+
 
 dict_loader = loaders.DictLoader({
     'justdict.html':        'FOO'
     env = Environment(loader=dict_loader)
     tmpl = env.get_template('justdict.html')
     assert tmpl.render().strip() == 'FOO'
-    raises(TemplateNotFound, env.get_template, 'missing.html')
+    assert_raises(TemplateNotFound, env.get_template, 'missing.html')
 
 
 def test_package_loader():
     env = Environment(loader=package_loader)
     tmpl = env.get_template('test.html')
     assert tmpl.render().strip() == 'BAR'
-    raises(TemplateNotFound, env.get_template, 'missing.html')
+    assert_raises(TemplateNotFound, env.get_template, 'missing.html')
 
 
 def test_filesystem_loader():
     assert tmpl.render().strip() == 'BAR'
     tmpl = env.get_template('foo/test.html')
     assert tmpl.render().strip() == 'FOO'
-    raises(TemplateNotFound, env.get_template, 'missing.html')
+    assert_raises(TemplateNotFound, env.get_template, 'missing.html')
 
 
 def test_choice_loader():
     assert tmpl.render().strip() == 'FOO'
     tmpl = env.get_template('test.html')
     assert tmpl.render().strip() == 'BAR'
-    raises(TemplateNotFound, env.get_template, 'missing.html')
+    assert_raises(TemplateNotFound, env.get_template, 'missing.html')
 
 
 def test_function_loader():
     env = Environment(loader=function_loader)
     tmpl = env.get_template('justfunction.html')
     assert tmpl.render().strip() == 'FOO'
-    raises(TemplateNotFound, env.get_template, 'missing.html')
+    assert_raises(TemplateNotFound, env.get_template, 'missing.html')
 
 
 def test_prefix_loader():
     assert tmpl.render().strip() == 'BAR'
     tmpl = env.get_template('b/justdict.html')
     assert tmpl.render().strip() == 'FOO'
-    raises(TemplateNotFound, env.get_template, 'missing')
+    assert_raises(TemplateNotFound, env.get_template, 'missing')
 
 
 def test_caching():
 def test_split_template_path():
     assert split_template_path('foo/bar') == ['foo', 'bar']
     assert split_template_path('./foo/bar') == ['foo', 'bar']
-    raises(TemplateNotFound, split_template_path, '../foo')
+    assert_raises(TemplateNotFound, split_template_path, '../foo')

tests/test_macros.py

     :license: BSD, see LICENSE for more details.
 """
 
+from jinja2 import Environment, DictLoader
+
+env = Environment(trim_blocks=True)
+
+
 SIMPLE = '''\
 {% macro say_hello(name) %}Hello {{ name }}!{% endmacro %}
 {{ say_hello('Peter') }}\
 INCLUDETEMPLATE = '''{% macro test(foo) %}[{{ foo }}]{% endmacro %}'''
 
 
-def test_simple(env):
+def test_simple():
     tmpl = env.from_string(SIMPLE)
     assert tmpl.render() == 'Hello Peter!'
 
 
-def test_scoping(env):
+def test_scoping():
     tmpl = env.from_string(SCOPING)
     assert tmpl.render() == 'foo|bar'
 
 
-def test_arguments(env):
+def test_arguments():
     tmpl = env.from_string(ARGUMENTS)
     assert tmpl.render() == '||c|d|a||c|d|a|b|c|d|1|2|3|d'
 
 
-def test_varargs(env):
+def test_varargs():
     tmpl = env.from_string(VARARGS)
     assert tmpl.render() == '1|2|3'
 
 
-def test_simple_call(env):
+def test_simple_call():
     tmpl = env.from_string(SIMPLECALL)
     assert tmpl.render() == '[[data]]'
 
 
-def test_complex_call(env):
+def test_complex_call():
     tmpl = env.from_string(COMPLEXCALL)
     assert tmpl.render() == '[[data]]'
 
 
-def test_caller_undefined(env):
+def test_caller_undefined():
     tmpl = env.from_string(CALLERUNDEFINED)
     assert tmpl.render() == 'True'
 
 
-def test_include(env):
+def test_include():
+    env = Environment(loader=DictLoader({'include': INCLUDETEMPLATE}))
     tmpl = env.from_string('{% from "include" import test %}{{ test("foo") }}')
     assert tmpl.render() == '[foo]'
 
 
-def test_macro_api(env):
+def test_macro_api():
     tmpl = env.from_string('{% macro foo(a, b) %}{% endmacro %}'
                            '{% macro bar() %}{{ varargs }}{{ kwargs }}{% endmacro %}'
                            '{% macro baz() %}{{ caller() }}{% endmacro %}')

tests/test_meta.py

+# -*- coding: utf-8 -*-
+"""
+    unit test for the meta module
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    :copyright: (c) 2009 by the Jinja Team.
+    :license: BSD, see LICENSE for more details.
+"""
+from jinja2 import Environment, meta
+
+
+def test_find_undeclared_variables():
+    env = Environment()
+    ast = env.parse('{% set foo = 42 %}{{ bar + foo }}')
+    x = meta.find_undeclared_variables(ast)
+    assert x == set(['bar'])
+
+    ast = env.parse('{% set foo = 42 %}{{ bar + foo }}'
+                    '{% macro meh(x) %}{{ x }}{% endmacro %}'
+                    '{% for item in seq %}{{ muh(item) + meh(seq) }}{% endfor %}')
+    x = meta.find_undeclared_variables(ast)
+    assert x == set(['bar', 'seq', 'muh'])
+
+
+def test_find_refererenced_templates():
+    env = Environment()
+    ast = env.parse('{% extends "layout.html" %}{% include helper %}')
+    i = meta.find_referenced_templates(ast)
+    assert i.next() == 'layout.html'
+    assert i.next() is None
+    assert list(i) == []
+
+    ast = env.parse('{% extends "layout.html" %}'
+                    '{% from "test.html" import a, b as c %}'
+                    '{% import "meh.html" as meh %}'
+                    '{% include "muh.html" %}')
+    i = meta.find_referenced_templates(ast)
+    assert list(i) == ['layout.html', 'test.html', 'meh.html', 'muh.html']

tests/test_old_bugs.py

     :copyright: (c) 2009 by the Jinja Team.
     :license: BSD.
 """
-from py.test import raises
 from jinja2 import Environment, DictLoader, TemplateSyntaxError
 
+env = Environment()
+
+from nose.tools import assert_raises
+
 
 def test_keyword_folding():
     env = Environment()
     assert t.render(expr=True) == '((title))'
 
 
-def test_urlize_filter_escaping(env):
+def test_urlize_filter_escaping():
     tmpl = env.from_string('{{ "http://www.example.org/<foo"|urlize }}')
     assert tmpl.render() == '<a href="http://www.example.org/&lt;foo">http://www.example.org/&lt;foo</a>'
 
 
-def test_loop_call_loop(env):
+def test_loop_call_loop():
     tmpl = env.from_string('''
 
     {% macro test() %}
 
 def test_weird_inline_comment():
     env = Environment(line_statement_prefix='%')
-    raises(TemplateSyntaxError, env.from_string,
-           '% for item in seq {# missing #}\n...% endfor')
+    assert_raises(TemplateSyntaxError, env.from_string,
+                  '% for item in seq {# missing #}\n...% endfor')
 
 
-def test_old_macro_loop_scoping_bug(env):
+def test_old_macro_loop_scoping_bug():
     tmpl = env.from_string('{% for i in (1, 2) %}{{ i }}{% endfor %}'
                            '{% macro i() %}3{% endmacro %}{{ i() }}')
     assert tmpl.render() == '123'

tests/test_parser.py

 """
 from jinja2 import Environment
 
+env = Environment()
+
 
 PHP_SYNTAX = '''\
 <!-- I'm a comment, I'm not interesting -->\
     assert tmpl.render(seq=range(5)) == '01234'
 
 
-def test_balancing(env):
+def test_balancing():
     tmpl = env.from_string(BALANCING)
     assert tmpl.render() == 'bar'
 
 
-def test_start_comment(env):
+def test_start_comment():
     tmpl = env.from_string(STARTCOMMENT)
     assert tmpl.render().strip() == 'foo'
 
     env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%')
     tmpl = env.from_string(MAKO_SYNTAX)
     assert [int(x.strip()) for x in tmpl.render(seq=range(5)).split()] == \
-            range(5)
+           range(5)
 
     env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##')
     tmpl = env.from_string(MAKO_SYNTAX_LINECOMMENTS)

tests/test_security.py

     :copyright: (c) 2009 by the Jinja Team.
     :license: BSD, see LICENSE for more details.
 """
-from py.test import raises
 from jinja2 import Environment
 from jinja2.sandbox import SandboxedEnvironment, \
      ImmutableSandboxedEnvironment, unsafe
 from jinja2.exceptions import SecurityError, TemplateSyntaxError
 
 
+from nose.tools import assert_raises
+
 class PrivateStuff(object):
 
     def bar(self):
         return 'PublicStuff'
 
 
-test_unsafe = '''
->>> env = MODULE.SandboxedEnvironment()
->>> env.from_string("{{ foo.foo() }}").render(foo=MODULE.PrivateStuff())
+def test_unsafe():
+    '''
+>>> env = SandboxedEnvironment()
+>>> env.from_string("{{ foo.foo() }}").render(foo=PrivateStuff())
 Traceback (most recent call last):
     ...
 SecurityError: <bound method PrivateStuff.foo of PrivateStuff> is not safely callable
->>> env.from_string("{{ foo.bar() }}").render(foo=MODULE.PrivateStuff())
+>>> env.from_string("{{ foo.bar() }}").render(foo=PrivateStuff())
 u'23'
 
->>> env.from_string("{{ foo._foo() }}").render(foo=MODULE.PublicStuff())
+>>> env.from_string("{{ foo._foo() }}").render(foo=PublicStuff())
 Traceback (most recent call last):
     ...
 SecurityError: access to attribute '_foo' of 'PublicStuff' object is unsafe.
->>> env.from_string("{{ foo.bar() }}").render(foo=MODULE.PublicStuff())
+>>> env.from_string("{{ foo.bar() }}").render(foo=PublicStuff())
 u'23'
 
 >>> env.from_string("{{ foo.__class__ }}").render(foo=42)
 
 def test_restricted():
     env = SandboxedEnvironment()
-    raises(TemplateSyntaxError, env.from_string,
-           "{% for item.attribute in seq %}...{% endfor %}")
-    raises(TemplateSyntaxError, env.from_string,
-           "{% for foo, bar.baz in seq %}...{% endfor %}")
+    assert_raises(TemplateSyntaxError, env.from_string,
+                  "{% for item.attribute in seq %}...{% endfor %}")
+    assert_raises(TemplateSyntaxError, env.from_string,
+                  "{% for foo, bar.baz in seq %}...{% endfor %}")
 
 
-test_immutable_environment = '''
->>> env = MODULE.ImmutableSandboxedEnvironment()
+def test_immutable_environment():
+    '''
+>>> env = ImmutableSandboxedEnvironment()
 >>> env.from_string('{{ [].append(23) }}').render()
 Traceback (most recent call last):
     ...
 def test_attr_filter():
     env = SandboxedEnvironment()
     tmpl = env.from_string('{{ 42|attr("__class__")|attr("__subclasses__")() }}')
-    raises(SecurityError, tmpl.render)
+    assert_raises(SecurityError, tmpl.render)

tests/test_streaming.py

     :license: BSD, see LICENSE for more details.
 """
 
+from jinja2 import Environment
+env = Environment()
 
-test_basic_streaming = r"""
+
+def test_basic_streaming():
+    r"""
 >>> tmpl = env.from_string("<ul>{% for item in seq %}<li>{{ loop.index "
 ...                        "}} - {{ item }}</li>{%- endfor %}</ul>")
 >>> stream = tmpl.stream(seq=range(4))
 u'</ul>'
 """
 
-test_buffered_streaming = r"""
+def test_buffered_streaming():
+    r"""
 >>> tmpl = env.from_string("<ul>{% for item in seq %}<li>{{ loop.index "
 ...                        "}} - {{ item }}</li>{%- endfor %}</ul>")
 >>> stream = tmpl.stream(seq=range(4))
 u'<li>3 - 2</li><li>4 - 3</li></ul>'
 """
 
-test_streaming_behavior = r"""
+def test_streaming_behavior():
+    r"""
 >>> tmpl = env.from_string("")
 >>> stream = tmpl.stream()
 >>> stream.buffered

tests/test_syntax.py

     :copyright: (c) 2009 by the Jinja Team.
     :license: BSD, see LICENSE for more details.
 """
-from py.test import raises
-from jinja2 import Environment, DictLoader
+from jinja2 import Environment
 from jinja2.exceptions import TemplateSyntaxError, UndefinedError
 
+from nose.tools import assert_raises
+
+env = Environment()
+
 
 CALL = '''{{ foo('a', c='d', e='f', *['b'], **{'g': 'h'}) }}'''
 SLICING = '''{{ [1, 2, 3][:] }}|{{ [1, 2, 3][::-1] }}'''
 
 
 def test_call():
-    from jinja2 import Environment
     env = Environment()
     env.globals['foo'] = lambda a, b, c, e, g: a + b + c + e + g
     tmpl = env.from_string(CALL)
     assert tmpl.render() == 'abdfh'
 
 
-def test_slicing(env):
+def test_slicing():
     tmpl = env.from_string(SLICING)
     assert tmpl.render() == '[1, 2, 3]|[3, 2, 1]'
 
 
-def test_attr(env):
+def test_attr():
     tmpl = env.from_string(ATTR)
     assert tmpl.render(foo={'bar': 42}) == '42|42'
 
 
-def test_subscript(env):
+def test_subscript():
     tmpl = env.from_string(SUBSCRIPT)
     assert tmpl.render(foo=[0, 1, 2]) == '0|2'
 
 
-def test_tuple(env):
+def test_tuple():
     tmpl = env.from_string(TUPLE)
     assert tmpl.render() == '()|(1,)|(1, 2)'
 
 
-def test_math(env):
+def test_math():
     tmpl = env.from_string(MATH)
     assert tmpl.render() == '1.5|8'
 
 
-def test_div(env):
+def test_div():
     tmpl = env.from_string(DIV)
     assert tmpl.render() == '1|1.5|1'
 
 
-def test_unary(env):
+def test_unary():
     tmpl = env.from_string(UNARY)
     assert tmpl.render() == '3|-3'
 
 
-def test_concat(env):
+def test_concat():
     tmpl = env.from_string(CONCAT)
     assert tmpl.render() == '[1, 2]foo'
 
 
-def test_compare(env):
+def test_compare():
     tmpl = env.from_string(COMPARE)
     assert tmpl.render() == 'True|True|True|True|True'
 
 
-def test_inop(env):
+def test_inop():
     tmpl = env.from_string(INOP)
     assert tmpl.render() == 'True|False'
 
 
-def test_literals(env):
+def test_literals():
     tmpl = env.from_string(LITERALS)
     assert tmpl.render().lower() == '[]|{}|()'
 
 
-def test_bool(env):
+def test_bool():
     tmpl = env.from_string(BOOL)
     assert tmpl.render() == 'False|True|True'
 
 
-def test_grouping(env):
+def test_grouping():
     tmpl = env.from_string(GROUPING)
     assert tmpl.render() == 'False'
 
 
-def test_django_attr(env):
+def test_django_attr():
     tmpl = env.from_string(DJANGOATTR)
     assert tmpl.render() == '1|1'
 
 
-def test_conditional_expression(env):
+def test_conditional_expression():
     tmpl = env.from_string(CONDEXPR)
     assert tmpl.render() == '0'
 
 
-def test_short_conditional_expression(env):
+def test_short_conditional_expression():
     tmpl = env.from_string('<{{ 1 if false }}>')
     assert tmpl.render() == '<>'
 
     tmpl = env.from_string('<{{ (1 if false).bar }}>')
-    raises(UndefinedError, tmpl.render)
+    assert_raises(UndefinedError, tmpl.render)
 
 
-def test_filter_priority(env):
+def test_filter_priority():
     tmpl = env.from_string(FILTERPRIORITY)
     assert tmpl.render() == 'FOOBAR'
 
 
-def test_function_calls(env):
+def test_function_calls():
     tests = [
         (True, '*foo, bar'),
         (True, '*foo, *bar'),
     ]
     for should_fail, sig in tests:
         if should_fail:
-            raises(TemplateSyntaxError, env.from_string, '{{ foo(%s) }}' % sig)
+            assert_raises(TemplateSyntaxError, env.from_string, '{{ foo(%s) }}' % sig)
         else:
             env.from_string('foo(%s)' % sig)
 
 
-def test_tuple_expr(env):
+def test_tuple_expr():
     for tmpl in TUPLETEMPLATES:
         print tmpl
         assert env.from_string(tmpl)
 
 
-def test_trailing_comma(env):
+def test_trailing_comma():
     tmpl = env.from_string(TRAILINGCOMMA)
     assert tmpl.render().lower() == '(1, 2)|[1, 2]|{1: 2}'
 
 
-def test_block_end_name(env):
+def test_block_end_name():
     env.from_string('{% block foo %}...{% endblock foo %}')
-    raises(TemplateSyntaxError, env.from_string, '{% block x %}{% endblock y %}')
+    assert_raises(TemplateSyntaxError, env.from_string, '{% block x %}{% endblock y %}')
 
 
-def test_contant_casing(env):
+def test_contant_casing():
     for const in True, False, None:
         tmpl = env.from_string('{{ %s }}|{{ %s }}|{{ %s }}' % (
             str(const), str(const).lower(), str(const).upper()
         assert tmpl.render() == '%s|%s|' % (const, const)
 
 
-def test_test_chaining(env):
-    raises(TemplateSyntaxError, env.from_string, '{{ foo is string is sequence }}')
+def test_test_chaining():
+    assert_raises(TemplateSyntaxError, env.from_string, '{{ foo is string is sequence }}')
     env.from_string('{{ 42 is string or 42 is number }}').render() == 'True'
 
 
-def test_string_concatenation(env):
+def test_string_concatenation():
     tmpl = env.from_string('{{ "foo" "bar" "baz" }}')
     assert tmpl.render() == 'foobarbaz'
 
 
-def test_notin(env):
+def test_notin():
     bar = xrange(100)
     tmpl = env.from_string('''{{ not 42 in bar }}''')
     assert tmpl.render(bar=bar) == unicode(not 42 in bar)
 
 
-def test_implicit_subscribed_tuple(env):
+def test_implicit_subscribed_tuple():
     class Foo(object):
         def __getitem__(self, x):
             return x

tests/test_tests.py

     :license: BSD, see LICENSE for more details.
 """
 from jinja2 import Environment, Markup
+env = Environment()
 
 
 DEFINED = '''{{ missing is defined }}|{{ true is defined }}'''
 {{ range(5) is iterable }}'''
 
 
-def test_defined(env):
+def test_defined():
     tmpl = env.from_string(DEFINED)
     assert tmpl.render() == 'False|True'
 
 
-def test_even(env):
+def test_even():
     tmpl = env.from_string(EVEN)
     assert tmpl.render() == 'False|True'
 
 
-def test_odd(env):
+def test_odd():
     tmpl = env.from_string(ODD)
     assert tmpl.render() == 'True|False'
 
 
-def test_lower(env):
+def test_lower():
     tmpl = env.from_string(LOWER)
     assert tmpl.render() == 'True|False'
 
 
-def test_typechecks(env):
+def test_typechecks():
     tmpl = env.from_string(TYPECHECKS)
     assert tmpl.render() == ''
 
 
-def test_sequence(env):
+def test_sequence():
     tmpl = env.from_string(SEQUENCE)
     assert tmpl.render() == 'True|True|False'
 
 
-def test_upper(env):
+def test_upper():
     tmpl = env.from_string(UPPER)
     assert tmpl.render() == 'True|False'
 
 
-def test_sameas(env):
+def test_sameas():
     tmpl = env.from_string(SAMEAS)
     assert tmpl.render(foo=False) == 'True|False'
 
 
-def test_typechecks(env):
+def test_typechecks():
     tmpl = env.from_string(TYPECHECKS)
     assert tmpl.render() == (
         'False\nTrue\nFalse\nTrue\nTrue\nFalse\n'
     )
 
 
-def test_no_paren_for_arg1(env):
+def test_no_paren_for_arg1():
     tmpl = env.from_string(NOPARENFORARG1)
     assert tmpl.render(foo=None) == 'True'
 

tests/test_undefined.py

     :copyright: (c) 2009 by the Jinja Team.
     :license: BSD, see LICENSE for more details.
 """
-from py.test import raises
 from jinja2 import Template
 from jinja2.exceptions import UndefinedError
 
+from nose.tools import assert_raises
 
-test_default_undefined = '''
+
+def test_default_undefined():
+    '''
 >>> from jinja2 import Environment, Undefined
 >>> env = Environment(undefined=Undefined)
 >>> env.from_string('{{ missing }}').render()
 u'True'
 '''
 
-test_debug_undefined = '''
+def test_debug_undefined():
+    '''
 >>> from jinja2 import Environment, DebugUndefined
 >>> env = Environment(undefined=DebugUndefined)
 >>> env.from_string('{{ missing }}').render()
 u'True'
 '''
 
-test_strict_undefined = '''
+def test_strict_undefined():
+    '''
 >>> from jinja2 import Environment, StrictUndefined
 >>> env = Environment(undefined=StrictUndefined)
 >>> env.from_string('{{ missing }}').render()
 
 def test_indexing_gives_undefined():
     t = Template("{{ var[42].foo }}")
-    raises(UndefinedError, t.render, var=0)
+    assert_raises(UndefinedError, t.render, var=0)

tests/test_various.py

     :license: BSD, see LICENSE for more details.
 """
 import gc
-from py.test import raises
-from jinja2 import escape, is_undefined
+from jinja2 import escape, is_undefined, Environment
 from jinja2.utils import Cycler
 from jinja2.exceptions import TemplateSyntaxError
 
+from nose.tools import assert_raises
+
+env = Environment()
+
 
 UNPACKING = '''{% for a, b, c in [[1, 2, 3]] %}{{ a }}|{{ b }}|{{ c }}{% endfor %}'''
 RAW = '''{% raw %}{{ FOO }} and {% BAR %}{% endraw %}'''
 CONSTASS2 = '''{% for none in seq %}{% endfor %}'''
 
 
-def test_unpacking(env):
+def test_unpacking():
     tmpl = env.from_string(UNPACKING)
     assert tmpl.render() == '1|2|3'
 
 
-def test_raw(env):
+def test_raw():
     tmpl = env.from_string(RAW)
     assert tmpl.render() == '{{ FOO }} and {% BAR %}'
 
 
-def test_const(env):
+def test_const():
     tmpl = env.from_string(CONST)
     assert tmpl.render() == 'True|False|None|True|False'
 
 
-def test_const_assign(env):
+def test_const_assign():
     for tmpl in CONSTASS1, CONSTASS2:
-        raises(TemplateSyntaxError, env.from_string, tmpl)
+        assert_raises(TemplateSyntaxError, env.from_string, tmpl)
 
 
-def test_localset(env):
+def test_localset():
     tmpl = env.from_string(LOCALSET)
     assert tmpl.render() == '0'
 
 
 
 def test_item_and_attribute():
-    from jinja2 import Environment
     from jinja2.sandbox import SandboxedEnvironment
 
     for env in Environment(), SandboxedEnvironment():
 
 
 def test_finalizer():
-    from jinja2 import Environment
     def finalize_none_empty(value):
         if value is None:
             value = u''
     assert c.current == 1
 
 
-def test_expressions(env):
+def test_expressions():
     expr = env.compile_expression("foo")
     assert expr() is None
     assert expr(foo=42) == 42
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.