- Fix a bug causing deadlocks in ``LRUCache.setdefault``. :pr:`1000`
- The ``trim`` filter takes an optional string of characters to trim.
:pr:`828`
-- A new ``jinja.ext.debug`` extension adds a ``{% debug %}`` tag to
+- A new ``jinja2.ext.debug`` extension adds a ``{% debug %}`` tag to
quickly dump the current context and available filters and tests.
:issue:`174`, :pr:`798, 983`
- Lexing templates with large amounts of whitespace is much faster.
arguments. This change makes ``{% macro m(x, y=1, z) %}`` a syntax
error. The previous behavior for this code was broken anyway
(resulting in the default value being applied to ``y``).
-- Add ability to use custom subclasses of ``CodeGenerator`` and
- ``Context`` by adding two new attributes to the environment
- (``code_generator_class`` and ``context_class``). :pr:`404`
+- Add ability to use custom subclasses of
+ ``jinja2.compiler.CodeGenerator`` and ``jinja2.runtime.Context`` by
+ adding two new attributes to the environment
+ (``code_generator_class`` and ``context_class``) (pull request
+ ``:issue:`404```).
- Added support for context/environment/evalctx decorator functions on
the finalize callback of the environment.
- Escape query strings for urlencode properly. Previously slashes were
- Fixed a bug for getattribute constant folding.
- Support for newstyle gettext translations which result in a nicer
in-template user interface and more consistent catalogs.
+ (:ref:`newstyle-gettext`)
- It's now possible to register extensions after an environment was
created.
folder.
- The _speedups C extension now supports Python 3.
- Added support for autoescaping toggling sections and support for
- evaluation contexts.
+ evaluation contexts (:ref:`eval-context`).
- Extensions have a priority now.
- Added ``sort`` filter that works like ``dictsort`` but for arbitrary
sequences.
- Fixed a bug with empty statements in macros.
-- Implemented a bytecode cache system.
+- Implemented a bytecode cache system. (:ref:`bytecode-cache`)
- The template context is now weakref-able
- Inclusions and imports "with context" forward all variables now, not
only the initial context.
from slightly. It's now possible to give attributes or items a
higher priority by either using dot-notation lookup or the bracket
syntax. This also changed the AST slightly. ``Subscript`` is gone
- and was replaced with ``Getitem`` and ``Getattr``.
+ and was replaced with :class:`~jinja2.nodes.Getitem` and
+ :class:`~jinja2.nodes.Getattr`. For more information see :ref:`the
+ implementation details <notes-on-subscriptions>`.
- Added support for preprocessing and token stream filtering for
extensions. This would allow extensions to allow simplified gettext
calls in template data and something similar.
-- Added ``TemplateStream.dump``.
+- Added :meth:`jinja2.environment.TemplateStream.dump`.
- Added missing support for implicit string literal concatenation.
``{{ "foo" "bar" }}`` is equivalent to ``{{ "foobar" }}``
- ``else`` is optional for conditional expressions. If not given it
.. code-block:: text
- $ pip install -U Jinja
+ $ pip install -U Jinja2
.. _pip: https://pip.pypa.io/en/stable/quickstart/
- Website: https://palletsprojects.com/p/jinja/
- Documentation: https://jinja.palletsprojects.com/
-- Releases: https://pypi.org/project/Jinja/
+- Releases: https://pypi.org/project/Jinja2/
- Code: https://github.com/pallets/jinja
- Issue tracker: https://github.com/pallets/jinja/issues
- Test status: https://dev.azure.com/pallets/jinja/_build
API
===
-.. module:: jinja
+.. module:: jinja2
:noindex:
:synopsis: public Jinja API
The simplest way to configure Jinja to load templates for your application
looks roughly like this::
- from jinja import Environment, PackageLoader, select_autoescape
+ from jinja2 import Environment, PackageLoader, select_autoescape
env = Environment(
loader=PackageLoader('yourapplication', 'templates'),
autoescape=select_autoescape(['html', 'xml'])
If the environment is sandboxed this attribute is `True`. For the
sandbox mode have a look at the documentation for the
- :class:`~jinja.sandbox.SandboxedEnvironment`.
+ :class:`~jinja2.sandbox.SandboxedEnvironment`.
.. attribute:: filters
The context used for templates. This should not be changed
in most cases, unless you need to modify internals of how
template variables are handled. For details, see
- :class:`~jinja.runtime.Context`.
+ :class:`~jinja2.runtime.Context`.
.. automethod:: overlay([options])
.. automethod:: generate_async([context])
-.. autoclass:: jinja.environment.TemplateStream()
+.. autoclass:: jinja2.environment.TemplateStream()
:members: disable_buffering, enable_buffering, dump
autoescaping. This makes it possible to enable and disable autoescaping
on a per-template basis (HTML versus text for instance).
-.. autofunction:: jinja.select_autoescape
+.. autofunction:: jinja2.select_autoescape
Here a recommended setup that enables autoescaping for templates ending
in ``'.html'``, ``'.htm'`` and ``'.xml'`` and disabling it by default
-for all other extensions. You can use the :func:`~jinja.select_autoescape`
+for all other extensions. You can use the :func:`~jinja2.select_autoescape`
function for this::
- from jinja import Environment, select_autoescape
+ from jinja2 import Environment, select_autoescape
env = Environment(autoescape=select_autoescape(['html', 'htm', 'xml']),
loader=PackageLoader('mypackage'))
The closest to regular Python behavior is the :class:`StrictUndefined` which
disallows all operations beside testing if it's an undefined object.
-.. autoclass:: jinja.Undefined()
+.. autoclass:: jinja2.Undefined()
.. attribute:: _undefined_hint
:attr:`_undefined_exception` with an error message generated
from the undefined hints stored on the undefined object.
-.. autoclass:: jinja.ChainableUndefined()
+.. autoclass:: jinja2.ChainableUndefined()
-.. autoclass:: jinja.DebugUndefined()
+.. autoclass:: jinja2.DebugUndefined()
-.. autoclass:: jinja.StrictUndefined()
+.. autoclass:: jinja2.StrictUndefined()
There is also a factory function that can decorate undefined objects to
implement logging on failures:
-.. autofunction:: jinja.make_logging_undefined
+.. autofunction:: jinja2.make_logging_undefined
Undefined objects are created by calling :attr:`undefined`.
The Context
-----------
-.. autoclass:: jinja.runtime.Context()
+.. autoclass:: jinja2.runtime.Context()
:members: resolve, get_exported, get_all
.. attribute:: parent
The current :ref:`eval-context`.
- .. automethod:: jinja.runtime.Context.call(callable, \*args, \**kwargs)
+ .. automethod:: jinja2.runtime.Context.call(callable, \*args, \**kwargs)
.. admonition:: Implementation
All loaders are subclasses of :class:`BaseLoader`. If you want to create your
own loader, subclass :class:`BaseLoader` and override `get_source`.
-.. autoclass:: jinja.BaseLoader
+.. autoclass:: jinja2.BaseLoader
:members: get_source, load
Here a list of the builtin loaders Jinja provides:
-.. autoclass:: jinja.FileSystemLoader
+.. autoclass:: jinja2.FileSystemLoader
-.. autoclass:: jinja.PackageLoader
+.. autoclass:: jinja2.PackageLoader
-.. autoclass:: jinja.DictLoader
+.. autoclass:: jinja2.DictLoader
-.. autoclass:: jinja.FunctionLoader
+.. autoclass:: jinja2.FunctionLoader
-.. autoclass:: jinja.PrefixLoader
+.. autoclass:: jinja2.PrefixLoader
-.. autoclass:: jinja.ChoiceLoader
+.. autoclass:: jinja2.ChoiceLoader
-.. autoclass:: jinja.ModuleLoader
+.. autoclass:: jinja2.ModuleLoader
.. _bytecode-cache:
To use a bytecode cache, instantiate it and pass it to the :class:`Environment`.
-.. autoclass:: jinja.BytecodeCache
+.. autoclass:: jinja2.BytecodeCache
:members: load_bytecode, dump_bytecode, clear
-.. autoclass:: jinja.bccache.Bucket
+.. autoclass:: jinja2.bccache.Bucket
:members: write_bytecode, load_bytecode, bytecode_from_string,
bytecode_to_string, reset
Builtin bytecode caches:
-.. autoclass:: jinja.FileSystemBytecodeCache
+.. autoclass:: jinja2.FileSystemBytecodeCache
-.. autoclass:: jinja.MemcachedBytecodeCache
+.. autoclass:: jinja2.MemcachedBytecodeCache
Async Support
Starting with Jinja 2.9 policies can be configured on the environment
which can slightly influence how filters and other template constructs
behave. They can be configured with the
-:attr:`~jinja.Environment.policies` attribute.
+:attr:`~jinja2.Environment.policies` attribute.
Example::
These helper functions and classes are useful if you add custom filters or
functions to a Jinja environment.
-.. autofunction:: jinja.environmentfilter
+.. autofunction:: jinja2.environmentfilter
-.. autofunction:: jinja.contextfilter
+.. autofunction:: jinja2.contextfilter
-.. autofunction:: jinja.evalcontextfilter
+.. autofunction:: jinja2.evalcontextfilter
-.. autofunction:: jinja.environmentfunction
+.. autofunction:: jinja2.environmentfunction
-.. autofunction:: jinja.contextfunction
+.. autofunction:: jinja2.contextfunction
-.. autofunction:: jinja.evalcontextfunction
+.. autofunction:: jinja2.evalcontextfunction
.. function:: escape(s)
The return value is a :class:`Markup` string.
-.. autofunction:: jinja.clear_caches
+.. autofunction:: jinja2.clear_caches
-.. autofunction:: jinja.is_undefined
+.. autofunction:: jinja2.is_undefined
-.. autoclass:: jinja.Markup([string])
+.. autoclass:: jinja2.Markup([string])
:members: escape, unescape, striptags
.. admonition:: Note
Exceptions
----------
-.. autoexception:: jinja.TemplateError
+.. autoexception:: jinja2.TemplateError
-.. autoexception:: jinja.UndefinedError
+.. autoexception:: jinja2.UndefinedError
-.. autoexception:: jinja.TemplateNotFound
+.. autoexception:: jinja2.TemplateNotFound
-.. autoexception:: jinja.TemplatesNotFound
+.. autoexception:: jinja2.TemplatesNotFound
-.. autoexception:: jinja.TemplateSyntaxError
+.. autoexception:: jinja2.TemplateSyntaxError
.. attribute:: message
unicode strings is that Python 2.x is not using unicode for exceptions
and tracebacks as well as the compiler. This will change with Python 3.
-.. autoexception:: jinja.TemplateRuntimeError
+.. autoexception:: jinja2.TemplateRuntimeError
-.. autoexception:: jinja.TemplateAssertionError
+.. autoexception:: jinja2.TemplateAssertionError
.. _writing-filters:
enabled::
import re
- from jinja import evalcontextfilter, Markup, escape
+ from jinja2 import evalcontextfilter, Markup, escape
_paragraph_re = re.compile(r'(?:\r\n|\r(?!\n)|\n){2,}')
:class:`nodes.ScopedEvalContextModifier` from an extension, not on the
eval context object itself.
-.. autoclass:: jinja.nodes.EvalContext
+.. autoclass:: jinja2.nodes.EvalContext
.. attribute:: autoescape
the functions of the meta API operate on an abstract syntax tree as
returned by the :meth:`Environment.parse` method.
-.. autofunction:: jinja.meta.find_undeclared_variables
+.. autofunction:: jinja2.meta.find_undeclared_variables
-.. autofunction:: jinja.meta.find_referenced_templates
+.. autofunction:: jinja2.meta.find_referenced_templates
project = "Jinja"
copyright = "2007 Pallets"
author = "Pallets"
-release, version = get_version("Jinja")
+release, version = get_version("Jinja2")
# General --------------------------------------------------------------
"project_links": [
ProjectLink("Donate to Pallets", "https://palletsprojects.com/donate"),
ProjectLink("Jinja Website", "https://palletsprojects.com/p/jinja/"),
- ProjectLink("PyPI releases", "https://pypi.org/project/Jinja/"),
+ ProjectLink("PyPI releases", "https://pypi.org/project/Jinja2/"),
ProjectLink("Source Code", "https://github.com/pallets/jinja/"),
ProjectLink("Issue Tracker", "https://github.com/pallets/jinja/issues/"),
]
-from jinja import nodes
-from jinja.ext import Extension
+from jinja2 import nodes
+from jinja2.ext import Extension
class FragmentCacheExtension(Extension):
# -*- coding: utf-8 -*-
import re
-from jinja.exceptions import TemplateSyntaxError
-from jinja.ext import Extension
-from jinja.lexer import count_newlines
-from jinja.lexer import Token
+from jinja2.exceptions import TemplateSyntaxError
+from jinja2.ext import Extension
+from jinja2.lexer import count_newlines
+from jinja2.lexer import Token
_outside_re = re.compile(r"\\?(gettext|_)\(")
Extensions are added to the Jinja environment at creation time. Once the
environment is created additional extensions cannot be added. To add an
extension pass a list of extension classes or import paths to the
-``extensions`` parameter of the :class:`~jinja.Environment` constructor. The following
+``extensions`` parameter of the :class:`~jinja2.Environment` constructor. The following
example creates a Jinja environment with the i18n extension loaded::
- jinja_env = Environment(extensions=['jinja.ext.i18n'])
+ jinja_env = Environment(extensions=['jinja2.ext.i18n'])
.. _i18n-extension:
i18n Extension
--------------
-**Import name:** ``jinja.ext.i18n``
+**Import name:** ``jinja2.ext.i18n``
The i18n extension can be used in combination with `gettext`_ or
`Babel`_. When it's enabled, Jinja provides a ``trans`` statement that
After enabling the extension, the environment provides the following
additional methods:
-.. method:: jinja.Environment.install_gettext_translations(translations, newstyle=False)
+.. method:: jinja2.Environment.install_gettext_translations(translations, newstyle=False)
Installs a translation globally for the environment. The
``translations`` object must implement ``gettext`` and ``ngettext``
.. versionchanged:: 2.5 Added new-style gettext support.
-.. method:: jinja.Environment.install_null_translations(newstyle=False)
+.. method:: jinja2.Environment.install_null_translations(newstyle=False)
Install no-op gettext functions. This is useful if you want to
prepare the application for internationalization but don't want to
.. versionchanged:: 2.5 Added new-style gettext support.
-.. method:: jinja.Environment.install_gettext_callables(gettext, ngettext, newstyle=False)
+.. method:: jinja2.Environment.install_gettext_callables(gettext, ngettext, newstyle=False)
Install the given ``gettext`` and ``ngettext`` callables into the
environment. They should behave exactly like
.. versionadded:: 2.5 Added new-style gettext support.
-.. method:: jinja.Environment.uninstall_gettext_translations()
+.. method:: jinja2.Environment.uninstall_gettext_translations()
Uninstall the environment's globally installed translation.
-.. method:: jinja.Environment.extract_translations(source)
+.. method:: jinja2.Environment.extract_translations(source)
Extract localizable strings from the given template node or source.
.. code-block:: python
translations = get_gettext_translations()
- env = Environment(extensions=["jinja.ext.i18n"])
+ env = Environment(extensions=["jinja2.ext.i18n"])
env.install_gettext_translations(translations)
The ``get_gettext_translations`` function would return the translator
Expression Statement
--------------------
-**Import name:** ``jinja.ext.do``
+**Import name:** ``jinja2.ext.do``
The "do" aka expression-statement extension adds a simple ``do`` tag to the
template engine that works like a variable expression but ignores the
Loop Controls
-------------
-**Import name:** ``jinja.ext.loopcontrols``
+**Import name:** ``jinja2.ext.loopcontrols``
This extension adds support for ``break`` and ``continue`` in loops. After
enabling, Jinja provides those two keywords which work exactly like in
With Statement
--------------
-**Import name:** ``jinja.ext.with_``
+**Import name:** ``jinja2.ext.with_``
.. versionchanged:: 2.9
Autoescape Extension
--------------------
-**Import name:** ``jinja.ext.autoescape``
+**Import name:** ``jinja2.ext.autoescape``
.. versionchanged:: 2.9
Debug Extension
---------------
-**Import name:** ``jinja.ext.debug``
+**Import name:** ``jinja2.ext.debug``
Adds a ``{% debug %}`` tag to dump the current context as well as the
available filters and tests. This is useful to see what's available to
Writing Extensions
------------------
-.. module:: jinja.ext
+.. module:: jinja2.ext
By writing extensions you can add custom tags to Jinja. This is a non-trivial
task and usually not needed as the default tags and expressions cover all
And here is how you use it in an environment::
- from jinja import Environment
+ from jinja2 import Environment
from cachelib import SimpleCache
env = Environment(extensions=[FragmentCacheExtension])
Extension
~~~~~~~~~
-Extensions always have to extend the :class:`jinja.ext.Extension` class:
+Extensions always have to extend the :class:`jinja2.ext.Extension` class:
.. autoclass:: Extension
:members: preprocess, filter_stream, parse, attr, call_method
expressions of different types. The following methods may be used by
extensions:
-.. autoclass:: jinja.parser.Parser
+.. autoclass:: jinja2.parser.Parser
:members: parse_expression, parse_tuple, parse_assign_target,
parse_statements, free_identifier, fail
.. attribute:: stream
- The current :class:`~jinja.lexer.TokenStream`
+ The current :class:`~jinja2.lexer.TokenStream`
-.. autoclass:: jinja.lexer.TokenStream
+.. autoclass:: jinja2.lexer.TokenStream
:members: push, look, eos, skip, __next__, next_if, skip_if, expect
.. attribute:: current
- The current :class:`~jinja.lexer.Token`.
+ The current :class:`~jinja2.lexer.Token`.
-.. autoclass:: jinja.lexer.Token
+.. autoclass:: jinja2.lexer.Token
:members: test, test_any
.. attribute:: lineno
There is also a utility function in the lexer module that can count newline
characters in strings:
-.. autofunction:: jinja.lexer.count_newlines
+.. autofunction:: jinja2.lexer.count_newlines
AST
The list below describes all nodes that are currently available. The AST may
change between Jinja versions but will stay backwards compatible.
-For more information have a look at the repr of :meth:`jinja.Environment.parse`.
+For more information have a look at the repr of :meth:`jinja2.Environment.parse`.
-.. module:: jinja.nodes
+.. module:: jinja2.nodes
-.. jinja:nodes:: jinja.nodes.Node
+.. jinja:nodes:: jinja2.nodes.Node
.. autoexception:: Impossible
sandbox._WHITE_LIST_C_MODULES += ['_ctypes', 'gestalt']
Credit for this snippet goes to `Thomas Johansson
-<https://stackoverflow.com/a/3694434>`_
+<https://stackoverflow.com/questions/3086091/debug-jinja2-in-google-app-engine/3694434#3694434>`_
Why is there no Python 2.3/2.4/2.5/2.6/3.1/3.2/3.3 support?
-----------------------------------------------------------
-----------------
Jinja provides support for extracting gettext messages from templates via a
-`Babel`_ extractor entry point called `jinja.ext.babel_extract`. The Babel
+`Babel`_ extractor entry point called `jinja2.ext.babel_extract`. The Babel
support is implemented as part of the :ref:`i18n-extension` extension.
Gettext messages extracted from both `trans` tags and code expressions.
.. sourcecode:: ini
- [jinja: **/templates/**.html]
+ [jinja2: **/templates/**.html]
encoding = utf-8
The syntax related options of the :class:`Environment` are also available as
.. sourcecode:: ini
- [jinja: **/templates/**.html]
+ [jinja2: **/templates/**.html]
encoding = utf-8
line_statement_prefix = %
The template engine is configured in `config/environment.py`. The configuration
for Jinja looks something like that::
- from jinja import Environment, PackageLoader
+ from jinja2 import Environment, PackageLoader
config['pylons.app_globals'].jinja_env = Environment(
loader=PackageLoader('yourapplication', 'templates')
)
developer friendly by sticking to Python's principles and adding functionality
useful for templating environments.
-
Prerequisites
-------------
-Jinja works with Python >= 3.5 and 2.7.
-
-Jinja depends on `MarkupSafe`_. If you install via ``pip`` it will be
-installed automatically.
-
-.. _MarkupSafe: https://markupsafe.palletsprojects.com/
+Jinja works with Python 2.7.x and >= 3.5. If you are using Python
+3.2 you can use an older release of Jinja (2.6) as support for Python 3.2
+was dropped in Jinja version 2.7. The last release which supported Python 2.6
+and 3.3 was Jinja 2.10.
+If you wish to use the :class:`~jinja2.PackageLoader` class, you will also
+need `setuptools`_ or `distribute`_ installed at runtime.
Installation
------------
You can install the most recent Jinja version using `pip`_::
- pip install Jinja
+ pip install Jinja2
This will install Jinja in your Python installation's site-packages directory.
+Installing the development version
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+1. Install `git`_
+2. ``git clone git://github.com/pallets/jinja.git``
+3. ``cd jinja2``
+4. ``ln -s jinja2 /usr/lib/python2.X/site-packages``
+
+As an alternative to steps 4 you can also do ``python setup.py develop``
+which will install the package via `distribute` in development mode. This also
+has the advantage that the C extensions are compiled.
+
+.. _distribute: https://pypi.org/project/distribute/
+.. _setuptools: https://pypi.org/project/setuptools/
.. _pip: https://pypi.org/project/pip/
+.. _git: https://git-scm.com/
+
+
+MarkupSafe Dependency
+~~~~~~~~~~~~~~~~~~~~~
+As of version 2.7 Jinja depends on the `MarkupSafe`_ module. If you install
+Jinja via ``pip`` it will be installed automatically for you.
+
+.. _MarkupSafe: https://markupsafe.palletsprojects.com/
Basic API Usage
---------------
templates.
The most basic way to create a template and render it is through
-:class:`~jinja.Template`. This however is not the recommended way to
+:class:`~jinja2.Template`. This however is not the recommended way to
work with it if your templates are not loaded from strings but the file
system or another data source:
->>> from jinja import Template
+>>> from jinja2 import Template
>>> template = Template('Hello {{ name }}!')
>>> template.render(name='John Doe')
u'Hello John Doe!'
-By creating an instance of :class:`~jinja.Template` you get back a new template
-object that provides a method called :meth:`~jinja.Template.render` which when
+By creating an instance of :class:`~jinja2.Template` you get back a new template
+object that provides a method called :meth:`~jinja2.Template.render` which when
called with a dict or keyword arguments expands the template. The dict
or keywords arguments passed to the template are the so-called "context"
of the template.
-.. module:: jinja.nativetypes
+.. module:: jinja2.nativetypes
.. _nativetypes:
Native Python Types
===================
-The default :class:`~jinja.Environment` renders templates to strings. With
+The default :class:`~jinja2.Environment` renders templates to strings. With
:class:`NativeEnvironment`, rendering a template produces a native Python type.
This is useful if you are using Jinja outside the context of creating text
files. For example, your code may have an intermediate step where users may use
API
---
-.. module:: jinja.sandbox
+.. module:: jinja2.sandbox
.. autoclass:: SandboxedEnvironment([options])
:members: is_safe_attribute, is_safe_callable, default_binop_table,
This example shows how the power (``**``) operator can be disabled in
Jinja::
- from jinja.sandbox import SandboxedEnvironment
+ from jinja2.sandbox import SandboxedEnvironment
class MyEnvironment(SandboxedEnvironment):
List of Builtin Filters
-----------------------
-.. jinja:filters:: jinja.defaults.DEFAULT_FILTERS
+.. jinja:filters:: jinja2.defaults.DEFAULT_FILTERS
.. _builtin-tests:
List of Builtin Tests
---------------------
-.. jinja:tests:: jinja.defaults.DEFAULT_TESTS
+.. jinja:tests:: jinja2.defaults.DEFAULT_TESTS
.. _builtin-globals:
.. code-block:: text
- {'context': {'cycler': <class 'jinja.utils.Cycler'>,
+ {'context': {'cycler': <class 'jinja2.utils.Cycler'>,
...,
- 'namespace': <class 'jinja.utils.Namespace'>},
+ 'namespace': <class 'jinja2.utils.Namespace'>},
'filters': ['abs', 'attr', 'batch', 'capitalize', 'center', 'count', 'd',
..., 'urlencode', 'urlize', 'wordcount', 'wordwrap', 'xmlattr'],
'tests': ['!=', '<', '<=', '==', '>', '>=', 'callable', 'defined',
from __future__ import print_function
-from jinja import Environment
+from jinja2 import Environment
env = Environment(
line_statement_prefix="#", variable_start_string="${", variable_end_string="}"
from __future__ import print_function
-from jinja import Environment
-from jinja.loaders import FileSystemLoader
+from jinja2 import Environment
+from jinja2.loaders import FileSystemLoader
env = Environment(loader=FileSystemLoader("templates"))
tmpl = env.get_template("broken.html")
from __future__ import print_function
-from jinja import Environment
-from jinja.loaders import DictLoader
+from jinja2 import Environment
+from jinja2.loaders import DictLoader
env = Environment(
loader=DictLoader(
from __future__ import print_function
-from jinja import Environment
-from jinja.loaders import DictLoader
+from jinja2 import Environment
+from jinja2.loaders import DictLoader
env = Environment(
loader=DictLoader(
from __future__ import print_function
-from jinja import Environment
+from jinja2 import Environment
env = Environment(
line_statement_prefix="%", variable_start_string="${", variable_end_string="}"
from __future__ import print_function
-from jinja import Environment
+from jinja2 import Environment
tmpl = Environment().from_string(
"""\
from __future__ import print_function
-from jinja import Environment
+from jinja2 import Environment
-env = Environment(extensions=["jinja.ext.i18n"])
+env = Environment(extensions=["jinja2.ext.i18n"])
env.globals["gettext"] = {"Hello %(user)s!": "Hallo %(user)s!"}.__getitem__
env.globals["ngettext"] = lambda s, p, n: {
"%(count)s user": "%(count)d Benutzer",
def main():
- """Build the regex pattern and write it to ``_identifier.py``."""
+ """Build the regex pattern and write it to
+ ``jinja2/_identifier.py``.
+ """
pattern = build_pattern(collapse_ranges(get_characters()))
filename = os.path.abspath(
- os.path.join(os.path.dirname(__file__), "..", "src", "jinja", "_identifier.py")
+ os.path.join(os.path.dirname(__file__), "..", "src", "jinja2", "_identifier.py")
)
with open(filename, "w", encoding="utf8") as f:
testpaths = tests
filterwarnings =
error
- ignore:the sets module:DeprecationWarning:jinja.sandbox
+ ignore:the sets module:DeprecationWarning:jinja2.sandbox
[coverage:run]
branch = True
source =
- jinja
+ jinja2
tests
[coverage:paths]
source =
- src/jinja
- .tox/*/lib/python*/site-packages/jinja
- .tox/*/site-packages/jinja
+ src/jinja2
+ .tox/*/lib/python*/site-packages/jinja2
+ .tox/*/site-packages/jinja2
[flake8]
# B = bugbear
max-line-length = 80
per-file-ignores =
# __init__ module exports names
- src/jinja/__init__.py: F401
+ src/jinja2/__init__.py: F401
with io.open("README.rst", "rt", encoding="utf8") as f:
readme = f.read()
-with io.open("src/jinja/__init__.py", "rt", encoding="utf8") as f:
+with io.open("src/jinja2/__init__.py", "rt", encoding="utf8") as f:
version = re.search(r'__version__ = "(.*?)"', f.read(), re.M).group(1)
setup(
- name="Jinja",
+ name="Jinja2",
version=version,
url="https://palletsprojects.com/p/jinja/",
project_urls={
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
install_requires=["MarkupSafe>=0.23"],
extras_require={"i18n": ["Babel>=0.8"]},
- entry_points={"babel.extractors": ["jinja = jinja.ext:babel_extract[i18n]"]},
+ entry_points={"babel.extractors": ["jinja2 = jinja2.ext:babel_extract[i18n]"]},
)
from ._compat import text_type
from .utils import open_if_exists
-bc_version = 4
-# Magic bytes to identify Jinja bytecode cache files. Contains the
-# Python major and minor version to avoid loading incompatible bytecode
-# if a project upgrades its Python version.
+bc_version = 3
+
+# magic version used to only change with new jinja versions. With 2.6
+# we change this to also take Python version changes into account. The
+# reason for this is that Python tends to segfault if fed earlier bytecode
+# versions because someone thought it would be a good idea to reuse opcodes
+# or make Python incompatible with earlier versions.
bc_magic = (
- b"jinja"
+ "j2".encode("ascii")
+ pickle.dumps(bc_version, 2)
- + pickle.dumps((sys.version_info[0] << 24) | sys.version_info[1], 2)
+ + pickle.dumps((sys.version_info[0] << 24) | sys.version_info[1])
)
class BytecodeCache(object):
"""To implement your own bytecode cache you have to subclass this class
and override :meth:`load_bytecode` and :meth:`dump_bytecode`. Both of
- these methods are passed a :class:`Bucket`.
+ these methods are passed a :class:`~jinja2.bccache.Bucket`.
A very basic bytecode cache that saves the bytecode on the file system::
is created for the user in the system temp directory.
The pattern can be used to have multiple separate caches operate on the
- same directory. The default pattern is ``'__jinja_%s.cache'``. ``%s``
+ same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s``
is replaced with the cache key.
>>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache')
This bytecode cache supports clearing of the cache using the clear method.
-
- .. versionchanged:; 2.11
- The default cache directory was renamed to
- ``_jinja-cache-{uid}``. The default filename pattern was renamed
- to ``__jinja_%s.cache``.
"""
- def __init__(self, directory=None, pattern="__jinja_%s.cache"):
+ def __init__(self, directory=None, pattern="__jinja2_%s.cache"):
if directory is None:
directory = self._get_default_cache_dir()
self.directory = directory
if not hasattr(os, "getuid"):
_unsafe_dir()
- dirname = "_jinja-cache-%d" % os.getuid()
+ dirname = "_jinja2-cache-%d" % os.getuid()
actual_dir = os.path.join(tmpdir, dirname)
try:
This bytecode cache does not support clearing of used items in the cache.
The clear method is a no-operation function.
- .. versionchanged:: 2.11
- The default prefix was renamed to ``jinja/bytecode/``.
-
- .. versionchanged:: 2.7
- Added support for ignoring memcache errors through the
- ``ignore_memcache_errors`` parameter.
+ .. versionadded:: 2.7
+ Added support for ignoring memcache errors through the
+ `ignore_memcache_errors` parameter.
"""
def __init__(
self,
client,
- prefix="jinja/bytecode/",
+ prefix="jinja2/bytecode/",
timeout=None,
ignore_memcache_errors=True,
):
from .runtime import __all__ as exported
self.writeline("from __future__ import %s" % ", ".join(code_features))
- self.writeline("from jinja.runtime import " + ", ".join(exported))
+ self.writeline("from jinja2.runtime import " + ", ".join(exported))
if self.environment.is_async:
self.writeline(
- "from jinja.asyncsupport import auto_await, "
+ "from jinja2.asyncsupport import auto_await, "
"auto_aiter, AsyncLoopContext"
)
`autoescape`
If set to ``True`` the XML/HTML autoescaping feature is enabled by
default. For more details about autoescaping see
- :class:`~markupsafe.Markup`. This can also
+ :class:`~jinja2.utils.Markup`. As of Jinja 2.4 this can also
be a callable that is passed the template name and has to
return ``True`` or ``False`` depending on autoescape should be
enabled by default.
#: if this environment is sandboxed. Modifying this variable won't make
#: the environment sandboxed though. For a real sandboxed environment
- #: have a look at jinja.sandbox. This flag alone controls the code
+ #: have a look at jinja2.sandbox. This flag alone controls the code
#: generation by the compiler.
sandboxed = False
shared = False
#: the class that is used for code generation. See
- #: :class:`~jinja.compiler.CodeGenerator` for more information.
+ #: :class:`~jinja2.compiler.CodeGenerator` for more information.
code_generator_class = CodeGenerator
#: the context class thatis used for templates. See
- #: :class:`~jinja.runtime.Context` for more information.
+ #: :class:`~jinja2.runtime.Context` for more information.
context_class = Context
def __init__(
def _tokenize(self, source, name, filename=None, state=None):
"""Called by the parser to do the preprocessing and filtering
- for all the extensions. Returns a :class:`~jinja.lexer.TokenStream`.
+ for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`.
"""
source = self.preprocess(source, name, filename)
stream = self.lexer.tokenize(source, name, filename, state)
class TemplateExpression(object):
- """The :meth:`jinja.Environment.compile_expression` method returns an
+ """The :meth:`jinja2.Environment.compile_expression` method returns an
instance of this object. It encapsulates the expression-like access
to the template with an expression it wraps.
"""
return source
def filter_stream(self, stream):
- """It's passed a :class:`~jinja.lexer.TokenStream` that can be used
+ """It's passed a :class:`~jinja2.lexer.TokenStream` that can be used
to filter tokens returned. This method has to return an iterable of
- :class:`~jinja.lexer.Token`\\s, but it doesn't have to return a
- :class:`~jinja.lexer.TokenStream`.
+ :class:`~jinja2.lexer.Token`\\s, but it doesn't have to return a
+ :class:`~jinja2.lexer.TokenStream`.
"""
return stream
self, name, args=None, kwargs=None, dyn_args=None, dyn_kwargs=None, lineno=None
):
"""Call a method of the extension. This is a shortcut for
- :meth:`attr` + :class:`jinja.nodes.Call`.
+ :meth:`attr` + :class:`jinja2.nodes.Call`.
"""
if args is None:
args = []
.. code-block:: text
- {'context': {'cycler': <class 'jinja.utils.Cycler'>,
+ {'context': {'cycler': <class 'jinja2.utils.Cycler'>,
...,
- 'namespace': <class 'jinja.utils.Namespace'>},
+ 'namespace': <class 'jinja2.utils.Namespace'>},
'filters': ['abs', 'attr', 'batch', 'capitalize', 'center', 'count', 'd',
..., 'urlencode', 'urlize', 'wordcount', 'wordwrap', 'xmlattr'],
'tests': ['!=', '<', '<=', '==', '>', '>=', 'callable', 'defined',
This example explains the behavior:
- >>> from jinja import Environment
+ >>> from jinja2 import Environment
>>> env = Environment()
>>> node = env.parse('{{ (_("foo"), _(), ngettext("foo", "bar", 42)) }}')
>>> list(extract_from_ast(node))
{{ ''|default('the string was empty', true) }}
.. versionchanged:: 2.11
- It's now possible to configure the :class:`~jinja.Environment` with
- :class:`~jinja.ChainableUndefined` to make the `default` filter work
+ It's now possible to configure the :class:`~jinja2.Environment` with
+ :class:`~jinja2.ChainableUndefined` to make the `default` filter work
on nested elements and attributes that may contain undefined values
- in the chain without getting an :exc:`~jinja.UndefinedError`.
+ in the chain without getting an :exc:`~jinja2.UndefinedError`.
"""
if isinstance(value, Undefined) or (boolean and not value):
return default_value
def expect(self, expr):
"""Expect a given token type and return it. This accepts the same
- argument as :meth:`jinja.lexer.Token.test`.
+ argument as :meth:`jinja2.lexer.Token.test`.
"""
if not self.current.test(expr):
expr = describe_token_expr(expr)
A very basic example for a loader that looks up templates on the file
system could look like this::
- from jinja import BaseLoader, TemplateNotFound
+ from jinja2 import BaseLoader, TemplateNotFound
from os.path import join, exists, getmtime
class MyLoader(BaseLoader):
has_source_access = False
def __init__(self, path):
- package_name = "_jinja_module_templates_%x" % id(self)
+ package_name = "_jinja2_module_templates_%x" % id(self)
# create a fake module that looks for the templates in the
# path given.
variables will be used depending on the path the execution takes at
runtime, all variables are returned.
- >>> from jinja import Environment, meta
+ >>> from jinja2 import Environment, meta
>>> env = Environment()
>>> ast = env.parse('{% set foo = 42 %}{{ bar + foo }}')
>>> meta.find_undeclared_variables(ast) == set(['bar'])
imports. If dynamic inheritance or inclusion is used, `None` will be
yielded.
- >>> from jinja import Environment, meta
+ >>> from jinja2 import Environment, meta
>>> env = Environment()
>>> ast = env.parse('{% extends "layout.html" %}{% include helper %}')
>>> list(meta.find_referenced_templates(ast))
The identifier is the identifier of the :class:`Extension`.
This node is usually constructed by calling the
- :meth:`~jinja.ext.Extension.attr` method on an extension.
+ :meth:`~jinja2.ext.Extension.attr` method on an extension.
"""
fields = ("identifier", "name")
class InternalName(Expr):
"""An internal name in the compiler. You cannot create these nodes
yourself but the parser provides a
- :meth:`~jinja.parser.Parser.free_identifier` method that creates
+ :meth:`~jinja2.parser.Parser.free_identifier` method that creates
a new identifier for you. This identifier is not available from the
template and is not threated specially by the compiler.
"""
class ContextReference(Expr):
"""Returns the current template context. It can be used like a
:class:`Name` node, with a ``'load'`` ctx and will return the
- current :class:`~jinja.runtime.Context` object.
+ current :class:`~jinja2.runtime.Context` object.
Here an example that assigns the current template name to a
variable named `foo`::
Getattr(ContextReference(), 'name'))
This is basically equivalent to using the
- :func:`~jinja.contextfunction` decorator when using the
+ :func:`~jinja2.contextfunction` decorator when using the
high-level API, which causes a reference to the context to be passed
as the first argument to a function.
"""
class ScopedEvalContextModifier(EvalContextModifier):
"""Modifies the eval context and reverts it later. Works exactly like
:class:`EvalContextModifier` but will only modify the
- :class:`~jinja.nodes.EvalContext` for nodes in the :attr:`body`.
+ :class:`~jinja2.nodes.EvalContext` for nodes in the :attr:`body`.
"""
fields = ("body",)
return False
def free_identifier(self, lineno=None):
- """Return a new free identifier as :class:`~jinja.nodes.InternalName`."""
+ """Return a new free identifier as :class:`~jinja2.nodes.InternalName`."""
self._last_identifier += 1
rv = object.__new__(nodes.InternalName)
nodes.Node.__init__(rv, "fi%d" % self._last_identifier, lineno=lineno)
explicit_parentheses=False,
):
"""Works like `parse_expression` but if multiple expressions are
- delimited by a comma a :class:`~jinja.nodes.Tuple` node is created.
+ delimited by a comma a :class:`~jinja2.nodes.Tuple` node is created.
This method could also return a regular expression instead of a tuple
if no commas where found.
>>> foo + 42
Traceback (most recent call last):
...
- jinja.exceptions.UndefinedError: 'foo' is undefined
+ jinja2.exceptions.UndefinedError: 'foo' is undefined
"""
__slots__ = (
>>> foo.bar['baz'] + 42
Traceback (most recent call last):
...
- jinja.exceptions.UndefinedError: 'foo' is undefined
+ jinja2.exceptions.UndefinedError: 'foo' is undefined
.. versionadded:: 2.11.0
"""
>>> foo + 42
Traceback (most recent call last):
...
- jinja.exceptions.UndefinedError: 'foo' is undefined
+ jinja2.exceptions.UndefinedError: 'foo' is undefined
"""
__slots__ = ()
>>> str(foo)
Traceback (most recent call last):
...
- jinja.exceptions.UndefinedError: 'foo' is undefined
+ jinja2.exceptions.UndefinedError: 'foo' is undefined
>>> not foo
Traceback (most recent call last):
...
- jinja.exceptions.UndefinedError: 'foo' is undefined
+ jinja2.exceptions.UndefinedError: 'foo' is undefined
>>> foo + 42
Traceback (most recent call last):
...
- jinja.exceptions.UndefinedError: 'foo' is undefined
+ jinja2.exceptions.UndefinedError: 'foo' is undefined
"""
__slots__ = ()
python objects. This is useful if the environment method
:meth:`~SandboxedEnvironment.is_safe_attribute` is overridden.
- >>> from jinja.sandbox import is_internal_attribute
+ >>> from jinja2.sandbox import is_internal_attribute
>>> is_internal_attribute(str, "mro")
True
>>> is_internal_attribute(str, "upper")
If you want to enable it for all templates created from strings or
for all templates with `.html` and `.xml` extensions::
- from jinja import Environment, select_autoescape
+ from jinja2 import Environment, select_autoescape
env = Environment(autoescape=select_autoescape(
enabled_extensions=('html', 'xml'),
default_for_string=True,
Example configuration to turn it on at all times except if the template
ends with `.txt`::
- from jinja import Environment, select_autoescape
+ from jinja2 import Environment, select_autoescape
env = Environment(autoescape=select_autoescape(
disabled_extensions=('txt',),
default_for_string=True,
from markupsafe import soft_unicode
warnings.warn(
- "'jinja.utils.soft_unicode' will be removed in version 3.0."
+ "'jinja2.utils.soft_unicode' will be removed in version 3.0."
" Use 'markupsafe.soft_unicode' instead.",
DeprecationWarning,
stacklevel=2,
import pytest
-from jinja import Environment
-from jinja import loaders
-from jinja.utils import have_async_gen
+from jinja2 import Environment
+from jinja2 import loaders
+from jinja2.utils import have_async_gen
def pytest_ignore_collect(path):
import pytest
-from jinja import ChainableUndefined
-from jinja import DebugUndefined
-from jinja import DictLoader
-from jinja import Environment
-from jinja import is_undefined
-from jinja import make_logging_undefined
-from jinja import meta
-from jinja import StrictUndefined
-from jinja import Template
-from jinja import TemplatesNotFound
-from jinja import Undefined
-from jinja import UndefinedError
-from jinja.compiler import CodeGenerator
-from jinja.runtime import Context
-from jinja.utils import contextfunction
-from jinja.utils import Cycler
-from jinja.utils import environmentfunction
-from jinja.utils import evalcontextfunction
+from jinja2 import ChainableUndefined
+from jinja2 import DebugUndefined
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2 import is_undefined
+from jinja2 import make_logging_undefined
+from jinja2 import meta
+from jinja2 import StrictUndefined
+from jinja2 import Template
+from jinja2 import TemplatesNotFound
+from jinja2 import Undefined
+from jinja2 import UndefinedError
+from jinja2.compiler import CodeGenerator
+from jinja2.runtime import Context
+from jinja2.utils import contextfunction
+from jinja2.utils import Cycler
+from jinja2.utils import environmentfunction
+from jinja2.utils import evalcontextfunction
@pytest.mark.api
@pytest.mark.extended
class TestExtendedAPI(object):
def test_item_and_attribute(self, env):
- from jinja.sandbox import SandboxedEnvironment
+ from jinja2.sandbox import SandboxedEnvironment
for env in Environment(), SandboxedEnvironment():
# the |list is necessary for python3
assert t.render(foo="<foo>") == "<foo>"
def test_sandbox_max_range(self, env):
- from jinja.sandbox import SandboxedEnvironment, MAX_RANGE
+ from jinja2.sandbox import SandboxedEnvironment, MAX_RANGE
env = SandboxedEnvironment()
t = env.from_string("{% for item in range(total) %}{{ item }}{% endfor %}")
import pytest
-from jinja import DictLoader
-from jinja import Environment
-from jinja import Template
-from jinja.asyncsupport import auto_aiter
-from jinja.exceptions import TemplateNotFound
-from jinja.exceptions import TemplatesNotFound
-from jinja.exceptions import UndefinedError
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2 import Template
+from jinja2.asyncsupport import auto_aiter
+from jinja2.exceptions import TemplateNotFound
+from jinja2.exceptions import TemplatesNotFound
+from jinja2.exceptions import UndefinedError
def run(coro):
import pytest
-from jinja import Environment
-from jinja.utils import Markup
+from jinja2 import Environment
+from jinja2.utils import Markup
async def make_aiter(iter):
# -*- coding: utf-8 -*-
import pytest
-from jinja import Environment
-from jinja.bccache import Bucket
-from jinja.bccache import FileSystemBytecodeCache
-from jinja.bccache import MemcachedBytecodeCache
-from jinja.exceptions import TemplateNotFound
+from jinja2 import Environment
+from jinja2.bccache import Bucket
+from jinja2.bccache import FileSystemBytecodeCache
+from jinja2.bccache import MemcachedBytecodeCache
+from jinja2.exceptions import TemplateNotFound
@pytest.fixture
b = Bucket(None, "key", "")
b.code = "code"
m.dump_bytecode(b)
- assert memcached.key == "jinja/bytecode/key"
+ assert memcached.key == "jinja2/bytecode/key"
b = Bucket(None, "key", "")
m.load_bytecode(b)
# -*- coding: utf-8 -*-
import pytest
-from jinja import DictLoader
-from jinja import Environment
-from jinja import TemplateRuntimeError
-from jinja import TemplateSyntaxError
-from jinja import UndefinedError
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2 import TemplateRuntimeError
+from jinja2 import TemplateSyntaxError
+from jinja2 import UndefinedError
@pytest.fixture
import pytest
-from jinja import ChoiceLoader
-from jinja import DictLoader
-from jinja import Environment
-from jinja import TemplateSyntaxError
+from jinja2 import ChoiceLoader
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2 import TemplateSyntaxError
@pytest.fixture
"""(?sm)
File ".*?syntaxerror.html", line 4, in (template|<module>)
\\{% endif %\\}.*?
-(jinja\\.exceptions\\.)?TemplateSyntaxError: Encountered unknown tag 'endif'. Jinja \
+(jinja2\\.exceptions\\.)?TemplateSyntaxError: Encountered unknown tag 'endif'. Jinja \
was looking for the following tags: 'endfor' or 'else'. The innermost block that needs \
to be closed is 'for'.
""",
r"""
File ".*debug.pyc?", line \d+, in test
raise TemplateSyntaxError\("wtf", 42\)
-(jinja\.exceptions\.)?TemplateSyntaxError: wtf
+(jinja2\.exceptions\.)?TemplateSyntaxError: wtf
line 42""",
)
assert exc_info.value.source is not None
def test_local_extraction(self):
- from jinja.debug import get_template_locals
- from jinja.runtime import missing
+ from jinja2.debug import get_template_locals
+ from jinja2.runtime import missing
locals = get_template_locals(
{
import pytest
-from jinja import contextfunction
-from jinja import DictLoader
-from jinja import Environment
-from jinja import nodes
-from jinja._compat import BytesIO
-from jinja._compat import itervalues
-from jinja._compat import text_type
-from jinja.exceptions import TemplateAssertionError
-from jinja.ext import Extension
-from jinja.lexer import count_newlines
-from jinja.lexer import Token
+from jinja2 import contextfunction
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2 import nodes
+from jinja2._compat import BytesIO
+from jinja2._compat import itervalues
+from jinja2._compat import text_type
+from jinja2.exceptions import TemplateAssertionError
+from jinja2.ext import Extension
+from jinja2.lexer import count_newlines
+from jinja2.lexer import Token
importable_object = 23
return languages.get(language, {}).get(s, s)
-i18n_env = Environment(loader=DictLoader(i18n_templates), extensions=["jinja.ext.i18n"])
+i18n_env = Environment(
+ loader=DictLoader(i18n_templates), extensions=["jinja2.ext.i18n"]
+)
i18n_env.globals.update({"_": gettext, "gettext": gettext, "ngettext": ngettext})
-i18n_env_trimmed = Environment(extensions=["jinja.ext.i18n"])
+i18n_env_trimmed = Environment(extensions=["jinja2.ext.i18n"])
i18n_env_trimmed.policies["ext.i18n.trimmed"] = True
i18n_env_trimmed.globals.update(
{"_": gettext, "gettext": gettext, "ngettext": ngettext}
)
newstyle_i18n_env = Environment(
- loader=DictLoader(newstyle_i18n_templates), extensions=["jinja.ext.i18n"]
+ loader=DictLoader(newstyle_i18n_templates), extensions=["jinja2.ext.i18n"]
)
newstyle_i18n_env.install_gettext_callables(gettext, ngettext, newstyle=True)
class TestExtensions(object):
def test_extend_late(self):
env = Environment()
- env.add_extension("jinja.ext.autoescape")
+ env.add_extension("jinja2.ext.autoescape")
t = env.from_string('{% autoescape true %}{{ "<test>" }}{% endautoescape %}')
assert t.render() == "<test>"
def test_loop_controls(self):
- env = Environment(extensions=["jinja.ext.loopcontrols"])
+ env = Environment(extensions=["jinja2.ext.loopcontrols"])
tmpl = env.from_string(
"""
assert tmpl.render() == "12"
def test_do(self):
- env = Environment(extensions=["jinja.ext.do"])
+ env = Environment(extensions=["jinja2.ext.do"])
tmpl = env.from_string(
"""
{%- set items = [] %}
assert ext[1].__class__ is T2
def test_debug(self):
- env = Environment(extensions=["jinja.ext.debug"])
+ env = Environment(extensions=["jinja2.ext.debug"])
t = env.from_string("Hello\n{% debug %}\nGoodbye")
out = t.render()
assert tmpl.render() == " hello\n world "
def test_extract(self):
- from jinja.ext import babel_extract
+ from jinja2.ext import babel_extract
source = BytesIO(
"""
]
def test_extract_trimmed(self):
- from jinja.ext import babel_extract
+ from jinja2.ext import babel_extract
source = BytesIO(
"""
]
def test_extract_trimmed_option(self):
- from jinja.ext import babel_extract
+ from jinja2.ext import babel_extract
source = BytesIO(
"""
]
def test_comment_extract(self):
- from jinja.ext import babel_extract
+ from jinja2.ext import babel_extract
source = BytesIO(
"""
assert tmpl.render(LANGUAGE="de", apples=5) == u"5 Äpfel"
def test_autoescape_support(self):
- env = Environment(extensions=["jinja.ext.autoescape", "jinja.ext.i18n"])
+ env = Environment(extensions=["jinja2.ext.autoescape", "jinja2.ext.i18n"])
env.install_gettext_callables(
lambda x: u"<strong>Wert: %(name)s</strong>",
lambda s, p, n: s,
assert t.render(ae=False) == "<strong>Wert: <test></strong>"
def test_autoescape_macros(self):
- env = Environment(autoescape=False, extensions=["jinja.ext.autoescape"])
+ env = Environment(autoescape=False, extensions=["jinja2.ext.autoescape"])
template = (
"{% macro m() %}<html>{% endmacro %}"
"{% autoescape true %}{{ m() }}{% endautoescape %}"
@pytest.mark.ext
class TestAutoEscape(object):
def test_scoped_setting(self):
- env = Environment(extensions=["jinja.ext.autoescape"], autoescape=True)
+ env = Environment(extensions=["jinja2.ext.autoescape"], autoescape=True)
tmpl = env.from_string(
"""
{{ "<HelloWorld>" }}
u"<HelloWorld>",
]
- env = Environment(extensions=["jinja.ext.autoescape"], autoescape=False)
+ env = Environment(extensions=["jinja2.ext.autoescape"], autoescape=False)
tmpl = env.from_string(
"""
{{ "<HelloWorld>" }}
]
def test_nonvolatile(self):
- env = Environment(extensions=["jinja.ext.autoescape"], autoescape=True)
+ env = Environment(extensions=["jinja2.ext.autoescape"], autoescape=True)
tmpl = env.from_string('{{ {"foo": "<test>"}|xmlattr|escape }}')
assert tmpl.render() == ' foo="<test>"'
tmpl = env.from_string(
assert tmpl.render() == " foo="&lt;test&gt;""
def test_volatile(self):
- env = Environment(extensions=["jinja.ext.autoescape"], autoescape=True)
+ env = Environment(extensions=["jinja2.ext.autoescape"], autoescape=True)
tmpl = env.from_string(
'{% autoescape foo %}{{ {"foo": "<test>"}'
"|xmlattr|escape }}{% endautoescape %}"
assert tmpl.render(foo=True) == ' foo="<test>"'
def test_scoping(self):
- env = Environment(extensions=["jinja.ext.autoescape"])
+ env = Environment(extensions=["jinja2.ext.autoescape"])
tmpl = env.from_string(
'{% autoescape true %}{% set x = "<x>" %}{{ x }}'
'{% endautoescape %}{{ x }}{{ "<y>" }}'
assert tmpl.render(x=1) == "<x>1<y>"
def test_volatile_scoping(self):
- env = Environment(extensions=["jinja.ext.autoescape"])
+ env = Environment(extensions=["jinja2.ext.autoescape"])
tmplsource = """
{% autoescape val %}
{% macro foo(x) %}
# looking at the source we should see <testing> there in raw
# (and then escaped as well)
- env = Environment(extensions=["jinja.ext.autoescape"])
+ env = Environment(extensions=["jinja2.ext.autoescape"])
pysource = env.compile(tmplsource, raw=True)
assert "<testing>\\n" in pysource
- env = Environment(extensions=["jinja.ext.autoescape"], autoescape=True)
+ env = Environment(extensions=["jinja2.ext.autoescape"], autoescape=True)
pysource = env.compile(tmplsource, raw=True)
assert "<testing>\\n" in pysource
import pytest
-from jinja import contextfilter
-from jinja import Environment
-from jinja import Template
-from jinja._compat import text_type
+from jinja2 import contextfilter
+from jinja2 import Environment
+from jinja2 import Template
+from jinja2._compat import text_type
@pytest.mark.skipif(sys.version_info < (3, 5), reason="Requires 3.5 or later")
import pytest
-from jinja import Environment
-from jinja import Markup
-from jinja._compat import implements_to_string
-from jinja._compat import text_type
+from jinja2 import Environment
+from jinja2 import Markup
+from jinja2._compat import implements_to_string
+from jinja2._compat import text_type
@implements_to_string
-from jinja import nodes
-from jinja.idtracking import symbols_for_node
+from jinja2 import nodes
+from jinja2.idtracking import symbols_for_node
def test_basics():
# -*- coding: utf-8 -*-
import pytest
-from jinja import DictLoader
-from jinja import Environment
-from jinja.exceptions import TemplateNotFound
-from jinja.exceptions import TemplatesNotFound
-from jinja.exceptions import TemplateSyntaxError
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2.exceptions import TemplateNotFound
+from jinja2.exceptions import TemplatesNotFound
+from jinja2.exceptions import TemplateSyntaxError
@pytest.fixture
# -*- coding: utf-8 -*-
import pytest
-from jinja import DictLoader
-from jinja import Environment
-from jinja import TemplateRuntimeError
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2 import TemplateRuntimeError
LAYOUTTEMPLATE = """\
|{% block block1 %}block 1 from layout{% endblock %}
# -*- coding: utf-8 -*-
import pytest
-from jinja import Environment
-from jinja import nodes
-from jinja import Template
-from jinja import TemplateSyntaxError
-from jinja import UndefinedError
-from jinja._compat import iteritems
-from jinja._compat import PY2
-from jinja._compat import text_type
-from jinja.lexer import Token
-from jinja.lexer import TOKEN_BLOCK_BEGIN
-from jinja.lexer import TOKEN_BLOCK_END
-from jinja.lexer import TOKEN_EOF
-from jinja.lexer import TokenStream
+from jinja2 import Environment
+from jinja2 import nodes
+from jinja2 import Template
+from jinja2 import TemplateSyntaxError
+from jinja2 import UndefinedError
+from jinja2._compat import iteritems
+from jinja2._compat import PY2
+from jinja2._compat import text_type
+from jinja2.lexer import Token
+from jinja2.lexer import TOKEN_BLOCK_BEGIN
+from jinja2.lexer import TOKEN_BLOCK_END
+from jinja2.lexer import TOKEN_EOF
+from jinja2.lexer import TokenStream
# how does a string look like in jinja syntax?
assert tmpl.render() == pformat("foo") + "|" + pformat(u"bär")
def test_operators(self, env):
- from jinja.lexer import operators
+ from jinja2.lexer import operators
for test, expect in iteritems(operators):
if test in "([{}])":
import pytest
-from jinja import Environment
-from jinja import loaders
-from jinja import PackageLoader
-from jinja._compat import PY2
-from jinja._compat import PYPY
-from jinja.exceptions import TemplateNotFound
-from jinja.loaders import split_template_path
+from jinja2 import Environment
+from jinja2 import loaders
+from jinja2 import PackageLoader
+from jinja2._compat import PY2
+from jinja2._compat import PYPY
+from jinja2.exceptions import TemplateNotFound
+from jinja2.loaders import split_template_path
@pytest.mark.loaders
import pytest
-from jinja._compat import text_type
-from jinja.exceptions import UndefinedError
-from jinja.nativetypes import NativeEnvironment
-from jinja.nativetypes import NativeTemplate
-from jinja.runtime import Undefined
+from jinja2._compat import text_type
+from jinja2.exceptions import UndefinedError
+from jinja2.nativetypes import NativeEnvironment
+from jinja2.nativetypes import NativeTemplate
+from jinja2.runtime import Undefined
@pytest.fixture
import pytest
-from jinja import DictLoader
-from jinja import Environment
-from jinja import PrefixLoader
-from jinja import Template
-from jinja import TemplateAssertionError
-from jinja import TemplateNotFound
-from jinja import TemplateSyntaxError
-from jinja._compat import text_type
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2 import PrefixLoader
+from jinja2 import Template
+from jinja2 import TemplateAssertionError
+from jinja2 import TemplateNotFound
+from jinja2 import TemplateSyntaxError
+from jinja2._compat import text_type
@pytest.mark.regression
assert e.value.name == "foo/bar.html"
def test_contextfunction_callable_classes(self, env):
- from jinja.utils import contextfunction
+ from jinja2.utils import contextfunction
class CallableClass(object):
@contextfunction
def test_macro_escaping(self):
env = Environment(
- autoescape=lambda x: False, extensions=["jinja.ext.autoescape"]
+ autoescape=lambda x: False, extensions=["jinja2.ext.autoescape"]
)
template = "{% macro m() %}<html>{% endmacro %}"
template += "{% autoescape true %}{{ m() }}{% endautoescape %}"
assert env.get_template("main").render() == "123"
def test_grouper_repr(self):
- from jinja.filters import _GroupTuple
+ from jinja2.filters import _GroupTuple
t = _GroupTuple("foo", [1, 2])
assert t.grouper == "foo"
assert str(t) == "('foo', [1, 2])"
def test_custom_context(self, env):
- from jinja.runtime import Context
+ from jinja2.runtime import Context
class MyContext(Context):
pass
assert env.get_template("test").render(foobar="test") == "test"
def test_legacy_custom_context(self, env):
- from jinja.runtime import Context, missing
+ from jinja2.runtime import Context, missing
class MyContext(Context):
def resolve(self, name):
assert tmpl.render(values=[]) == "0"
def test_markup_and_chainable_undefined(self):
- from jinja import Markup
- from jinja.runtime import ChainableUndefined
+ from jinja2 import Markup
+ from jinja2.runtime import ChainableUndefined
assert str(Markup(ChainableUndefined())) == ""
import itertools
-from jinja import Template
-from jinja.runtime import LoopContext
+from jinja2 import Template
+from jinja2.runtime import LoopContext
TEST_IDX_TEMPLATE_STR_1 = (
"[{% for i in lst|reverse %}(len={{ loop.length }},"
# -*- coding: utf-8 -*-
import pytest
-from jinja import Environment
-from jinja import escape
-from jinja import Markup
-from jinja._compat import text_type
-from jinja.exceptions import SecurityError
-from jinja.exceptions import TemplateRuntimeError
-from jinja.exceptions import TemplateSyntaxError
-from jinja.nodes import EvalContext
-from jinja.sandbox import ImmutableSandboxedEnvironment
-from jinja.sandbox import SandboxedEnvironment
-from jinja.sandbox import unsafe
+from jinja2 import Environment
+from jinja2 import escape
+from jinja2 import Markup
+from jinja2._compat import text_type
+from jinja2.exceptions import SecurityError
+from jinja2.exceptions import TemplateRuntimeError
+from jinja2.exceptions import TemplateSyntaxError
+from jinja2.nodes import EvalContext
+from jinja2.sandbox import ImmutableSandboxedEnvironment
+from jinja2.sandbox import SandboxedEnvironment
+from jinja2.sandbox import unsafe
class PrivateStuff(object):
# -*- coding: utf-8 -*-
import pytest
-from jinja import Environment
-from jinja import Markup
+from jinja2 import Environment
+from jinja2 import Markup
class MyDict(dict):
import pytest
from markupsafe import Markup
-from jinja._compat import range_type
-from jinja._compat import string_types
-from jinja.utils import consume
-from jinja.utils import generate_lorem_ipsum
-from jinja.utils import LRUCache
-from jinja.utils import missing
-from jinja.utils import object_type_repr
-from jinja.utils import select_autoescape
-from jinja.utils import urlize
+from jinja2._compat import range_type
+from jinja2._compat import string_types
+from jinja2.utils import consume
+from jinja2.utils import generate_lorem_ipsum
+from jinja2.utils import LRUCache
+from jinja2.utils import missing
+from jinja2.utils import object_type_repr
+from jinja2.utils import select_autoescape
+from jinja2.utils import urlize
@pytest.mark.utils