]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
apply flake8
authorDavid Lord <davidism@gmail.com>
Fri, 10 Jan 2020 18:40:52 +0000 (10:40 -0800)
committerDavid Lord <davidism@gmail.com>
Fri, 10 Jan 2020 18:40:52 +0000 (10:40 -0800)
43 files changed:
examples/basic/inheritance.py
examples/basic/translate.py
examples/bench.py
ext/django2jinja/django2jinja.py
ext/django2jinja/example.py
scripts/generate_identifier_pattern.py
scripts/make-release.py
setup.cfg
src/jinja2/_compat.py
src/jinja2/_identifier.py
src/jinja2/asyncfilters.py
src/jinja2/bccache.py
src/jinja2/compiler.py
src/jinja2/debug.py
src/jinja2/defaults.py
src/jinja2/environment.py
src/jinja2/ext.py
src/jinja2/filters.py
src/jinja2/lexer.py
src/jinja2/loaders.py
src/jinja2/nodes.py
src/jinja2/parser.py
src/jinja2/runtime.py
src/jinja2/sandbox.py
src/jinja2/tests.py
src/jinja2/utils.py
tests/test_api.py
tests/test_async.py
tests/test_asyncfilters.py
tests/test_core_tags.py
tests/test_debug.py
tests/test_ext.py
tests/test_features.py
tests/test_filters.py
tests/test_imports.py
tests/test_inheritance.py
tests/test_lexnparse.py
tests/test_loader.py
tests/test_regression.py
tests/test_runtime.py
tests/test_security.py
tests/test_tests.py
tests/test_utils.py

index a3073a5e1eb258dba9c74f7f997dfedd4ef58e66..4a881bf8a87c1a0d826aefc3793612a05c294bc6 100644 (file)
@@ -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 %}",
         }
     )
 )
index fda8f7a1c0d0caf1dfc1440936da1eb96a6db7fb..71547f4649cad60083814a4a1718cdf0e448928e 100644 (file)
@@ -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])
 )
index 473928b9c460e34882b3b86fcd71c3ddae7ead64..e610718f94702739fb2da2d663ec415db84e5d26 100644 (file)
@@ -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>
index 25b116e59046a469d77f232bc44a6819da540209..11e1a2b4e93804047992e08491d0ab1acb7c6f10 100644 (file)
@@ -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:
index 9bd6b97d87fa643c91621775ea4b0366321f370c..070549fed6427c0562b1b9b261f599e72c411a37 100644 (file)
@@ -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)
index 96fedba6a8161c8170b63e599cd36783ccfd0709..845a441cad9656771bc98021efe1c0733a15524c 100755 (executable)
@@ -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__":
index cd6ce23dbd179f3456932e89415a49f1033b195f..de36ae125918109fd7764fbb2966c67b66403ccb 100644 (file)
@@ -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.")
 
