summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lord <davidism@gmail.com>2020-01-10 10:40:52 -0800
committerDavid Lord <davidism@gmail.com>2020-01-10 10:40:52 -0800
commitbb6216ea305a06d0157f0c0d0fb8be7bb625c523 (patch)
tree221d419c2f8562a3758f468ccc7bd47b00447382
parent04c8787155137206d58d6ee147d06482c1a8b598 (diff)
downloadjinja2-bb6216ea305a06d0157f0c0d0fb8be7bb625c523.tar.gz
apply flake8
-rw-r--r--examples/basic/inheritance.py6
-rw-r--r--examples/basic/translate.py4
-rw-r--r--examples/bench.py20
-rw-r--r--ext/django2jinja/django2jinja.py174
-rw-r--r--ext/django2jinja/example.py5
-rwxr-xr-xscripts/generate_identifier_pattern.py9
-rw-r--r--scripts/make-release.py4
-rw-r--r--setup.cfg3
-rw-r--r--src/jinja2/_compat.py16
-rw-r--r--src/jinja2/_identifier.py2
-rw-r--r--src/jinja2/asyncfilters.py14
-rw-r--r--src/jinja2/bccache.py22
-rw-r--r--src/jinja2/compiler.py13
-rw-r--r--src/jinja2/debug.py2
-rw-r--r--src/jinja2/defaults.py4
-rw-r--r--src/jinja2/environment.py24
-rw-r--r--src/jinja2/ext.py14
-rw-r--r--src/jinja2/filters.py25
-rw-r--r--src/jinja2/lexer.py6
-rw-r--r--src/jinja2/loaders.py2
-rw-r--r--src/jinja2/nodes.py6
-rw-r--r--src/jinja2/parser.py6
-rw-r--r--src/jinja2/runtime.py32
-rw-r--r--src/jinja2/sandbox.py28
-rw-r--r--src/jinja2/tests.py2
-rw-r--r--src/jinja2/utils.py53
-rw-r--r--tests/test_api.py19
-rw-r--r--tests/test_async.py16
-rw-r--r--tests/test_asyncfilters.py42
-rw-r--r--tests/test_core_tags.py10
-rw-r--r--tests/test_debug.py27
-rw-r--r--tests/test_ext.py2
-rw-r--r--tests/test_features.py5
-rw-r--r--tests/test_filters.py79
-rw-r--r--tests/test_imports.py4
-rw-r--r--tests/test_inheritance.py5
-rw-r--r--tests/test_lexnparse.py8
-rw-r--r--tests/test_loader.py23
-rw-r--r--tests/test_regression.py59
-rw-r--r--tests/test_runtime.py26
-rw-r--r--tests/test_security.py7
-rw-r--r--tests/test_tests.py5
-rw-r--r--tests/test_utils.py26
43 files changed, 426 insertions, 433 deletions
diff --git a/examples/basic/inheritance.py b/examples/basic/inheritance.py
index a3073a5..4a881bf 100644
--- a/examples/basic/inheritance.py
+++ b/examples/basic/inheritance.py
@@ -6,9 +6,9 @@ from jinja2.loaders import DictLoader
env = Environment(
loader=DictLoader(
{
- "a": """[A[{% block body %}{% endblock %}]]""",
- "b": """{% extends 'a' %}{% block body %}[B]{% endblock %}""",
- "c": """{% extends 'b' %}{% block body %}###{{ super() }}###{% endblock %}""",
+ "a": "[A[{% block body %}{% endblock %}]]",
+ "b": "{% extends 'a' %}{% block body %}[B]{% endblock %}",
+ "c": "{% extends 'b' %}{% block body %}###{{ super() }}###{% endblock %}",
}
)
)
diff --git a/examples/basic/translate.py b/examples/basic/translate.py
index fda8f7a..71547f4 100644
--- a/examples/basic/translate.py
+++ b/examples/basic/translate.py
@@ -12,7 +12,9 @@ print(
env.from_string(
"""\
{% trans %}Hello {{ user }}!{% endtrans %}
-{% trans count=users|count %}{{ count }} user{% pluralize %}{{ count }} users{% endtrans %}
+{% trans count=users|count -%}
+{{ count }} user{% pluralize %}{{ count }} users
+{% endtrans %}
"""
).render(user="someone", users=[1, 2, 3])
)
diff --git a/examples/bench.py b/examples/bench.py
index 473928b..e610718 100644
--- a/examples/bench.py
+++ b/examples/bench.py
@@ -8,6 +8,7 @@ import sys
from timeit import Timer
from jinja2 import Environment as JinjaEnvironment
+from jinja2._compat import text_type
context = {
"page_title": "mitsuhiko's benchmark",
@@ -171,7 +172,8 @@ else:
<h1>${page_title|h}</h1>
</div>
<ul class="navigation">
- % for href, caption in [('index.html', 'Index'), ('downloads.html', 'Downloads'), ('products.html', 'Products')]:
+ % for href, caption in [('index.html', 'Index'), ('downloads.html', 'Downloads'), \
+('products.html', 'Products')]:
<li><a href="${href|h}">${caption|h}</a></li>
% endfor
</ul>
@@ -250,7 +252,8 @@ else:
<h1>$cgi.escape($page_title)</h1>
</div>
<ul class="navigation">
- #for $href, $caption in [('index.html', 'Index'), ('downloads.html', 'Downloads'), ('products.html', 'Products')]:
+ #for $href, $caption in [('index.html', 'Index'), ('downloads.html', 'Downloads'), \
+('products.html', 'Products')]:
<li><a href="$cgi.escape($href)">$cgi.escape($caption)</a></li>
#end for
</ul>
@@ -272,7 +275,7 @@ else:
)
def test_cheetah():
- unicode(cheetah_template)
+ text_type(cheetah_template)
try:
@@ -293,7 +296,8 @@ else:
<h1>${page_title}</h1>
</div>
<ul class="navigation">
-<?py for href, caption in [('index.html', 'Index'), ('downloads.html', 'Downloads'), ('products.html', 'Products')]: ?>
+<?py for href, caption in [('index.html', 'Index'), ('downloads.html', 'Downloads'), \
+('products.html', 'Products')]: ?>
<li><a href="${href}">${caption}</a></li>
<?py #end ?>
</ul>
@@ -314,8 +318,6 @@ else:
)
def test_tenjin():
- from tenjin.helpers import escape, to_str
-
tenjin_template.render(context, locals())
@@ -337,7 +339,8 @@ else:
<h1>$cgi.escape($page_title)</h1>
</div>
<ul class="navigation">
- #for $href, $caption in [('index.html', 'Index'), ('downloads.html', 'Downloads'), ('products.html', 'Products')]
+ #for $href, $caption in [('index.html', 'Index'), ('downloads.html', 'Downloads'), \
+('products.html', 'Products')]
<li><a href="$cgi.escape($href)">$cgi.escape($caption)</a></li>
#end for
</ul>
@@ -381,7 +384,8 @@ else:
<h1 tal:content="page_title">Page Title</h1>
</div>
<ul class="navigation">
- <li tal:repeat="item sections"><a tal:attributes="href item[0]" tal:content="item[1]">caption</a></li>
+ <li tal:repeat="item sections"><a tal:attributes="href item[0]" \
+tal:content="item[1]">caption</a></li>
</ul>
<div class="table">
<table>
diff --git a/ext/django2jinja/django2jinja.py b/ext/django2jinja/django2jinja.py
index 25b116e..11e1a2b 100644
--- a/ext/django2jinja/django2jinja.py
+++ b/ext/django2jinja/django2jinja.py
@@ -1,72 +1,75 @@
# -*- coding: utf-8 -*-
"""
- Django to Jinja
- ~~~~~~~~~~~~~~~
+Django to Jinja
+~~~~~~~~~~~~~~~
- Helper module that can convert django templates into Jinja templates.
+Helper module that can convert django templates into Jinja templates.
- This file is not intended to be used as stand alone application but to
- be used as library. To convert templates you basically create your own
- writer, add extra conversion logic for your custom template tags,
- configure your django environment and run the `convert_templates`
- function.
+This file is not intended to be used as stand alone application but to
+be used as library. To convert templates you basically create your own
+writer, add extra conversion logic for your custom template tags,
+configure your django environment and run the `convert_templates`
+function.
- Here a simple example::
+Here a simple example::
- # configure django (or use settings.configure)
- import os
- os.environ['DJANGO_SETTINGS_MODULE'] = 'yourapplication.settings'
- from yourapplication.foo.templatetags.bar import MyNode
+ # configure django (or use settings.configure)
+ import os
- from django2jinja import Writer, convert_templates
+ os.environ["DJANGO_SETTINGS_MODULE"] = "yourapplication.settings"
+ from yourapplication.foo.templatetags.bar import MyNode
- def write_my_node(writer, node):
- writer.start_variable()
- writer.write('myfunc(')
- for idx, arg in enumerate(node.args):
- if idx:
- writer.write(', ')
- writer.node(arg)
- writer.write(')')
- writer.end_variable()
+ from django2jinja import Writer, convert_templates
- writer = Writer()
- writer.node_handlers[MyNode] = write_my_node
- convert_templates('/path/to/output/folder', writer=writer)
-
- Here is an example hos to automatically translate your django
- variables to jinja2::
-
- import re
- # List of tuple (Match pattern, Replace pattern, Exclusion pattern)
-
- var_re = ((re.compile(r"(u|user)\.is_authenticated"), r"\1.is_authenticated()", None),
- (re.compile(r"\.non_field_errors"), r".non_field_errors()", None),
- (re.compile(r"\.label_tag"), r".label_tag()", None),
- (re.compile(r"\.as_dl"), r".as_dl()", None),
- (re.compile(r"\.as_table"), r".as_table()", None),
- (re.compile(r"\.as_widget"), r".as_widget()", None),
- (re.compile(r"\.as_hidden"), r".as_hidden()", None),
-
- (re.compile(r"\.get_([0-9_\w]+)_url"), r".get_\1_url()", None),
- (re.compile(r"\.url"), r".url()", re.compile(r"(form|calendar).url")),
- (re.compile(r"\.get_([0-9_\w]+)_display"), r".get_\1_display()", None),
- (re.compile(r"loop\.counter"), r"loop.index", None),
- (re.compile(r"loop\.revcounter"), r"loop.revindex", None),
- (re.compile(r"request\.GET\.([0-9_\w]+)"), r"request.GET.get('\1', '')", None),
- (re.compile(r"request\.get_host"), r"request.get_host()", None),
-
- (re.compile(r"\.all(?!_)"), r".all()", None),
- (re.compile(r"\.all\.0"), r".all()[0]", None),
- (re.compile(r"\.([0-9])($|\s+)"), r"[\1]\2", None),
- (re.compile(r"\.items"), r".items()", None),
- )
- writer = Writer(var_re=var_re)
+ def write_my_node(writer, node):
+ writer.start_variable()
+ writer.write("myfunc(")
+ for idx, arg in enumerate(node.args):
+ if idx:
+ writer.write(", ")
+ writer.node(arg)
+ writer.write(")")
+ writer.end_variable()
- For details about the writing process have a look at the module code.
+ writer = Writer()
+ writer.node_handlers[MyNode] = write_my_node
+ convert_templates("/path/to/output/folder", writer=writer)
+
+Here is an example hos to automatically translate your django
+variables to jinja2::
+
+ import re
+ # List of tuple (Match pattern, Replace pattern, Exclusion pattern)
+ var_re = (
+ (re.compile("(u|user)\\.is_authenticated"), "\\1.is_authenticated()", None),
+ (re.compile("\\.non_field_errors"), ".non_field_errors()", None),
+ (re.compile("\\.label_tag"), ".label_tag()", None),
+ (re.compile("\\.as_dl"), ".as_dl()", None),
+ (re.compile("\\.as_table"), ".as_table()", None),
+ (re.compile("\\.as_widget"), ".as_widget()", None),
+ (re.compile("\\.as_hidden"), ".as_hidden()", None),
+ (re.compile("\\.get_([0-9_\\w]+)_url"), ".get_\\1_url()", None),
+ (re.compile("\\.url"), ".url()", re.compile("(form|calendar).url")),
+ (re.compile("\\.get_([0-9_\\w]+)_display"), ".get_\\1_display()", None),
+ (re.compile("loop\\.counte"), "loop.index", None),
+ (re.compile("loop\\.revcounte"), "loop.revindex", None),
+ (
+ re.compile("request\\.GET\\.([0-9_\\w]+)"),
+ "request.GET.get('\\1', '')",
+ None,
+ ),
+ (re.compile("request\\.get_host"), "request.get_host()", None),
+ (re.compile("\\.all(?!_)"), ".all()", None),
+ (re.compile("\\.all\\.0"), ".all()[0]", None),
+ (re.compile("\\.([0-9])($|\\s+)"), "[\\1]\\2", None),
+ (re.compile("\\.items"), ".items()", None),
+ )
+ writer = Writer(var_re=var_re)
+
+For details about the writing process have a look at the module code.
- :copyright: (c) 2009 by the Jinja Team.
- :license: BSD.
+:copyright: (c) 2009 by the Jinja Team.
+:license: BSD.
"""
from __future__ import print_function
@@ -87,14 +90,12 @@ from django.template import Variable
from django.template.debug import DebugVariableNode as VariableNode
from django.templatetags import i18n as i18n_tags
-from jinja2.defaults import *
-
+from jinja2 import defaults
_node_handlers = {}
_resolved_filters = {}
_newline_re = re.compile(r"(?:\r\n|\r|\n)")
-
# 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()
@@ -122,7 +123,8 @@ def convert_templates(
output_dir, extensions=(".html", ".txt"), writer=None, callback=None
):
"""Iterates over all templates in the template dirs configured and
- translates them and writes the new templates into the output directory.
+ translates them and writes the new templates into the output
+ directory.
"""
if writer is None:
writer = Writer()
@@ -156,11 +158,8 @@ def convert_templates(
if not os.path.exists(basetarget):
os.makedirs(basetarget)
callback(source)
- f = file(target, "w")
- try:
+ with open(target, "w") as f:
translate(f, source)
- finally:
- f.close()
class Writer(object):
@@ -170,16 +169,16 @@ class Writer(object):
self,
stream=None,
error_stream=None,
- block_start_string=BLOCK_START_STRING,
- block_end_string=BLOCK_END_STRING,
- variable_start_string=VARIABLE_START_STRING,
- variable_end_string=VARIABLE_END_STRING,
- comment_start_string=COMMENT_START_STRING,
- comment_end_string=COMMENT_END_STRING,
+ block_start_string=defaults.BLOCK_START_STRING,
+ block_end_string=defaults.BLOCK_END_STRING,
+ variable_start_string=defaults.VARIABLE_START_STRING,
+ variable_end_string=defaults.VARIABLE_END_STRING,
+ comment_start_string=defaults.COMMENT_START_STRING,
+ comment_end_string=defaults.COMMENT_END_STRING,
initial_autoescape=True,
use_jinja_autoescape=False,
custom_node_handlers=None,
- var_re=[],
+ var_re=None,
env=None,
):
if stream is None:
@@ -200,12 +199,12 @@ class Writer(object):
self.node_handlers = dict(_node_handlers, **(custom_node_handlers or {}))
self._loop_depth = 0
self._filters_warned = set()
- self.var_re = var_re
+ self.var_re = [] if var_re is None else var_re
self.env = env
def enter_loop(self):
- """Increments the loop depth so that write functions know if they
- are in a loop.
+ """Increments the loop depth so that write functions know if
+ they are in a loop.
"""
self._loop_depth += 1
@@ -223,7 +222,9 @@ class Writer(object):
self.stream.write(s.encode(settings.FILE_CHARSET))
def print_expr(self, expr):
- """Open a variable tag, write to the string to the stream and close."""
+ """Open a variable tag, write to the string to the stream and
+ close.
+ """
self.start_variable()
self.write(expr)
self.end_variable()
@@ -269,7 +270,9 @@ class Writer(object):
self.end_block()
def variable(self, name):
- """Prints a variable. This performs variable name transformation."""
+ """Prints a variable. This performs variable name
+ transformation.
+ """
self.write(self.translate_variable_name(name))
def literal(self, value):
@@ -287,7 +290,10 @@ class Writer(object):
if name is None:
self.warn("Could not find filter %s" % name)
continue
- if name not in DEFAULT_FILTERS and name not in self._filters_warned:
+ if (
+ name not in defaults.DEFAULT_FILTERS
+ and name not in self._filters_warned
+ ):
self._filters_warned.add(name)
self.warn("Filter %s probably doesn't exist in Jinja" % name)
if not want_pipe:
@@ -344,13 +350,13 @@ class Writer(object):
"""
if filter not in _resolved_filters:
for library in libraries.values():
- for key, value in library.filters.iteritems():
+ for key, value in library.filters.items():
_resolved_filters[value] = key
return _resolved_filters.get(filter, None)
def node(self, node):
"""Invokes the node handler for a node."""
- for cls, handler in self.node_handlers.iteritems():
+ for cls, handler in self.node_handlers.items():
if type(node) is cls or type(node).__name__ == cls:
handler(self, node)
break
@@ -410,7 +416,7 @@ def comment_tag(writer, node):
@node(core_tags.DebugNode)
-def comment_tag(writer, node):
+def debug_tag(writer, node):
writer.warn(
"Debug tag detected. Make sure to add a global function "
"called debug to the namespace.",
@@ -596,7 +602,6 @@ def url_tag(writer, node):
writer.write("set %s = " % node.asvar)
else:
writer.start_variable()
- autoescape = writer.autoescape
writer.write("url(")
writer.literal(node.view_name)
for arg in node.args:
@@ -740,10 +745,7 @@ def translate_block(writer, node):
touch_var(key)
writer.node(var.filter_expression)
- have_plural = False
- plural_var = None
if node.plural and node.countervar and node.counter:
- have_plural = True
plural_var = node.countervar
if plural_var not in variables:
if idx > -1:
diff --git a/ext/django2jinja/example.py b/ext/django2jinja/example.py
index 9bd6b97..070549f 100644
--- a/ext/django2jinja/example.py
+++ b/ext/django2jinja/example.py
@@ -1,8 +1,7 @@
from django.conf import settings
+from django2jinja import convert_templates
+from django2jinja import Writer
settings.configure(TEMPLATE_DIRS=["templates"], TEMPLATE_DEBUG=True)
-
-from django2jinja import convert_templates, Writer
-
writer = Writer(use_jinja_autoescape=True)
convert_templates("converted", writer=writer)
diff --git a/scripts/generate_identifier_pattern.py b/scripts/generate_identifier_pattern.py
index 96fedba..845a441 100755
--- a/scripts/generate_identifier_pattern.py
+++ b/scripts/generate_identifier_pattern.py
@@ -10,9 +10,9 @@ if sys.version_info[0] < 3:
def get_characters():
"""Find every Unicode character that is valid in a Python `identifier`_ but
- is not matched by the regex ``\w`` group.
+ is not matched by the regex ``\\w`` group.
- ``\w`` matches some characters that aren't valid in identifiers, but
+ ``\\w`` matches some characters that aren't valid in identifiers, but
:meth:`str.isidentifier` will catch that later in lexing.
All start characters are valid continue characters, so we only test for
@@ -33,7 +33,7 @@ def collapse_ranges(data):
Source: https://stackoverflow.com/a/4629241/400617
"""
- for a, b in itertools.groupby(enumerate(data), lambda x: ord(x[1]) - x[0]):
+ for _, b in itertools.groupby(enumerate(data), lambda x: ord(x[1]) - x[0]):
b = list(b)
yield b[0][1], b[-1][1]
@@ -66,8 +66,9 @@ def main():
)
with open(filename, "w", encoding="utf8") as f:
+ f.write("")
f.write("# generated by scripts/generate_identifier_pattern.py\n")
- f.write('pattern = "{}"\n'.format(pattern))
+ f.write('pattern = "{}" # noqa: B950\n'.format(pattern))
if __name__ == "__main__":
diff --git a/scripts/make-release.py b/scripts/make-release.py
index cd6ce23..de36ae1 100644
--- a/scripts/make-release.py
+++ b/scripts/make-release.py
@@ -27,7 +27,7 @@ def parse_changelog():
with open("CHANGES.rst") as f:
lineiter = iter(f)
for line in lineiter:
- match = re.search("^Version\s+(.*)", line.strip())
+ match = re.search(r"^Version\s+(.*)", line.strip())
if match is None:
continue
@@ -161,7 +161,7 @@ def main():
fail("You have uncommitted changes in git")
try:
- import wheel
+ __import__("wheel")
except ImportError:
fail("You need to install the wheel package.")
diff --git a/setup.cfg b/setup.cfg
index 5ff30eb..a9dfcbb 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -37,3 +37,6 @@ ignore =
W503
# up to 88 allowed by bugbear B950
max-line-length = 80
+per-file-ignores =
+ # __init__ module exports names
+ src/jinja2/__init__.py: F401
diff --git a/src/jinja2/_compat.py b/src/jinja2/_compat.py
index 02aed34..aa21641 100644
--- a/src/jinja2/_compat.py
+++ b/src/jinja2/_compat.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
+# flake8: noqa
"""
jinja2._compat
~~~~~~~~~~~~~~
@@ -10,6 +11,7 @@
:copyright: Copyright 2013 by the Jinja team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
+import marshal
import sys
PY2 = sys.version_info[0] == 2
@@ -46,6 +48,9 @@ if not PY2:
implements_to_string = _identity
encode_filename = _identity
+ marshal_dump = marshal.dump
+ marshal_load = marshal.load
+
else:
unichr = unichr
text_type = unicode
@@ -83,6 +88,17 @@ else:
return filename.encode("utf-8")
return filename
+ def marshal_dump(code, f):
+ if isinstance(f, file):
+ marshal.dump(code, f)
+ else:
+ f.write(marshal.dumps(code))
+
+ def marshal_load(f):
+ if isinstance(f, file):
+ return marshal.load(f)
+ return marshal.loads(f.read())
+
def with_metaclass(meta, *bases):
"""Create a base class with a metaclass."""
diff --git a/src/jinja2/_identifier.py b/src/jinja2/_identifier.py
index 0a93e95..2490963 100644
--- a/src/jinja2/_identifier.py
+++ b/src/jinja2/_identifier.py
@@ -1,2 +1,2 @@
# generated by scripts/generate_identifier_pattern.py
-pattern = "·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣔ-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூெ-ைொ-்ௗఀ-ఃా-ౄె-ైొ-్ౕౖౢౣಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣංඃ්ා-ුූෘ-ෟෲෳัิ-ฺ็-๎ັິ-ູົຼ່-ໍ༹༘༙༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏႚ-ႝ፝-፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝᠋-᠍ᢅᢆᢩᤠ-ᤫᤰ-᤻ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼᪰-᪽ᬀ-ᬄ᬴-᭄᭫-᭳ᮀ-ᮂᮡ-ᮭ᯦-᯳ᰤ-᰷᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰℘℮⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣠-꣱ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀ꧥꨩ-ꨶꩃꩌꩍꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ︀-️︠-︯︳︴﹍-﹏_𐇽𐋠𐍶-𐍺𐨁-𐨃𐨅𐨆𐨌-𐨏𐨸-𐨿𐨺𐫦𐫥𑀀-𑀂𑀸-𑁆𑁿-𑂂𑂰-𑂺𑄀-𑄂𑄧-𑅳𑄴𑆀-𑆂𑆳-𑇊𑇀-𑇌𑈬-𑈷𑈾𑋟-𑋪𑌀-𑌃𑌼𑌾-𑍄𑍇𑍈𑍋-𑍍𑍗𑍢𑍣𑍦-𑍬𑍰-𑍴𑐵-𑑆𑒰-𑓃𑖯-𑖵𑖸-𑗀𑗜𑗝𑘰-𑙀𑚫-𑚷𑜝-𑜫𑰯-𑰶𑰸-𑰿𑲒-𑲧𑲩-𑲶𖫰-𖫴𖬰-𖬶𖽑-𖽾𖾏-𖾒𛲝𛲞𝅥-𝅩𝅭-𝅲𝅻-𝆂𝆅-𝆋𝆪-𝆭𝉂-𝉄𝨀-𝨶𝨻-𝩬𝩵𝪄𝪛-𝪟𝪡-𝪯𞀀-𞀆𞀈-𞀘𞀛-𞀡𞀣𞀤𞀦-𞣐𞀪-𞣖𞥄-𞥊󠄀-󠇯"
+pattern = "·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣔ-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூெ-ைொ-்ௗఀ-ఃా-ౄె-ైొ-్ౕౖౢౣಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣංඃ්ා-ුූෘ-ෟෲෳัิ-ฺ็-๎ັິ-ູົຼ່-ໍ༹༘༙༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏႚ-ႝ፝-፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝᠋-᠍ᢅᢆᢩᤠ-ᤫᤰ-᤻ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼᪰-᪽ᬀ-ᬄ᬴-᭄᭫-᭳ᮀ-ᮂᮡ-ᮭ᯦-᯳ᰤ-᰷᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰℘℮⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣠-꣱ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀ꧥꨩ-ꨶꩃꩌꩍꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ︀-️︠-︯︳︴﹍-﹏_𐇽𐋠𐍶-𐍺𐨁-𐨃𐨅𐨆𐨌-𐨏𐨸-𐨿𐨺𐫦𐫥𑀀-𑀂𑀸-𑁆𑁿-𑂂𑂰-𑂺𑄀-𑄂𑄧-𑅳𑄴𑆀-𑆂𑆳-𑇊𑇀-𑇌𑈬-𑈷𑈾𑋟-𑋪𑌀-𑌃𑌼𑌾-𑍄𑍇𑍈𑍋-𑍍𑍗𑍢𑍣𑍦-𑍬𑍰-𑍴𑐵-𑑆𑒰-𑓃𑖯-𑖵𑖸-𑗀𑗜𑗝𑘰-𑙀𑚫-𑚷𑜝-𑜫𑰯-𑰶𑰸-𑰿𑲒-𑲧𑲩-𑲶𖫰-𖫴𖬰-𖬶𖽑-𖽾𖾏-𖾒𛲝𛲞𝅥-𝅩𝅭-𝅲𝅻-𝆂𝆅-𝆋𝆪-𝆭𝉂-𝉄𝨀-𝨶𝨻-𝩬𝩵𝪄𝪛-𝪟𝪡-𝪯𞀀-𞀆𞀈-𞀘𞀛-𞀡𞀣𞀤𞀦-𞣐𞀪-𞣖𞥄-𞥊󠄀-󠇯" # noqa: B950
diff --git a/src/jinja2/asyncfilters.py b/src/jinja2/asyncfilters.py
index 451d3f8..d29f6c6 100644
--- a/src/jinja2/asyncfilters.py
+++ b/src/jinja2/asyncfilters.py
@@ -27,14 +27,19 @@ async def async_select_or_reject(args, kwargs, modfunc, lookup_attr):
def dualfilter(normal_filter, async_filter):
wrap_evalctx = False
if getattr(normal_filter, "environmentfilter", False):
- is_async = lambda args: args[0].is_async
+
+ def is_async(args):
+ return args[0].is_async
+
wrap_evalctx = False
else:
if not getattr(normal_filter, "evalcontextfilter", False) and not getattr(
normal_filter, "contextfilter", False
):
wrap_evalctx = True
- is_async = lambda args: args[0].environment.is_async
+
+ def is_async(args):
+ return args[0].environment.is_async
@wraps(normal_filter)
def wrapper(*args, **kwargs):
@@ -123,7 +128,10 @@ async def do_sum(environment, iterable, attribute=None, start=0):
if attribute is not None:
func = filters.make_attrgetter(environment, attribute)
else:
- func = lambda x: x
+
+ def func(x):
+ return x
+
async for item in auto_aiter(iterable):
rv += func(item)
return rv
diff --git a/src/jinja2/bccache.py b/src/jinja2/bccache.py
index c2b877e..75419d1 100644
--- a/src/jinja2/bccache.py
+++ b/src/jinja2/bccache.py
@@ -16,7 +16,6 @@
"""
import errno
import fnmatch
-import marshal
import os
import stat
import sys
@@ -26,29 +25,12 @@ from os import listdir
from os import path
from ._compat import BytesIO
+from ._compat import marshal_dump
+from ._compat import marshal_load
from ._compat import pickle
-from ._compat import PY2
from ._compat import text_type
from .utils import open_if_exists
-# marshal works better on 3.x, one hack less required
-if not PY2:
- marshal_dump = marshal.dump
- marshal_load = marshal.load
-else:
-
- def marshal_dump(code, f):
- if isinstance(f, file):
- marshal.dump(code, f)
- else:
- f.write(marshal.dumps(code))
-
- def marshal_load(f):
- if isinstance(f, file):
- return marshal.load(f)
- return marshal.loads(f.read())
-
-
bc_version = 3
# magic version used to only change with new jinja versions. With 2.6
diff --git a/src/jinja2/compiler.py b/src/jinja2/compiler.py
index 324bc0f..068ad56 100644
--- a/src/jinja2/compiler.py
+++ b/src/jinja2/compiler.py
@@ -549,10 +549,10 @@ class CodeGenerator(NodeVisitor):
else:
args.append(frame.symbols.declare_parameter("caller"))
macro_ref.accesses_caller = True
- if "kwargs" in undeclared and not "kwargs" in skip_special_params:
+ if "kwargs" in undeclared and "kwargs" not in skip_special_params:
args.append(frame.symbols.declare_parameter("kwargs"))
macro_ref.accesses_kwargs = True
- if "varargs" in undeclared and not "varargs" in skip_special_params:
+ if "varargs" in undeclared and "varargs" not in skip_special_params:
args.append(frame.symbols.declare_parameter("varargs"))
macro_ref.accesses_varargs = True
@@ -1242,7 +1242,6 @@ class CodeGenerator(NodeVisitor):
if frame.toplevel:
if not node.name.startswith("_"):
self.write("context.exported_vars.add(%r)" % node.name)
- ref = frame.symbols.ref(node.name)
self.writeline("context.vars[%r] = " % node.name)
self.write("%s = " % frame.symbols.ref(node.name))
self.macro_def(macro_ref, macro_frame)
@@ -1270,7 +1269,7 @@ class CodeGenerator(NodeVisitor):
with_frame = frame.inner()
with_frame.symbols.analyze_node(node)
self.enter_frame(with_frame)
- for idx, (target, expr) in enumerate(izip(node.targets, node.values)):
+ for target, expr in izip(node.targets, node.values):
self.newline()
self.visit(target, with_frame)
self.write(" = ")
@@ -1317,7 +1316,7 @@ class CodeGenerator(NodeVisitor):
if getattr(env_finalize, "contextfunction", False):
src += "context, "
- finalize = None
+ finalize = None # noqa: F811
elif getattr(env_finalize, "evalcontextfunction", False):
src += "context.eval_ctx, "
finalize = None
@@ -1570,7 +1569,7 @@ class CodeGenerator(NodeVisitor):
self.visit(item.value, frame)
self.write("}")
- def binop(operator, interceptable=True):
+ def binop(operator, interceptable=True): # noqa: B902
@optimizeconst
def visitor(self, node, frame):
if (
@@ -1590,7 +1589,7 @@ class CodeGenerator(NodeVisitor):
return visitor
- def uaop(operator, interceptable=True):
+ def uaop(operator, interceptable=True): # noqa: B902
@optimizeconst
def visitor(self, node, frame):
if (
diff --git a/src/jinja2/debug.py b/src/jinja2/debug.py
index bb36609..d2c5a06 100644
--- a/src/jinja2/debug.py
+++ b/src/jinja2/debug.py
@@ -160,7 +160,7 @@ def fake_traceback(exc_value, tb, filename, lineno):
# the new traceback without this frame.
try:
exec(code, globals, locals)
- except:
+ except BaseException:
return sys.exc_info()[2].tb_next
diff --git a/src/jinja2/defaults.py b/src/jinja2/defaults.py
index 8ee52bb..0af8c54 100644
--- a/src/jinja2/defaults.py
+++ b/src/jinja2/defaults.py
@@ -9,6 +9,8 @@
:license: BSD, see LICENSE for more details.
"""
from ._compat import range_type
+from .filters import FILTERS as DEFAULT_FILTERS # noqa: F401
+from .tests import TESTS as DEFAULT_TESTS # noqa: F401
from .utils import Cycler
from .utils import generate_lorem_ipsum
from .utils import Joiner
@@ -29,8 +31,6 @@ NEWLINE_SEQUENCE = "\n"
KEEP_TRAILING_NEWLINE = False
# default filters, tests and namespace
-from jinja2.filters import FILTERS as DEFAULT_FILTERS
-from jinja2.tests import TESTS as DEFAULT_TESTS
DEFAULT_NAMESPACE = {
"range": range_type,
diff --git a/src/jinja2/environment.py b/src/jinja2/environment.py
index 7c4d26a..d332831 100644
--- a/src/jinja2/environment.py
+++ b/src/jinja2/environment.py
@@ -16,8 +16,6 @@ from functools import reduce
from . import nodes
from ._compat import encode_filename
-from ._compat import ifilter
-from ._compat import imap
from ._compat import implements_iterator
from ._compat import implements_to_string
from ._compat import iteritems
@@ -368,7 +366,8 @@ class Environment(object):
self.enable_async = enable_async
self.is_async = self.enable_async and have_async_gen
if self.is_async:
- import jinja2.asyncsupport # runs patch_all() once
+ # runs patch_all() to enable async support
+ import jinja2.asyncsupport # noqa: F401
_environment_sanity_check(self)
@@ -722,7 +721,9 @@ class Environment(object):
from jinja2.loaders import ModuleLoader
if log_function is None:
- log_function = lambda x: None
+
+ def log_function(x):
+ pass
if py_compile:
if not PY2 or PYPY:
@@ -806,16 +807,21 @@ class Environment(object):
.. versionadded:: 2.4
"""
- x = self.loader.list_templates()
+ names = self.loader.list_templates()
+
if extensions is not None:
if filter_func is not None:
raise TypeError(
"either extensions or filter_func can be passed, but not both"
)
- filter_func = lambda x: "." in x and x.rsplit(".", 1)[1] in extensions
+
+ def filter_func(x):
+ return "." in x and x.rsplit(".", 1)[1] in extensions
+
if filter_func is not None:
- x = list(ifilter(filter_func, x))
- return x
+ names = [name for name in names if filter_func(name)]
+
+ return names
def handle_exception(self, source=None):
"""Exception handling helper. This is used internally to either raise
@@ -1202,7 +1208,7 @@ class Template(object):
def debug_info(self):
"""The debug info mapping."""
if self._debug_info:
- return [tuple(imap(int, x.split("="))) for x in self._debug_info.split("&")]
+ return [tuple(map(int, x.split("="))) for x in self._debug_info.split("&")]
return []
def __repr__(self):
diff --git a/src/jinja2/ext.py b/src/jinja2/ext.py
index 4891c9c..b231071 100644
--- a/src/jinja2/ext.py
+++ b/src/jinja2/ext.py
@@ -48,12 +48,14 @@ from .utils import Markup
# non unicode strings.
GETTEXT_FUNCTIONS = ("_", "gettext", "ngettext")
+_ws_re = re.compile(r"\s*\n\s*")
+
class ExtensionRegistry(type):
"""Gives the extension an unique identifier."""
- def __new__(cls, name, bases, d):
- rv = type.__new__(cls, name, bases, d)
+ def __new__(mcs, name, bases, d):
+ rv = type.__new__(mcs, name, bases, d)
rv.identifier = rv.__module__ + "." + rv.__name__
return rv
@@ -356,7 +358,7 @@ class InternationalizationExtension(Extension):
else:
return node
- def _trim_whitespace(self, string, _ws_re=re.compile(r"\s*\n\s*")):
+ def _trim_whitespace(self, string, _ws_re=_ws_re):
return _ws_re.sub(" ", string.strip())
def _parse_block(self, parser, allow_pluralize):
@@ -389,7 +391,7 @@ class InternationalizationExtension(Extension):
elif parser.stream.eos:
parser.fail("unclosed translation block")
else:
- assert False, "internal parser error"
+ raise RuntimeError("internal parser error")
return referenced, concat(buf)
@@ -574,7 +576,7 @@ def extract_from_ast(node, gettext_functions=GETTEXT_FUNCTIONS, babel_style=True
else:
strings.append(None)
- for arg in node.kwargs:
+ for _ in node.kwargs:
strings.append(None)
if node.dyn_args is not None:
strings.append(None)
@@ -699,7 +701,7 @@ def babel_extract(fileobj, keywords, comment_tags, options):
try:
node = environment.parse(source)
tokens = list(environment.lex(environment.preprocess(source)))
- except TemplateSyntaxError as e:
+ except TemplateSyntaxError:
if not silent:
raise
# skip templates with syntax errors
diff --git a/src/jinja2/filters.py b/src/jinja2/filters.py
index c7a2f39..79394ad 100644
--- a/src/jinja2/filters.py
+++ b/src/jinja2/filters.py
@@ -328,7 +328,8 @@ def do_sort(environment, value, reverse=False, case_sensitive=False, attribute=N
.. sourcecode:: jinja
- {% for user in users|sort(attribute="name")|sort(reverse=true, attribute="age") %}
+ {% for user in users|sort(attribute="name")
+ |sort(reverse=true, attribute="age") %}
...
{% endfor %}
@@ -523,7 +524,8 @@ def do_last(environment, seq):
"""
Return the last item of a sequence.
- Note: Does not work with generators. You may want to explicitly convert it to a list:
+ Note: Does not work with generators. You may want to explicitly
+ convert it to a list:
.. sourcecode:: jinja
@@ -931,7 +933,7 @@ def do_round(value, precision=0, method="common"):
{{ 42.55|round|int }}
-> 43
"""
- if not method in ("common", "ceil", "floor"):
+ if method not in {"common", "ceil", "floor"}:
raise FilterArgumentError("method must be common, ceil or floor")
if method == "common":
return round(value, precision)
@@ -1282,9 +1284,11 @@ def prepare_map(args, kwargs):
args = args[3:]
except LookupError:
raise FilterArgumentError("map requires a filter argument")
- func = lambda item: context.environment.call_filter(
- name, item, args, kwargs, context=context
- )
+
+ def func(item):
+ return context.environment.call_filter(
+ name, item, args, kwargs, context=context
+ )
return seq, func
@@ -1301,12 +1305,17 @@ def prepare_select_or_reject(args, kwargs, modfunc, lookup_attr):
off = 1
else:
off = 0
- transfunc = lambda x: x
+
+ def transfunc(x):
+ return x
try:
name = args[2 + off]
args = args[3 + off :]
- func = lambda item: context.environment.call_test(name, item, args, kwargs)
+
+ def func(item):
+ return context.environment.call_test(name, item, args, kwargs)
+
except LookupError:
func = bool
diff --git a/src/jinja2/lexer.py b/src/jinja2/lexer.py
index 1bac2d6..a9585ef 100644
--- a/src/jinja2/lexer.py
+++ b/src/jinja2/lexer.py
@@ -379,7 +379,7 @@ class TokenStream(object):
def skip(self, n=1):
"""Got n tokens ahead."""
- for x in range(n):
+ for _ in range(n):
next(self)
def next_if(self, expr):
@@ -485,9 +485,11 @@ class Lexer(object):
def __init__(self, environment):
# shortcuts
- c = lambda x: re.compile(x, re.M | re.S)
e = re.escape
+ def c(x):
+ return re.compile(x, re.M | re.S)
+
# lexing rules for tags
tag_rules = [
(whitespace_re, TOKEN_WHITESPACE, None),
diff --git a/src/jinja2/loaders.py b/src/jinja2/loaders.py
index fa91a73..99798fd 100644
--- a/src/jinja2/loaders.py
+++ b/src/jinja2/loaders.py
@@ -208,7 +208,7 @@ class FileSystemLoader(BaseLoader):
found = set()
for searchpath in self.searchpath:
walk_dir = os.walk(searchpath, followlinks=self.followlinks)
- for dirpath, dirnames, filenames in walk_dir:
+ for dirpath, _, filenames in walk_dir:
for filename in filenames:
template = (
os.path.join(dirpath, filename)[len(searchpath) :]
diff --git a/src/jinja2/nodes.py b/src/jinja2/nodes.py
index 65b2599..8026543 100644
--- a/src/jinja2/nodes.py
+++ b/src/jinja2/nodes.py
@@ -54,7 +54,7 @@ class NodeType(type):
inheritance. fields and attributes from the parent class are
automatically forwarded to the child."""
- def __new__(cls, name, bases, d):
+ def __new__(mcs, name, bases, d):
for attr in "fields", "attributes":
storage = []
storage.extend(getattr(bases[0], attr, ()))
@@ -63,7 +63,7 @@ class NodeType(type):
assert len(storage) == len(set(storage)), "layout conflict"
d[attr] = tuple(storage)
d.setdefault("abstract", False)
- return type.__new__(cls, name, bases, d)
+ return type.__new__(mcs, name, bases, d)
class EvalContext(object):
@@ -165,7 +165,7 @@ class Node(with_metaclass(NodeType, object)):
over all fields and yields the values of they are nodes. If the value
of a field is a list all the nodes in that list are returned.
"""
- for field, item in self.iter_fields(exclude, only):
+ for _, item in self.iter_fields(exclude, only):
if isinstance(item, list):
for n in item:
if isinstance(n, Node):
diff --git a/src/jinja2/parser.py b/src/jinja2/parser.py
index 648c3fd..1d9fd91 100644
--- a/src/jinja2/parser.py
+++ b/src/jinja2/parser.py
@@ -245,7 +245,6 @@ class Parser(object):
targets = []
values = []
while self.stream.current.type != "block_end":
- lineno = self.stream.current.lineno
if targets:
self.stream.expect("comma")
target = self.parse_assign_target()
@@ -639,7 +638,10 @@ class Parser(object):
elif with_condexpr:
parse = self.parse_expression
else:
- parse = lambda: self.parse_expression(with_condexpr=False)
+
+ def parse():
+ return self.parse_expression(with_condexpr=False)
+
args = []
is_tuple = False
while 1:
diff --git a/src/jinja2/runtime.py b/src/jinja2/runtime.py
index 9f4f224..365c1f7 100644
--- a/src/jinja2/runtime.py
+++ b/src/jinja2/runtime.py
@@ -12,6 +12,10 @@ import sys
from itertools import chain
from types import MethodType
+from markupsafe import escape
+from markupsafe import Markup
+from markupsafe import soft_unicode
+
from ._compat import abc
from ._compat import imap
from ._compat import implements_iterator
@@ -26,14 +30,11 @@ from .exceptions import TemplateRuntimeError
from .exceptions import UndefinedError
from .nodes import EvalContext
from .utils import concat
-from .utils import escape
from .utils import evalcontextfunction
from .utils import internalcode
-from .utils import Markup
from .utils import missing
from .utils import Namespace
from .utils import object_type_repr
-from .utils import soft_unicode
# these variables are exported to the template runtime
__all__ = [
@@ -58,11 +59,12 @@ __all__ = [
#: a string. We can just use the text type here.
to_string = text_type
-#: the identity function. Useful for certain things in the environment
-identity = lambda x: x
-_first_iteration = object()
-_last_iteration = object()
+def identity(x):
+ """Returns its argument. Useful for certain things in the
+ environment.
+ """
+ return x
def markup_join(seq):
@@ -127,8 +129,8 @@ def _get_func(x):
class ContextMeta(type):
- def __new__(cls, name, bases, d):
- rv = type.__new__(cls, name, bases, d)
+ def __new__(mcs, name, bases, d):
+ rv = type.__new__(mcs, name, bases, d)
if bases == ():
return rv
@@ -264,7 +266,7 @@ class Context(with_metaclass(ContextMeta)):
return dict(self.parent, **self.vars)
@internalcode
- def call(__self, __obj, *args, **kwargs):
+ def call(__self, __obj, *args, **kwargs): # noqa: B902
"""Call the callable with the arguments and keyword arguments
provided but inject the active context or environment as first
argument if the callable is a :func:`contextfunction` or
@@ -274,7 +276,7 @@ class Context(with_metaclass(ContextMeta)):
__traceback_hide__ = True # noqa
# Allow callable classes to take a context
- if hasattr(__obj, "__call__"):
+ if hasattr(__obj, "__call__"): # noqa: B004
fn = __obj.__call__
for fn_type in (
"contextfunction",
@@ -313,8 +315,10 @@ class Context(with_metaclass(ContextMeta)):
context.blocks.update((k, list(v)) for k, v in iteritems(self.blocks))
return context
- def _all(meth):
- proxy = lambda self: getattr(self.get_all(), meth)()
+ def _all(meth): # noqa: B902
+ def proxy(self):
+ return getattr(self.get_all(), meth)()
+
proxy.__doc__ = getattr(dict, meth).__doc__
proxy.__name__ = meth
return proxy
@@ -635,7 +639,7 @@ class Macro(object):
# arguments expected we start filling in keyword arguments
# and defaults.
if off != self._argument_count:
- for idx, name in enumerate(self.arguments[len(arguments) :]):
+ for name in self.arguments[len(arguments) :]:
try:
value = kwargs.pop(name)
except KeyError:
diff --git a/src/jinja2/sandbox.py b/src/jinja2/sandbox.py
index ad87997..bf4a0f6 100644
--- a/src/jinja2/sandbox.py
+++ b/src/jinja2/sandbox.py
@@ -14,6 +14,8 @@
"""
import operator
import types
+import warnings
+from collections import deque
from string import Formatter
from markupsafe import EscapeFormatter
@@ -31,36 +33,35 @@ MAX_RANGE = 100000
#: attributes of function objects that are considered unsafe.
if PY2:
- UNSAFE_FUNCTION_ATTRIBUTES = set(
- ["func_closure", "func_code", "func_dict", "func_defaults", "func_globals"]
- )
+ UNSAFE_FUNCTION_ATTRIBUTES = {
+ "func_closure",
+ "func_code",
+ "func_dict",
+ "func_defaults",
+ "func_globals",
+ }
else:
# On versions > python 2 the special attributes on functions are gone,
# but they remain on methods and generators for whatever reason.
UNSAFE_FUNCTION_ATTRIBUTES = set()
-
#: unsafe method attributes. function attributes are unsafe for methods too
-UNSAFE_METHOD_ATTRIBUTES = set(["im_class", "im_func", "im_self"])
+UNSAFE_METHOD_ATTRIBUTES = {"im_class", "im_func", "im_self"}
#: unsafe generator attributes.
-UNSAFE_GENERATOR_ATTRIBUTES = set(["gi_frame", "gi_code"])
+UNSAFE_GENERATOR_ATTRIBUTES = {"gi_frame", "gi_code"}
#: unsafe attributes on coroutines
-UNSAFE_COROUTINE_ATTRIBUTES = set(["cr_frame", "cr_code"])
+UNSAFE_COROUTINE_ATTRIBUTES = {"cr_frame", "cr_code"}
#: unsafe attributes on async generators
-UNSAFE_ASYNC_GENERATOR_ATTRIBUTES = set(["ag_code", "ag_frame"])
-
-import warnings
+UNSAFE_ASYNC_GENERATOR_ATTRIBUTES = {"ag_code", "ag_frame"}
# make sure we don't warn in python 2.6 about stuff we don't care about
warnings.filterwarnings(
"ignore", "the sets module", DeprecationWarning, module="jinja2.sandbox"
)
-from collections import deque
-
_mutable_set_types = (set,)
_mutable_mapping_types = (dict,)
_mutable_sequence_types = (list,)
@@ -89,7 +90,6 @@ _mutable_set_types += (abc.MutableSet,)
_mutable_mapping_types += (abc.MutableMapping,)
_mutable_sequence_types += (abc.MutableSequence,)
-
_mutable_spec = (
(
_mutable_set_types,
@@ -460,7 +460,7 @@ class SandboxedEnvironment(Environment):
rv = formatter.vformat(s, args, kwargs)
return type(s)(rv)
- def call(__self, __context, __obj, *args, **kwargs):
+ def call(__self, __context, __obj, *args, **kwargs): # noqa: B902
"""Call an object from sandboxed code."""
fmt = inspect_format_method(__obj)
if fmt is not None:
diff --git a/src/jinja2/tests.py b/src/jinja2/tests.py
index 3eea947..8c4d466 100644
--- a/src/jinja2/tests.py
+++ b/src/jinja2/tests.py
@@ -142,7 +142,7 @@ def test_sequence(value):
try:
len(value)
value.__getitem__
- except:
+ except Exception:
return False
return True
diff --git a/src/jinja2/utils.py b/src/jinja2/utils.py
index c051f30..e429428 100644
--- a/src/jinja2/utils.py
+++ b/src/jinja2/utils.py
@@ -15,6 +15,9 @@ import warnings
from collections import deque
from threading import Lock
+from markupsafe import escape
+from markupsafe import Markup
+
from ._compat import abc
from ._compat import string_types
from ._compat import text_type
@@ -109,7 +112,7 @@ def is_undefined(obj):
def consume(iterable):
"""Consumes an iterable without doing anything with it."""
- for event in iterable:
+ for _ in iterable:
pass
@@ -246,7 +249,7 @@ def urlize(text, trim_url_limit=None, rel=None, target=None):
if (
"@" in middle
and not middle.startswith("www.")
- and not ":" in middle
+ and ":" not in middle
and _simple_email_re.match(middle)
):
middle = '<a href="mailto:%s">%s</a>' % (middle, middle)
@@ -472,6 +475,12 @@ class LRUCache(object):
def iteritems(self):
"""Iterate over all items."""
+ warnings.warn(
+ "'iteritems()' will be removed in version 3.0. Use"
+ " 'iter(cache.items())' instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
return iter(self.items())
def values(self):
@@ -481,16 +490,21 @@ class LRUCache(object):
def itervalue(self):
"""Iterate over all values."""
warnings.warn(
- DeprecationWarning(
- '"itervalue()" is deprecated and will be removed in version 2.12.'
- + ' Use "itervalues()" instead.'
- ),
+ "'itervalue()' will be removed in version 3.0. Use"
+ " 'iter(cache.values())' instead.",
+ DeprecationWarning,
stacklevel=2,
)
- return self.itervalues()
+ return iter(self.values())
def itervalues(self):
"""Iterate over all values."""
+ warnings.warn(
+ "'itervalues()' will be removed in version 3.0. Use"
+ " 'iter(cache.values())' instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
return iter(self.values())
def keys(self):
@@ -501,9 +515,16 @@ class LRUCache(object):
"""Iterate over all keys in the cache dict, ordered by
the most recent usage.
"""
- return reversed(tuple(self._queue))
+ warnings.warn(
+ "'iterkeys()' will be removed in version 3.0. Use"
+ " 'iter(cache.keys())' instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return iter(self)
- __iter__ = iterkeys
+ def __iter__(self):
+ return reversed(tuple(self._queue))
def __reversed__(self):
"""Iterate over the keys in the cache dict, oldest items
@@ -675,7 +696,7 @@ class Namespace(object):
"""A namespace object that can hold arbitrary attributes. It may be
initialized from a dictionary or with keyword arguments."""
- def __init__(*args, **kwargs):
+ def __init__(*args, **kwargs): # noqa: B902
self, args = args[0], args[1:]
self.__attrs = dict(*args, **kwargs)
@@ -702,5 +723,13 @@ except SyntaxError:
have_async_gen = False
-# Imported here because that's where it was in the past
-from markupsafe import Markup, escape, soft_unicode
+def soft_unicode(s):
+ from markupsafe import soft_unicode
+
+ warnings.warn(
+ "'jinja2.utils.soft_unicode' will be removed in version 3.0."
+ " Use 'markupsafe.soft_unicode' instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return soft_unicode(s)
diff --git a/tests/test_api.py b/tests/test_api.py
index a0c546c..a9eddbe 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -105,17 +105,6 @@ class TestExtendedAPI(object):
c.reset()
assert c.current == 1
- def test_cycler_nextmethod(self, env):
- items = 1, 2, 3
- c = Cycler(*items)
- for item in items + items:
- assert c.current == item
- assert c.next() == item
- c.next()
- assert c.current == 2
- c.reset()
- assert c.current == 1
-
def test_expressions(self, env):
expr = env.compile_expression("foo")
assert expr() is None
@@ -338,7 +327,7 @@ class TestUndefined(object):
assert und1 != 42
assert hash(und1) == hash(und2) == hash(Undefined())
with pytest.raises(AttributeError):
- getattr(Undefined, "__slots__")
+ getattr(Undefined, "__slots__") # noqa: B009
def test_chainable_undefined(self):
env = Environment(undefined=ChainableUndefined)
@@ -350,7 +339,7 @@ class TestUndefined(object):
assert env.from_string("{{ not missing }}").render() == "True"
pytest.raises(UndefinedError, env.from_string("{{ missing - 1}}").render)
with pytest.raises(AttributeError):
- getattr(ChainableUndefined, "__slots__")
+ getattr(ChainableUndefined, "__slots__") # noqa: B009
# The following tests ensure subclass functionality works as expected
assert env.from_string('{{ missing.bar["baz"] }}').render() == u""
@@ -385,7 +374,7 @@ class TestUndefined(object):
== u"{{ undefined value printed: %s }}" % undefined_hint
)
with pytest.raises(AttributeError):
- getattr(DebugUndefined, "__slots__")
+ getattr(DebugUndefined, "__slots__") # noqa: B009
def test_strict_undefined(self):
env = Environment(undefined=StrictUndefined)
@@ -402,7 +391,7 @@ class TestUndefined(object):
== "default"
)
with pytest.raises(AttributeError):
- getattr(StrictUndefined, "__slots__")
+ getattr(StrictUndefined, "__slots__") # noqa: B009
assert env.from_string('{{ "foo" if false }}').render() == ""
def test_indexing_gives_undefined(self):
diff --git a/tests/test_async.py b/tests/test_async.py
index bae73c6..f7e2792 100644
--- a/tests/test_async.py
+++ b/tests/test_async.py
@@ -396,9 +396,8 @@ class TestAsyncForLoop(object):
def test_recursive_depth0(self, test_env_async):
tmpl = test_env_async.from_string(
- """{% for item in seq recursive -%}
- [{{ loop.depth0 }}:{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
- {%- endfor %}"""
+ "{% for item in seq recursive %}[{{ loop.depth0 }}:{{ item.a }}"
+ "{% if item.b %}<{{ loop(item.b) }}>{% endif %}]{% endfor %}"
)
assert (
tmpl.render(
@@ -413,9 +412,8 @@ class TestAsyncForLoop(object):
def test_recursive_depth(self, test_env_async):
tmpl = test_env_async.from_string(
- """{% for item in seq recursive -%}
- [{{ loop.depth }}:{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
- {%- endfor %}"""
+ "{% for item in seq recursive %}[{{ loop.depth }}:{{ item.a }}"
+ "{% if item.b %}<{{ loop(item.b) }}>{% endif %}]{% endfor %}"
)
assert (
tmpl.render(
@@ -544,9 +542,7 @@ class TestAsyncForLoop(object):
)
sm = t.render(
this="/foo",
- site={
- "root": {"url": "/", "children": [{"url": "/foo"}, {"url": "/bar"},]}
- },
+ site={"root": {"url": "/", "children": [{"url": "/foo"}, {"url": "/bar"}]}},
)
lines = [x.strip() for x in sm.splitlines() if x.strip()]
assert lines == [
@@ -569,7 +565,7 @@ class TestAsyncForLoop(object):
"""
)
sm = t.render(
- this="/foo", items=[{"url": "/"}, {"url": "/foo"}, {"url": "/bar"},]
+ this="/foo", items=[{"url": "/"}, {"url": "/foo"}, {"url": "/bar"}]
)
lines = [x.strip() for x in sm.splitlines() if x.strip()]
assert lines == [
diff --git a/tests/test_asyncfilters.py b/tests/test_asyncfilters.py
index 23a1001..7c737c8 100644
--- a/tests/test_asyncfilters.py
+++ b/tests/test_asyncfilters.py
@@ -1,3 +1,5 @@
+from collections import namedtuple
+
import pytest
from jinja2 import Environment
@@ -12,7 +14,7 @@ async def make_aiter(iter):
def mark_dualiter(parameter, factory):
def decorator(f):
return pytest.mark.parametrize(
- parameter, [lambda: factory(), lambda: make_aiter(factory()),]
+ parameter, [lambda: factory(), lambda: make_aiter(factory())]
)(f)
return decorator
@@ -66,22 +68,13 @@ def test_groupby_tuple_index(env_async, items):
def make_articles():
- class Date(object):
- def __init__(self, day, month, year):
- self.day = day
- self.month = month
- self.year = year
-
- class Article(object):
- def __init__(self, title, *date):
- self.date = Date(*date)
- self.title = title
-
+ Date = namedtuple("Date", "day,month,year")
+ Article = namedtuple("Article", "title,date")
return [
- Article("aha", 1, 1, 1970),
- Article("interesting", 2, 1, 1970),
- Article("really?", 3, 1, 1970),
- Article("totally not", 1, 1, 1971),
+ Article("aha", Date(1, 1, 1970)),
+ Article("interesting", Date(2, 1, 1970)),
+ Article("really?", Date(3, 1, 1970)),
+ Article("totally not", Date(1, 1, 1971)),
]
@@ -115,10 +108,7 @@ def test_join_string_list(string_items):
def make_users():
- class User(object):
- def __init__(self, username):
- self.username = username
-
+ User = namedtuple("User", "username")
return map(User, ["foo", "bar"])
@@ -153,11 +143,7 @@ def test_bool_select(env_async, items):
def make_users():
- class User(object):
- def __init__(self, name, is_active):
- self.name = name
- self.is_active = is_active
-
+ User = namedtuple("User", "name,is_active")
return [
User("john", True),
User("jane", True),
@@ -201,7 +187,7 @@ def test_sum(env_async, items):
assert tmpl.render(items=items) == "21"
-@mark_dualiter("items", lambda: [{"value": 23}, {"value": 1}, {"value": 18},])
+@mark_dualiter("items", lambda: [{"value": 23}, {"value": 1}, {"value": 18}])
def test_sum_attributes(env_async, items):
tmpl = env_async.from_string("""{{ items()|sum('value') }}""")
assert tmpl.render(items=items)
@@ -223,13 +209,13 @@ def test_sum_attributes_nested(env_async):
def test_sum_attributes_tuple(env_async):
tmpl = env_async.from_string("""{{ values.items()|sum('1') }}""")
- assert tmpl.render(values={"foo": 23, "bar": 1, "baz": 18,}) == "42"
+ assert tmpl.render(values={"foo": 23, "bar": 1, "baz": 18}) == "42"
@mark_dualiter("items", lambda: range(10))
def test_slice(env_async, items):
tmpl = env_async.from_string(
- "{{ items()|slice(3)|list }}|" '{{ items()|slice(3, "X")|list }}'
+ "{{ items()|slice(3)|list }}|{{ items()|slice(3, 'X')|list }}"
)
out = tmpl.render(items=items)
assert out == (
diff --git a/tests/test_core_tags.py b/tests/test_core_tags.py
index deb0169..0f9346b 100644
--- a/tests/test_core_tags.py
+++ b/tests/test_core_tags.py
@@ -163,7 +163,7 @@ class TestForLoop(object):
def test_recursive_depth0(self, env):
tmpl = env.from_string(
"""{% for item in seq recursive -%}
- [{{ loop.depth0 }}:{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
+ [{{ loop.depth0 }}:{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
{%- endfor %}"""
)
assert (
@@ -180,7 +180,7 @@ class TestForLoop(object):
def test_recursive_depth(self, env):
tmpl = env.from_string(
"""{% for item in seq recursive -%}
- [{{ loop.depth }}:{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
+ [{{ loop.depth }}:{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
{%- endfor %}"""
)
assert (
@@ -513,15 +513,13 @@ class TestSet(object):
assert "non-namespace object" in exc_info.value.message
def test_namespace_redefined(self, env_trim):
- tmpl = env_trim.from_string(
- "{% set ns = namespace() %}" '{% set ns.bar = "hi" %}'
- )
+ tmpl = env_trim.from_string("{% set ns = namespace() %}{% set ns.bar = 'hi' %}")
exc_info = pytest.raises(TemplateRuntimeError, tmpl.render, namespace=dict)
assert "non-namespace object" in exc_info.value.message
def test_namespace(self, env_trim):
tmpl = env_trim.from_string(
- "{% set ns = namespace() %}" '{% set ns.bar = "42" %}' "{{ ns.bar }}"
+ "{% set ns = namespace() %}{% set ns.bar = '42' %}{{ ns.bar }}"
)
assert tmpl.render() == "42"
diff --git a/tests/test_debug.py b/tests/test_debug.py
index e19a540..7dbad31 100644
--- a/tests/test_debug.py
+++ b/tests/test_debug.py
@@ -10,7 +10,6 @@
"""
import pickle
import re
-import sys
from traceback import format_exception
import pytest
@@ -30,17 +29,15 @@ def fs_env(filesystem_loader):
@pytest.mark.debug
class TestDebug(object):
def assert_traceback_matches(self, callback, expected_tb):
- try:
+ with pytest.raises(Exception) as exc_info:
callback()
- except Exception:
- tb = format_exception(*sys.exc_info())
- if re.search(expected_tb.strip(), "".join(tb)) is None:
- assert False, "Traceback did not match:\n\n%s\nexpected:\n%s" % (
- "".join(tb),
- expected_tb,
- )
- else:
- assert False, "Expected exception"
+
+ tb = format_exception(exc_info.type, exc_info.value, exc_info.tb)
+ m = re.search(expected_tb.strip(), "".join(tb))
+ assert m is not None, "Traceback did not match:\n\n%s\nexpected:\n%s" % (
+ "".join(tb),
+ expected_tb,
+ )
def test_runtime_error(self, fs_env):
def test():
@@ -64,10 +61,12 @@ ZeroDivisionError: (int(eger)? )?division (or modulo )?by zero
# error in the middle of other compiler frames.
self.assert_traceback_matches(
lambda: fs_env.get_template("syntaxerror.html"),
- r"""(?sm)
+ """(?sm)
File ".*?syntaxerror.html", line 4, in (template|<module>)
- \{% endif %\}.*?
-(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'.
+ \\{% endif %\\}.*?
+(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'.
""",
)
diff --git a/tests/test_ext.py b/tests/test_ext.py
index 0a9b648..6ecf9a2 100644
--- a/tests/test_ext.py
+++ b/tests/test_ext.py
@@ -343,7 +343,7 @@ class TestInternationalization(object):
# unlikely variable name, but when used as a variable
# it should not enable trimming
tmpl = i18n_env.from_string(
- '{%- trans trimmed = "world" %} hello\n {{ trimmed }} ' "{% endtrans -%}"
+ "{%- trans trimmed = 'world' %} hello\n {{ trimmed }} {% endtrans -%}"
)
assert tmpl.render() == " hello\n world "
diff --git a/tests/test_features.py b/tests/test_features.py
index 0d7baed..34b6f20 100644
--- a/tests/test_features.py
+++ b/tests/test_features.py
@@ -5,6 +5,7 @@ import pytest
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")
@@ -29,7 +30,7 @@ def test_ascii_str():
env.policies["compiler.ascii_str"] = False
t = env.from_string('{{ "foo"|assert }}')
- t.render(expected_type=unicode)
+ t.render(expected_type=text_type)
env.policies["compiler.ascii_str"] = True
t = env.from_string('{{ "foo"|assert }}')
@@ -38,4 +39,4 @@ def test_ascii_str():
for val in True, False:
env.policies["compiler.ascii_str"] = val
t = env.from_string(u'{{ "\N{SNOWMAN}"|assert }}')
- t.render(expected_type=unicode)
+ t.render(expected_type=text_type)
diff --git a/tests/test_filters.py b/tests/test_filters.py
index 3f74c27..ae10eb5 100644
--- a/tests/test_filters.py
+++ b/tests/test_filters.py
@@ -9,6 +9,7 @@
:license: BSD, see LICENSE for more details.
"""
import random
+from collections import namedtuple
import pytest
@@ -81,9 +82,7 @@ class TestFilter(object):
)
def test_slice(self, env):
- tmpl = env.from_string(
- "{{ foo|slice(3)|list }}|" '{{ foo|slice(3, "X")|list }}'
- )
+ tmpl = env.from_string("{{ foo|slice(3)|list }}|{{ foo|slice(3, 'X')|list }}")
out = tmpl.render(foo=list(range(10)))
assert out == (
"[[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]|"
@@ -244,10 +243,7 @@ class TestFilter(object):
assert tmpl.render() == "&lt;foo&gt;<span>foo</span>"
def test_join_attribute(self, env):
- class User(object):
- def __init__(self, username):
- self.username = username
-
+ User = namedtuple("User", "username")
tmpl = env.from_string("""{{ users|join(', ', 'username') }}""")
assert tmpl.render(users=map(User, ["foo", "bar"])) == "foo, bar"
@@ -291,7 +287,7 @@ class TestFilter(object):
def test_reverse(self, env):
tmpl = env.from_string(
- '{{ "foobar"|reverse|join }}|' "{{ [1, 2, 3]|reverse|list }}"
+ "{{ 'foobar'|reverse|join }}|{{ [1, 2, 3]|reverse|list }}"
)
assert tmpl.render() == "raboof|[3, 2, 1]"
@@ -370,7 +366,7 @@ class TestFilter(object):
env.policies["urlize.rel"] = None
tmpl = env.from_string('{{ "foo http://www.example.com/ bar"|urlize }}')
assert tmpl.render() == (
- 'foo <a href="http://www.example.com/">' "http://www.example.com/</a> bar"
+ 'foo <a href="http://www.example.com/">http://www.example.com/</a> bar'
)
def test_urlize_target_parameter(self, env):
@@ -401,7 +397,7 @@ class TestFilter(object):
def test_sum_attributes(self, env):
tmpl = env.from_string("""{{ values|sum('value') }}""")
- assert tmpl.render(values=[{"value": 23}, {"value": 1}, {"value": 18},]) == "42"
+ assert tmpl.render(values=[{"value": 23}, {"value": 1}, {"value": 18}]) == "42"
def test_sum_attributes_nested(self, env):
tmpl = env.from_string("""{{ values|sum('real.value') }}""")
@@ -418,7 +414,7 @@ class TestFilter(object):
def test_sum_attributes_tuple(self, env):
tmpl = env.from_string("""{{ values.items()|sum('1') }}""")
- assert tmpl.render(values={"foo": 23, "bar": 1, "baz": 18,}) == "42"
+ assert tmpl.render(values={"foo": 23, "bar": 1, "baz": 18}) == "42"
def test_abs(self, env):
tmpl = env.from_string("""{{ -1|abs }}|{{ 1|abs }}""")
@@ -561,22 +557,13 @@ class TestFilter(object):
assert tmpl.render() == "a:1:2|b:1|"
def test_groupby_multidot(self, env):
- class Date(object):
- def __init__(self, day, month, year):
- self.day = day
- self.month = month
- self.year = year
-
- class Article(object):
- def __init__(self, title, *date):
- self.date = Date(*date)
- self.title = title
-
+ Date = namedtuple("Date", "day,month,year")
+ Article = namedtuple("Article", "title,date")
articles = [
- Article("aha", 1, 1, 1970),
- Article("interesting", 2, 1, 1970),
- Article("really?", 3, 1, 1970),
- Article("totally not", 1, 1, 1971),
+ Article("aha", Date(1, 1, 1970)),
+ Article("interesting", Date(2, 1, 1970)),
+ Article("really?", Date(3, 1, 1970)),
+ Article("totally not", Date(1, 1, 1971)),
]
tmpl = env.from_string(
"""
@@ -647,10 +634,7 @@ class TestFilter(object):
assert tmpl.render() == "[3, 3, 15]"
def test_attribute_map(self, env):
- class User(object):
- def __init__(self, name):
- self.name = name
-
+ User = namedtuple("User", "name")
env = Environment()
users = [
User("john"),
@@ -666,15 +650,8 @@ class TestFilter(object):
assert tmpl.render() == "[]"
def test_map_default(self, env):
- class Fullname(object):
- def __init__(self, firstname, lastname):
- self.firstname = firstname
- self.lastname = lastname
-
- class Firstname(object):
- def __init__(self, firstname):
- self.firstname = firstname
-
+ Fullname = namedtuple("Fullname", "firstname,lastname")
+ Firstname = namedtuple("Firstname", "firstname")
env = Environment()
tmpl = env.from_string(
'{{ users|map(attribute="lastname", default="smith")|join(", ") }}'
@@ -708,11 +685,7 @@ class TestFilter(object):
assert tmpl.render() == "None|False|0"
def test_simple_select_attr(self, env):
- class User(object):
- def __init__(self, name, is_active):
- self.name = name
- self.is_active = is_active
-
+ User = namedtuple("User", "name,is_active")
env = Environment()
users = [
User("john", True),
@@ -725,11 +698,7 @@ class TestFilter(object):
assert tmpl.render(users=users) == "john|jane"
def test_simple_reject_attr(self, env):
- class User(object):
- def __init__(self, name, is_active):
- self.name = name
- self.is_active = is_active
-
+ User = namedtuple("User", "name,is_active")
env = Environment()
users = [
User("john", True),
@@ -742,11 +711,7 @@ class TestFilter(object):
assert tmpl.render(users=users) == "mike"
def test_func_select_attr(self, env):
- class User(object):
- def __init__(self, id, name):
- self.id = id
- self.name = name
-
+ User = namedtuple("User", "id,name")
env = Environment()
users = [
User(1, "john"),
@@ -759,11 +724,7 @@ class TestFilter(object):
assert tmpl.render(users=users) == "john|mike"
def test_func_reject_attr(self, env):
- class User(object):
- def __init__(self, id, name):
- self.id = id
- self.name = name
-
+ User = namedtuple("User", "id,name")
env = Environment()
users = [
User(1, "john"),
diff --git a/tests/test_imports.py b/tests/test_imports.py
index f2895d6..7b90222 100644
--- a/tests/test_imports.py
+++ b/tests/test_imports.py
@@ -180,9 +180,9 @@ class TestIncludes(object):
def test_import_from_with_context(self):
env = Environment(
- loader=DictLoader({"a": "{% macro x() %}{{ foobar }}{% endmacro %}",})
+ loader=DictLoader({"a": "{% macro x() %}{{ foobar }}{% endmacro %}"})
)
t = env.from_string(
- '{% set foobar = 42 %}{% from "a" ' "import x with context %}{{ x() }}"
+ "{% set foobar = 42 %}{% from 'a' import x with context %}{{ x() }}"
)
assert t.render() == "42"
diff --git a/tests/test_inheritance.py b/tests/test_inheritance.py
index 6d44d4f..0cea136 100644
--- a/tests/test_inheritance.py
+++ b/tests/test_inheritance.py
@@ -12,7 +12,6 @@ import pytest
from jinja2 import DictLoader
from jinja2 import Environment
-from jinja2 import TemplateError
from jinja2 import TemplateRuntimeError
LAYOUTTEMPLATE = """\
@@ -135,7 +134,7 @@ class TestInheritance(object):
assert tmpl.render() == "--INTRO--|BEFORE|[(INNER)]|AFTER"
def test_working(self, env):
- tmpl = env.get_template("working")
+ env.get_template("working")
def test_reuse_blocks(self, env):
tmpl = env.from_string(
@@ -196,7 +195,7 @@ class TestInheritance(object):
)
)
t = env.from_string(
- '{% extends "master.html" %}{% block item %}' "{{ item }}{% endblock %}"
+ "{% extends 'master.html' %}{% block item %}{{ item }}{% endblock %}"
)
assert t.render(seq=list(range(5))) == "[0][1][2][3][4]"
diff --git a/tests/test_lexnparse.py b/tests/test_lexnparse.py
index fb54ac8..dcfa617 100644
--- a/tests/test_lexnparse.py
+++ b/tests/test_lexnparse.py
@@ -81,13 +81,15 @@ class TestLexer(object):
assert tmpl.render() == "123"
def test_raw3(self, env):
- # The second newline after baz exists because it is AFTER the {% raw %} and is ignored.
+ # The second newline after baz exists because it is AFTER the
+ # {% raw %} and is ignored.
env = Environment(lstrip_blocks=True, trim_blocks=True)
tmpl = env.from_string("bar\n{% raw %}\n {{baz}}2 spaces\n{% endraw %}\nfoo")
assert tmpl.render(baz="test") == "bar\n\n {{baz}}2 spaces\nfoo"
def test_raw4(self, env):
- # The trailing dash of the {% raw -%} cleans both the spaces and newlines up to the first character of data.
+ # The trailing dash of the {% raw -%} cleans both the spaces and
+ # newlines up to the first character of data.
env = Environment(lstrip_blocks=True, trim_blocks=False)
tmpl = env.from_string(
"bar\n{%- raw -%}\n\n \n 2 spaces\n space{%- endraw -%}\nfoo"
@@ -531,7 +533,7 @@ class TestSyntax(object):
def test_notin(self, env):
bar = range(100)
tmpl = env.from_string("""{{ not 42 in bar }}""")
- assert tmpl.render(bar=bar) == text_type(not 42 in bar)
+ assert tmpl.render(bar=bar) == "False"
def test_operator_precedence(self, env):
tmpl = env.from_string("""{{ 2 * 3 + 4 % 2 + 1 - 2 }}""")
diff --git a/tests/test_loader.py b/tests/test_loader.py
index 44000e1..0a476d5 100644
--- a/tests/test_loader.py
+++ b/tests/test_loader.py
@@ -99,7 +99,7 @@ class TestLoaders(object):
t2 = env.get_template("two")
assert t2 is env.get_template("two")
assert t1 is env.get_template("one")
- t3 = env.get_template("three")
+ env.get_template("three")
loader_ref = weakref.ref(loader)
assert (loader_ref, "one") in env.cache
assert (loader_ref, "two") not in env.cache
@@ -183,7 +183,10 @@ class TestFileSystemLoader(object):
@pytest.mark.parametrize(
("encoding", "expect"),
- [("utf-8", u"文字化け"), ("iso-8859-1", u"æ\x96\x87å\xad\x97å\x8c\x96ã\x81\x91"),],
+ [
+ ("utf-8", u"文字化け"),
+ ("iso-8859-1", u"æ\x96\x87\xe5\xad\x97\xe5\x8c\x96\xe3\x81\x91"),
+ ],
)
def test_uses_specified_encoding(self, encoding, expect):
loader = loaders.FileSystemLoader(self.searchpath, encoding=encoding)
@@ -254,7 +257,7 @@ class TestModuleLoader(object):
def test_weak_references(self, prefix_loader):
self.compile_down(prefix_loader)
- tmpl = self.mod_env.get_template("a/test.html")
+ self.mod_env.get_template("a/test.html")
key = loaders.ModuleLoader.get_template_key("a/test.html")
name = self.mod_env.loader.module.__name__
@@ -262,13 +265,13 @@ class TestModuleLoader(object):
assert name in sys.modules
# unset all, ensure the module is gone from sys.modules
- self.mod_env = tmpl = None
+ self.mod_env = None
try:
import gc
gc.collect()
- except:
+ except BaseException:
pass
assert name not in sys.modules
@@ -280,32 +283,28 @@ class TestModuleLoader(object):
def test_byte_compilation(self, prefix_loader):
log = self.compile_down(prefix_loader, py_compile=True)
assert 'Byte-compiled "a/test.html"' in log
- tmpl1 = self.mod_env.get_template("a/test.html")
+ self.mod_env.get_template("a/test.html")
mod = self.mod_env.loader.module.tmpl_3c4ddf650c1a73df961a6d3d2ce2752f1b8fd490
assert mod.__file__.endswith(".pyc")
def test_choice_loader(self, prefix_loader):
- log = self.compile_down(prefix_loader)
-
+ self.compile_down(prefix_loader)
self.mod_env.loader = loaders.ChoiceLoader(
[self.mod_env.loader, loaders.DictLoader({"DICT_SOURCE": "DICT_TEMPLATE"})]
)
-
tmpl1 = self.mod_env.get_template("a/test.html")
assert tmpl1.render() == "BAR"
tmpl2 = self.mod_env.get_template("DICT_SOURCE")
assert tmpl2.render() == "DICT_TEMPLATE"
def test_prefix_loader(self, prefix_loader):
- log = self.compile_down(prefix_loader)
-
+ self.compile_down(prefix_loader)
self.mod_env.loader = loaders.PrefixLoader(
{
"MOD": self.mod_env.loader,
"DICT": loaders.DictLoader({"test.html": "DICT_TEMPLATE"}),
}
)
-
tmpl1 = self.mod_env.get_template("MOD/a/test.html")
assert tmpl1.render() == "BAR"
tmpl2 = self.mod_env.get_template("DICT/test.html")
diff --git a/tests/test_regression.py b/tests/test_regression.py
index 47e0073..5aa1f3d 100644
--- a/tests/test_regression.py
+++ b/tests/test_regression.py
@@ -254,35 +254,34 @@ class TestBug(object):
)
pytest.raises(TemplateSyntaxError, Template, "{% for x in %}..{% endfor %}")
- def test_recursive_loop_bug(self, env):
- tpl1 = Template(
+ def test_recursive_loop_compile(self, env):
+ Template(
"""
- {% for p in foo recursive%}
- {{p.bar}}
- {% for f in p.fields recursive%}
- {{f.baz}}
+ {% for p in foo recursive%}
{{p.bar}}
- {% if f.rec %}
- {{ loop(f.sub) }}
- {% endif %}
+ {% for f in p.fields recursive%}
+ {{f.baz}}
+ {{p.bar}}
+ {% if f.rec %}
+ {{ loop(f.sub) }}
+ {% endif %}
+ {% endfor %}
{% endfor %}
- {% endfor %}
- """
+ """
)
-
- tpl2 = Template(
+ Template(
"""
- {% for p in foo%}
- {{p.bar}}
- {% for f in p.fields recursive%}
- {{f.baz}}
+ {% for p in foo%}
{{p.bar}}
- {% if f.rec %}
- {{ loop(f.sub) }}
- {% endif %}
+ {% for f in p.fields recursive%}
+ {{f.baz}}
+ {{p.bar}}
+ {% if f.rec %}
+ {{ loop(f.sub) }}
+ {% endif %}
+ {% endfor %}
{% endfor %}
- {% endfor %}
- """
+ """
)
def test_else_loop_bug(self, env):
@@ -327,7 +326,7 @@ class TestBug(object):
def test_block_set_with_extends(self):
env = Environment(
- loader=DictLoader({"main": "{% block body %}[{{ x }}]{% endblock %}",})
+ loader=DictLoader({"main": "{% block body %}[{{ x }}]{% endblock %}"})
)
t = env.from_string('{% extends "main" %}{% set x %}42{% endset %}')
assert t.render() == "[42]"
@@ -538,9 +537,7 @@ class TestBug(object):
)
sm = t.render(
this="/foo",
- site={
- "root": {"url": "/", "children": [{"url": "/foo"}, {"url": "/bar"},]}
- },
+ site={"root": {"url": "/", "children": [{"url": "/foo"}, {"url": "/bar"}]}},
)
lines = [x.strip() for x in sm.splitlines() if x.strip()]
assert lines == [
@@ -581,8 +578,8 @@ class TestBug(object):
env = Environment(
loader=DictLoader(
{
- "inc": "{{ item }}",
- "main": '{% for item in [1, 2, 3] %}{% include "inc" %}{% endfor %}',
+ "inc": "{{ i }}",
+ "main": '{% for i in [1, 2, 3] %}{% include "inc" %}{% endfor %}',
}
)
)
@@ -611,7 +608,7 @@ class TestBug(object):
assert env.get_template("test").render(foobar="test") == "test"
def test_legacy_custom_context(self, env):
- from jinja2.runtime import Context, Undefined, missing
+ from jinja2.runtime import Context, missing
class MyContext(Context):
def resolve(self, name):
@@ -627,9 +624,7 @@ class TestBug(object):
def test_recursive_loop_bug(self, env):
tmpl = env.from_string(
- """
- {%- for value in values recursive %}1{% else %}0{% endfor -%}
- """
+ "{%- for value in values recursive %}1{% else %}0{% endfor -%}"
)
assert tmpl.render(values=[]) == "0"
diff --git a/tests/test_runtime.py b/tests/test_runtime.py
index 307f055..d24f266 100644
--- a/tests/test_runtime.py
+++ b/tests/test_runtime.py
@@ -3,18 +3,14 @@ import itertools
from jinja2 import Template
from jinja2.runtime import LoopContext
-
TEST_IDX_TEMPLATE_STR_1 = (
- "[{% for i in lst|reverse %}"
- + "(len={{ loop.length }}, revindex={{ loop.revindex }}, index={{ loop.index }}, val={{ i }})"
- + "{% endfor %}]"
+ "[{% for i in lst|reverse %}(len={{ loop.length }},"
+ " revindex={{ loop.revindex }}, index={{ loop.index }}, val={{ i }}){% endfor %}]"
)
-
-
TEST_IDX0_TEMPLATE_STR_1 = (
- "[{% for i in lst|reverse %}"
- + "(len={{ loop.length }}, revindex0={{ loop.revindex0 }}, index0={{ loop.index0 }}, val={{ i }})"
- + "{% endfor %}]"
+ "[{% for i in lst|reverse %}(len={{ loop.length }},"
+ " revindex0={{ loop.revindex0 }}, index0={{ loop.index0 }}, val={{ i }})"
+ "{% endfor %}]"
)
@@ -34,20 +30,20 @@ def test_loop_idx0():
def test_loopcontext0():
in_lst = []
- l = LoopContext(reversed(in_lst), None)
- assert l.length == len(in_lst)
+ lc = LoopContext(reversed(in_lst), None)
+ assert lc.length == len(in_lst)
def test_loopcontext1():
in_lst = [10]
- l = LoopContext(reversed(in_lst), None)
- assert l.length == len(in_lst)
+ lc = LoopContext(reversed(in_lst), None)
+ assert lc.length == len(in_lst)
def test_loopcontext2():
in_lst = [10, 11]
- l = LoopContext(reversed(in_lst), None)
- assert l.length == len(in_lst)
+ lc = LoopContext(reversed(in_lst), None)
+ assert lc.length == len(in_lst)
def test_iterator_not_advanced_early():
diff --git a/tests/test_security.py b/tests/test_security.py
index 39045fd..e00ef75 100644
--- a/tests/test_security.py
+++ b/tests/test_security.py
@@ -36,8 +36,11 @@ class PrivateStuff(object):
class PublicStuff(object):
- bar = lambda self: 23
- _foo = lambda self: 42
+ def bar(self):
+ return 23
+
+ def _foo(self):
+ return 42
def __repr__(self):
return "PublicStuff"
diff --git a/tests/test_tests.py b/tests/test_tests.py
index 27871ca..447935a 100644
--- a/tests/test_tests.py
+++ b/tests/test_tests.py
@@ -195,9 +195,8 @@ class TestTestsCase(object):
env = Environment()
env.tests["matching"] = matching
tmpl = env.from_string(
- "{{ 'us-west-1' is matching "
- "'(us-east-1|ap-northeast-1)' "
- "or 'stage' is matching '(dev|stage)' }}"
+ "{{ 'us-west-1' is matching '(us-east-1|ap-northeast-1)'"
+ " or 'stage' is matching '(dev|stage)' }}"
)
assert tmpl.render() == "False"
assert items == [
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 8cecb1b..58a2cdf 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -51,14 +51,14 @@ class TestLRUCache(object):
cache = LRUCache(3)
cache["b"] = 1
cache["a"] = 2
- values = [v for v in cache.itervalues()]
+ values = [v for v in cache.values()]
assert len(values) == 2
assert 1 in values
assert 2 in values
def test_itervalues_empty(self):
cache = LRUCache(2)
- values = [v for v in cache.itervalues()]
+ values = [v for v in cache.values()]
assert len(values) == 0
def test_pickleable(self):
@@ -106,17 +106,17 @@ class TestLRUCache(object):
d["a"] = 1
d["b"] = 2
d["c"] = 3
- assert d.items() == list(d.iteritems()) == [("c", 3), ("b", 2), ("a", 1)]
- assert d.keys() == list(d.iterkeys()) == ["c", "b", "a"]
- assert d.values() == list(d.itervalues()) == [3, 2, 1]
+ assert d.items() == [("c", 3), ("b", 2), ("a", 1)]
+ assert d.keys() == ["c", "b", "a"]
+ assert d.values() == [3, 2, 1]
assert list(reversed(d)) == ["a", "b", "c"]
# Change the cache a little
d["b"]
d["a"] = 4
- assert d.items() == list(d.iteritems()) == [("a", 4), ("b", 2), ("c", 3)]
- assert d.keys() == list(d.iterkeys()) == ["a", "b", "c"]
- assert d.values() == list(d.itervalues()) == [4, 2, 3]
+ assert d.items() == [("a", 4), ("b", 2), ("c", 3)]
+ assert d.keys() == ["a", "b", "c"]
+ assert d.values() == [4, 2, 3]
assert list(reversed(d)) == ["c", "b", "a"]
def test_setdefault(self):
@@ -152,11 +152,11 @@ class TestHelpers(object):
assert func(None) == "STRING"
assert func("unknown.foo") == "NONE"
- assert func("foo.html") == True
- assert func("foo.htm") == True
- assert func("foo.txt") == False
- assert func("FOO.HTML") == True
- assert func("FOO.TXT") == False
+ assert func("foo.html")
+ assert func("foo.htm")
+ assert not func("foo.txt")
+ assert func("FOO.HTML")
+ assert not func("FOO.TXT")
@pytest.mark.utils