index 5ff30eb42ff42bddd46d723b2807c4b965fd62b8..a9dfcbb01abdecf1333fb126f0e1a8f81ee1360c 100644 (file)
--- 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
index 02aed34d3acf38107e3fff7e20573655bc388bfa..aa21641f82f6a12d28e86db0b8296459e8abe177 100644 (file)
@@ -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."""
index 0a93e95680b01d7d40ba8ea231fa194038380299..2490963d48d2bd9fc06fb2082e3af358d57c45c9 100644 (file)
@@ -1,2 +1,2 @@
 # generated by scripts/generate_identifier_pattern.py
-pattern = "·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣔ-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூெ-ைொ-்ௗఀ-ఃా-ౄె-ైొ-్ౕౖౢౣಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣංඃ්ා-ුූෘ-ෟෲෳัิ-ฺ็-๎ັິ-ູົຼ່-ໍ༹༘༙༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏႚ-ႝ፝-፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝᠋-᠍ᢅᢆᢩᤠ-ᤫᤰ-᤻ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼᪰-᪽ᬀ-ᬄ᬴-᭄᭫-᭳ᮀ-ᮂᮡ-ᮭ᯦-᯳ᰤ-᰷᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰℘℮⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣠-꣱ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀ꧥꨩ-ꨶꩃꩌꩍꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ︀-️︠-︯︳︴﹍-﹏_𐇽𐋠𐍶-𐍺𐨁-𐨃𐨅𐨆𐨌-𐨏𐨸-𐨿𐨺𐫦𐫥𑀀-𑀂𑀸-𑁆𑁿-𑂂𑂰-𑂺𑄀-𑄂𑄧-𑅳𑄴𑆀-𑆂𑆳-𑇊𑇀-𑇌𑈬-𑈷𑈾𑋟-𑋪𑌀-𑌃𑌼𑌾-𑍄𑍇𑍈𑍋-𑍍𑍗𑍢𑍣𑍦-𑍬𑍰-𑍴𑐵-𑑆𑒰-𑓃𑖯-𑖵𑖸-𑗀𑗜𑗝𑘰-𑙀𑚫-𑚷𑜝-𑜫𑰯-𑰶𑰸-𑰿𑲒-𑲧𑲩-𑲶𖫰-𖫴𖬰-𖬶𖽑-𖽾𖾏-𖾒𛲝𛲞𝅥-𝅩𝅭-𝅲𝅻-𝆂𝆅-𝆋𝆪-𝆭𝉂-𝉄𝨀-𝨶𝨻-𝩬𝩵𝪄𝪛-𝪟𝪡-𝪯𞀀-𞀆𞀈-𞀘𞀛-𞀡𞀣𞀤𞀦-𞣐𞀪-𞣖𞥄-𞥊󠄀-󠇯"
+pattern = "·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣔ-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூெ-ைொ-்ௗఀ-ఃా-ౄె-ైొ-్ౕౖౢౣಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣංඃ්ා-ුූෘ-ෟෲෳัิ-ฺ็-๎ັິ-ູົຼ່-ໍ༹༘༙༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏႚ-ႝ፝-፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝᠋-᠍ᢅᢆᢩᤠ-ᤫᤰ-᤻ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼᪰-᪽ᬀ-ᬄ᬴-᭄᭫-᭳ᮀ-ᮂᮡ-ᮭ᯦-᯳ᰤ-᰷᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰℘℮⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣠-꣱ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀ꧥꨩ-ꨶꩃꩌꩍꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ︀-️︠-︯︳︴﹍-﹏_𐇽𐋠𐍶-𐍺𐨁-𐨃𐨅𐨆𐨌-𐨏𐨸-𐨿𐨺𐫦𐫥𑀀-𑀂𑀸-𑁆𑁿-𑂂𑂰-𑂺𑄀-𑄂𑄧-𑅳𑄴𑆀-𑆂𑆳-𑇊𑇀-𑇌𑈬-𑈷𑈾𑋟-𑋪𑌀-𑌃𑌼𑌾-𑍄𑍇𑍈𑍋-𑍍𑍗𑍢𑍣𑍦-𑍬𑍰-𑍴𑐵-𑑆𑒰-𑓃𑖯-𑖵𑖸-𑗀𑗜𑗝𑘰-𑙀𑚫-𑚷𑜝-𑜫𑰯-𑰶𑰸-𑰿𑲒-𑲧𑲩-𑲶𖫰-𖫴𖬰-𖬶𖽑-𖽾𖾏-𖾒𛲝𛲞𝅥-𝅩𝅭-𝅲𝅻-𝆂𝆅-𝆋𝆪-𝆭𝉂-𝉄𝨀-𝨶𝨻-𝩬𝩵𝪄𝪛-𝪟𝪡-𝪯𞀀-𞀆𞀈-𞀘𞀛-𞀡𞀣𞀤𞀦-𞣐𞀪-𞣖𞥄-𞥊󠄀-󠇯"  # noqa: B950
index 451d3f8b8432e76a342dfdab5a1e4e4ff48d1513..d29f6c62d2e51ba0fddda927c0a04d934da1118c 100644 (file)
@@ -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
index c2b877e635cb3550ba8c8ed927c552f28b361eb7..75419d1fc34b3e5a71fba8efca84c94956e16a5d 100644 (file)
@@ -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
index 324bc0ffe5ba34678f99d3d3e8aff736647370da..068ad569a1027d8381cb7d93217dcf1a5f1da622 100644 (file)
@@ -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 (
index bb366094739135040cef61fe901e802cdb454d91..d2c5a06bf6c1b17087a2663d84b2b735766f4a34 100644 (file)
@@ -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
 
 
index 8ee52bb227eb7314fcd4ffb0487287e74336a31d..0af8c54e2aef7161c3c6690e78d939042c95586d 100644 (file)
@@ -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,
index 7c4d26a7b9b2fc6aab00c79b8c22a007a0e2ce76..d3328311437fa90b27429ef4558058cf5eb53269 100644 (file)
@@ -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):
index 4891c9cdfea3189bfa6f8de17522fcc587d3be4e..b2310718d150680ec60a2a3b50e2d50783eab3f1 100644 (file)
@@ -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
index c7a2f39b8e45f7f54873fad007428c88ab0a4f03..79394ad7d9ddf4c30c3b6d8bb56f45eb190e7317 100644 (file)
@@ -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
 
index 1bac2d6b5b352580d1ff4f47732d12a4a83191af..a9585ef8f71cc6cc098db23af7e46f8e8c59e124 100644 (file)
@@ -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),
index fa91a735aebb35cbb46455ad9c471dd3073d6c75..99798fd4d66560eb203c5c675d46a31db9c1770a 100644 (file)
@@ -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) :]
index 65b259931971f98023c9350f8651e07b46259068..802654301e0170691a306b6ba9e3b0d5157e5597 100644 (file)
@@ -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):
index 648c3fd1acaafba8fccacfbf775b6912356b87c1..1d9fd9170f2dc1d69e2a1e685f130c550cd63963 100644 (file)
@@ -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:
index 9f4f224d08dbb95f111ffd9268418552b9bd3b29..365c1f719e5b697f0b68857b0b87fa681c2db1ed 100644 (file)
@@ -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:
index ad87997c8ec178140224c2e913f403c1b810662d..bf4a0f6798370822d781c8a10cb34eea491eecbe 100644 (file)
@@ -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:
index 3eea947907fcd4b5be49ef3022fd1b79c181555c..8c4d46691f3201ef18cd4a96039dd7bb33087918 100644 (file)
@@ -142,7 +142,7 @@ def test_sequence(value):
     try:
         len(value)
         value.__getitem__
-    except:
+    except Exception:
         return False
     return True
 
index c051f30b89693839d13f49fd0d5c8311973980fc..e42942833a201f415aa5c78be1d8277122705dd3 100644 (file)
@@ -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)
index a0c546c8661606ed19e669bd883b0f8130bf15fd..a9eddbeb0bca90bba4228f6b21d481d55cb13288 100644 (file)
@@ -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):
index bae73c6ef53d5aa2d45411b5321843b1a2de0733..f7e27922ea84773c1f2d13a615e00b2f7442fe6d 100644 (file)
@@ -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 == [
index 23a1001d7b22aa684fa30d8b7ffa448564198f73..7c737c835e0846c0a57d7abff4a93a5aba49af4a 100644 (file)
@@ -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 == (
index deb016938fac2b9b13b2d653a1d53b2a8df1566e..0f9346b9abdf884692bf3f9ccd185aec2d3a5237 100644 (file)
@@ -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"
 
index e19a540e13cf22a4042cf2da4c0a49e7a468caf6..7dbad312d85ef9248746a5e4d02f1a4997e57b70 100644 (file)
@@ -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'.
     """,
         )
 
index 0a9b648fb424812f6d228a8d3e7ac5cd082c9895..6ecf9a2acf71124a96ce58813801b1902bcb6004 100644 (file)
@@ -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  "
 
index 0d7baedf8eaa05a5b03759c9275528e70cb4de30..34b6f200deab22533911fb1ec800ff8770254792 100644 (file)
@@ -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)
index 3f74c27571e7effaf6f4e263f943f9cd5ff96b76..ae10eb5e9623286616d846e62c656665cacac988 100644 (file)
@@ -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"),
index f2895d6682f291f9283f1046c3176318a8bd44c8..7b902226bdffbe2627c7946a98e5ae2409e9b968 100644 (file)
@@ -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"
index 6d44d4f2bb906fa6b27d774084a47690cb31eca6..0cea136cceadb93bfa95fc7bd65513feac0a35f3 100644 (file)
@@ -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]"
 
index fb54ac8f72762f6624e80ee3d3ec6b62ace3c0a1..dcfa6172399edb29c9c6e2569ea951a10ba160d3 100644 (file)
@@ -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 }}""")
index 44000e19d8a0b749b7d11a28cb889189d01bfc3a..0a476d5259bfedcfa182071f9fff4ff237dae58c 100644 (file)
@@ -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")
index 47e007324b9681d601528c8a499cf07562250e67..5aa1f3d6b2a096efb88f97a245a78c5a5b21ec49 100644 (file)
@@ -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"
 
index 307f0550d041630d3f4554c9ee56f6d29460621e..d24f2660cf0c1c1d53115765ef939372a776f513 100644 (file)
@@ -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():
index 39045fd458ebf803cd84df0f91c628cb129548fb..e00ef7568ea186c7cbdd0196771c1656efafdedc 100644 (file)
@@ -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"
index 27871ca22718bc4fc14cad2da78394fa203caf98..447935a15dde91c87acbe5d706c0678c52fd2fd9 100644 (file)
@@ -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 == [
index 8cecb1b56d981dc42d0739beb794f9cff8bf5025..58a2cdffc881f7b5f1a1a96e967dcc93ffeb4ad8 100644 (file)
@@ -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