{
    "file_diffs": [
        {
            "old_file_content": "#!/usr/bin/env python\n#\n# Copyright 2009 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"A simple template system that compiles templates to Python code.\n\nBasic usage looks like::\n\n    t = template.Template(\"<html>{{ myvalue }}</html>\")\n    print t.generate(myvalue=\"XXX\")\n\n`Loader` is a class that loads templates from a root directory and caches\nthe compiled templates::\n\n    loader = template.Loader(\"/home/btaylor\")\n    print loader.load(\"test.html\").generate(myvalue=\"XXX\")\n\nWe compile all templates to raw Python. Error-reporting is currently... uh,\ninteresting. Syntax for the templates::\n\n    ### base.html\n    <html>\n      <head>\n        <title>{% block title %}Default title{% end %}</title>\n      </head>\n      <body>\n        <ul>\n          {% for student in students %}\n            {% block student %}\n              <li>{{ escape(student.name) }}</li>\n            {% end %}\n          {% end %}\n        </ul>\n      </body>\n    </html>\n\n    ### bold.html\n    {% extends \"base.html\" %}\n\n    {% block title %}A bolder title{% end %}\n\n    {% block student %}\n      <li><span style=\"bold\">{{ escape(student.name) }}</span></li>\n    {% end %}\n\nUnlike most other template systems, we do not put any restrictions on the\nexpressions you can include in your statements. ``if`` and ``for`` blocks get\ntranslated exactly into Python, so you can do complex expressions like::\n\n   {% for student in [p for p in people if p.student and p.age > 23] %}\n     <li>{{ escape(student.name) }}</li>\n   {% end %}\n\nTranslating directly to Python means you can apply functions to expressions\neasily, like the ``escape()`` function in the examples above. You can pass\nfunctions in to your template just like any other variable\n(In a `.RequestHandler`, override `.RequestHandler.get_template_namespace`)::\n\n   ### Python code\n   def add(x, y):\n      return x + y\n   template.execute(add=add)\n\n   ### The template\n   {{ add(1, 2) }}\n\nWe provide the functions `escape() <.xhtml_escape>`, `.url_escape()`,\n`.json_encode()`, and `.squeeze()` to all templates by default.\n\nTypical applications do not create `Template` or `Loader` instances by\nhand, but instead use the `~.RequestHandler.render` and\n`~.RequestHandler.render_string` methods of\n`tornado.web.RequestHandler`, which load templates automatically based\non the ``template_path`` `.Application` setting.\n\nVariable names beginning with ``_tt_`` are reserved by the template\nsystem and should not be used by application code.\n\nSyntax Reference\n----------------\n\nTemplate expressions are surrounded by double curly braces: ``{{ ... }}``.\nThe contents may be any python expression, which will be escaped according\nto the current autoescape setting and inserted into the output.  Other\ntemplate directives use ``{% %}``.  These tags may be escaped as ``{{!``\nand ``{%!`` if you need to include a literal ``{{`` or ``{%`` in the output.\n\nTo comment out a section so that it is omitted from the output, surround it\nwith ``{# ... #}``.\n\n``{% apply *function* %}...{% end %}``\n    Applies a function to the output of all template code between ``apply``\n    and ``end``::\n\n        {% apply linkify %}{{name}} said: {{message}}{% end %}\n\n    Note that as an implementation detail apply blocks are implemented\n    as nested functions and thus may interact strangely with variables\n    set via ``{% set %}``, or the use of ``{% break %}`` or ``{% continue %}``\n    within loops.\n\n``{% autoescape *function* %}``\n    Sets the autoescape mode for the current file.  This does not affect\n    other files, even those referenced by ``{% include %}``.  Note that\n    autoescaping can also be configured globally, at the `.Application`\n    or `Loader`.::\n\n        {% autoescape xhtml_escape %}\n        {% autoescape None %}\n\n``{% block *name* %}...{% end %}``\n    Indicates a named, replaceable block for use with ``{% extends %}``.\n    Blocks in the parent template will be replaced with the contents of\n    the same-named block in a child template.::\n\n        <!-- base.html -->\n        <title>{% block title %}Default title{% end %}</title>\n\n        <!-- mypage.html -->\n        {% extends \"base.html\" %}\n        {% block title %}My page title{% end %}\n\n``{% comment ... %}``\n    A comment which will be removed from the template output.  Note that\n    there is no ``{% end %}`` tag; the comment goes from the word ``comment``\n    to the closing ``%}`` tag.\n\n``{% extends *filename* %}``\n    Inherit from another template.  Templates that use ``extends`` should\n    contain one or more ``block`` tags to replace content from the parent\n    template.  Anything in the child template not contained in a ``block``\n    tag will be ignored.  For an example, see the ``{% block %}`` tag.\n\n``{% for *var* in *expr* %}...{% end %}``\n    Same as the python ``for`` statement.  ``{% break %}`` and\n    ``{% continue %}`` may be used inside the loop.\n\n``{% from *x* import *y* %}``\n    Same as the python ``import`` statement.\n\n``{% if *condition* %}...{% elif *condition* %}...{% else %}...{% end %}``\n    Conditional statement - outputs the first section whose condition is\n    true.  (The ``elif`` and ``else`` sections are optional)\n\n``{% import *module* %}``\n    Same as the python ``import`` statement.\n\n``{% include *filename* %}``\n    Includes another template file.  The included file can see all the local\n    variables as if it were copied directly to the point of the ``include``\n    directive (the ``{% autoescape %}`` directive is an exception).\n    Alternately, ``{% module Template(filename, **kwargs) %}`` may be used\n    to include another template with an isolated namespace.\n\n``{% module *expr* %}``\n    Renders a `~tornado.web.UIModule`.  The output of the ``UIModule`` is\n    not escaped::\n\n        {% module Template(\"foo.html\", arg=42) %}\n\n    ``UIModules`` are a feature of the `tornado.web.RequestHandler`\n    class (and specifically its ``render`` method) and will not work\n    when the template system is used on its own in other contexts.\n\n``{% raw *expr* %}``\n    Outputs the result of the given expression without autoescaping.\n\n``{% set *x* = *y* %}``\n    Sets a local variable.\n\n``{% try %}...{% except %}...{% else %}...{% finally %}...{% end %}``\n    Same as the python ``try`` statement.\n\n``{% while *condition* %}... {% end %}``\n    Same as the python ``while`` statement.  ``{% break %}`` and\n    ``{% continue %}`` may be used inside the loop.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport datetime\nimport linecache\nimport os.path\nimport posixpath\nimport re\nimport threading\n\nfrom tornado import escape\nfrom tornado.log import app_log\nfrom tornado.util import ObjectDict, exec_in, unicode_type\n\ntry:\n    from cStringIO import StringIO  # py2\nexcept ImportError:\n    from io import StringIO  # py3\n\n_DEFAULT_AUTOESCAPE = \"xhtml_escape\"\n_UNSET = object()\n\n\ndef filter_whitespace(mode, text):\n    \"\"\"Transform whitespace in ``text`` according to ``mode``.\n\n    Available modes are:\n\n    * ``all``: Return all whitespace unmodified.\n    * ``single``: Collapse consecutive whitespace with a single whitespace\n      character, preserving newlines.\n\n    .. versionadded:: 4.3\n    \"\"\"\n    if mode == 'all':\n        return text\n    elif mode == 'single':\n        text = re.sub(r\"([\\t ]+)\", \" \", text)\n        text = re.sub(r\"(\\s*\\n\\s*)\", \"\\n\", text)\n        return text\n    else:\n        raise Exception(\"invalid whitespace mode %s\" % mode)\n\n\nclass Template(object):\n    \"\"\"A compiled template.\n\n    We compile into Python from the given template_string. You can generate\n    the template from variables with generate().\n    \"\"\"\n    # note that the constructor's signature is not extracted with\n    # autodoc because _UNSET looks like garbage.  When changing\n    # this signature update website/sphinx/template.rst too.\n    def __init__(self, template_string, name=\"<string>\", loader=None,\n                 compress_whitespace=_UNSET, autoescape=_UNSET,\n                 whitespace=None):\n        \"\"\"Construct a Template.\n\n        :arg str template_string: the contents of the template file.\n        :arg str name: the filename from which the template was loaded\n            (used for error message).\n        :arg tornado.template.BaseLoader loader: the `~tornado.template.BaseLoader` responsible for this template,\n            used to resolve ``{% include %}`` and ``{% extend %}``\n            directives.\n        :arg bool compress_whitespace: Deprecated since Tornado 4.3.\n            Equivalent to ``whitespace=\"single\"`` if true and\n            ``whitespace=\"all\"`` if false.\n        :arg str autoescape: The name of a function in the template\n            namespace, or ``None`` to disable escaping by default.\n        :arg str whitespace: A string specifying treatment of whitespace;\n            see `filter_whitespace` for options.\n\n        .. versionchanged:: 4.3\n           Added ``whitespace`` parameter; deprecated ``compress_whitespace``.\n        \"\"\"\n        self.name = name\n\n        if compress_whitespace is not _UNSET:\n            # Convert deprecated compress_whitespace (bool) to whitespace (str).\n            if whitespace is not None:\n                raise Exception(\"cannot set both whitespace and compress_whitespace\")\n            whitespace = \"single\" if compress_whitespace else \"all\"\n        if whitespace is None:\n            if loader and loader.whitespace:\n                whitespace = loader.whitespace\n            else:\n                # Whitespace defaults by filename.\n                if name.endswith(\".html\") or name.endswith(\".js\"):\n                    whitespace = \"single\"\n                else:\n                    whitespace = \"all\"\n        # Validate the whitespace setting.\n        filter_whitespace(whitespace, '')\n\n        if autoescape is not _UNSET:\n            self.autoescape = autoescape\n        elif loader:\n            self.autoescape = loader.autoescape\n        else:\n            self.autoescape = _DEFAULT_AUTOESCAPE\n\n        self.namespace = loader.namespace if loader else {}\n        reader = _TemplateReader(name, escape.native_str(template_string),\n                                 whitespace)\n        self.file = _File(self, _parse(reader, self))\n        self.code = self._generate_python(loader)\n        self.loader = loader\n        try:\n            # Under python2.5, the fake filename used here must match\n            # the module name used in __name__ below.\n            # The dont_inherit flag prevents template.py's future imports\n            # from being applied to the generated code.\n            self.compiled = compile(\n                escape.to_unicode(self.code),\n                \"%s.generated.py\" % self.name.replace('.', '_'),\n                \"exec\", dont_inherit=True)\n        except Exception:\n            formatted_code = _format_code(self.code).rstrip()\n            app_log.error(\"%s code:\\n%s\", self.name, formatted_code)\n            raise\n\n    def generate(self, **kwargs):\n        \"\"\"Generate this template with the given arguments.\"\"\"\n        namespace = {\n            \"escape\": escape.xhtml_escape,\n            \"xhtml_escape\": escape.xhtml_escape,\n            \"url_escape\": escape.url_escape,\n            \"json_encode\": escape.json_encode,\n            \"squeeze\": escape.squeeze,\n            \"linkify\": escape.linkify,\n            \"datetime\": datetime,\n            \"_tt_utf8\": escape.utf8,  # for internal use\n            \"_tt_string_types\": (unicode_type, bytes),\n            # __name__ and __loader__ allow the traceback mechanism to find\n            # the generated source code.\n            \"__name__\": self.name.replace('.', '_'),\n            \"__loader__\": ObjectDict(get_source=lambda name: self.code),\n        }\n        namespace.update(self.namespace)\n        namespace.update(kwargs)\n        exec_in(self.compiled, namespace)\n        execute = namespace[\"_tt_execute\"]\n        # Clear the traceback module's cache of source data now that\n        # we've generated a new template (mainly for this module's\n        # unittests, where different tests reuse the same name).\n        linecache.clearcache()\n        return execute()\n\n    def _generate_python(self, loader):\n        buffer = StringIO()\n        try:\n            # named_blocks maps from names to _NamedBlock objects\n            named_blocks = {}\n            ancestors = self._get_ancestors(loader)\n            ancestors.reverse()\n            for ancestor in ancestors:\n                ancestor.find_named_blocks(loader, named_blocks)\n            writer = _CodeWriter(buffer, named_blocks, loader,\n                                 ancestors[0].template)\n            ancestors[0].generate(writer)\n            return buffer.getvalue()\n        finally:\n            buffer.close()\n\n    def _get_ancestors(self, loader):\n        ancestors = [self.file]\n        for chunk in self.file.body.chunks:\n            if isinstance(chunk, _ExtendsBlock):\n                if not loader:\n                    raise ParseError(\"{% extends %} block found, but no \"\n                                     \"template loader\")\n                template = loader.load(chunk.name, self.name)\n                ancestors.extend(template._get_ancestors(loader))\n        return ancestors\n\n\nclass BaseLoader(object):\n    \"\"\"Base class for template loaders.\n\n    You must use a template loader to use template constructs like\n    ``{% extends %}`` and ``{% include %}``. The loader caches all\n    templates after they are loaded the first time.\n    \"\"\"\n    def __init__(self, autoescape=_DEFAULT_AUTOESCAPE, namespace=None,\n                 whitespace=None):\n        \"\"\"Construct a template loader.\n\n        :arg str autoescape: The name of a function in the template\n            namespace, such as \"xhtml_escape\", or ``None`` to disable\n            autoescaping by default.\n        :arg dict namespace: A dictionary to be added to the default template\n            namespace, or ``None``.\n        :arg str whitespace: A string specifying default behavior for\n            whitespace in templates; see `filter_whitespace` for options.\n            Default is \"single\" for files ending in \".html\" and \".js\" and\n            \"all\" for other files.\n\n        .. versionchanged:: 4.3\n           Added ``whitespace`` parameter.\n        \"\"\"\n        self.autoescape = autoescape\n        self.namespace = namespace or {}\n        self.whitespace = whitespace\n        self.templates = {}\n        # self.lock protects self.templates.  It's a reentrant lock\n        # because templates may load other templates via `include` or\n        # `extends`.  Note that thanks to the GIL this code would be safe\n        # even without the lock, but could lead to wasted work as multiple\n        # threads tried to compile the same template simultaneously.\n        self.lock = threading.RLock()\n\n    def reset(self):\n        \"\"\"Resets the cache of compiled templates.\"\"\"\n        with self.lock:\n            self.templates = {}\n\n    def resolve_path(self, name, parent_path=None):\n        \"\"\"Converts a possibly-relative path to absolute (used internally).\"\"\"\n        raise NotImplementedError()\n\n    def load(self, name, parent_path=None):\n        \"\"\"Loads a template.\"\"\"\n        name = self.resolve_path(name, parent_path=parent_path)\n        with self.lock:\n            if name not in self.templates:\n                self.templates[name] = self._create_template(name)\n            return self.templates[name]\n\n    def _create_template(self, name):\n        raise NotImplementedError()\n\n\nclass Loader(BaseLoader):\n    \"\"\"A template loader that loads from a single root directory.\n    \"\"\"\n    def __init__(self, root_directory, **kwargs):\n        super(Loader, self).__init__(**kwargs)\n        self.root = os.path.abspath(root_directory)\n\n    def resolve_path(self, name, parent_path=None):\n        if parent_path and not parent_path.startswith(\"<\") and \\\n            not parent_path.startswith(\"/\") and \\\n                not name.startswith(\"/\"):\n            current_path = os.path.join(self.root, parent_path)\n            file_dir = os.path.dirname(os.path.abspath(current_path))\n            relative_path = os.path.abspath(os.path.join(file_dir, name))\n            if relative_path.startswith(self.root):\n                name = relative_path[len(self.root) + 1:]\n        return name\n\n    def _create_template(self, name):\n        path = os.path.join(self.root, name)\n        with open(path, \"rb\") as f:\n            template = Template(f.read(), name=name, loader=self)\n            return template\n\n\nclass DictLoader(BaseLoader):\n    \"\"\"A template loader that loads from a dictionary.\"\"\"\n    def __init__(self, dict, **kwargs):\n        super(DictLoader, self).__init__(**kwargs)\n        self.dict = dict\n\n    def resolve_path(self, name, parent_path=None):\n        if parent_path and not parent_path.startswith(\"<\") and \\\n            not parent_path.startswith(\"/\") and \\\n                not name.startswith(\"/\"):\n            file_dir = posixpath.dirname(parent_path)\n            name = posixpath.normpath(posixpath.join(file_dir, name))\n        return name\n\n    def _create_template(self, name):\n        return Template(self.dict[name], name=name, loader=self)\n\n\nclass _Node(object):\n    def each_child(self):\n        return ()\n\n    def generate(self, writer):\n        raise NotImplementedError()\n\n    def find_named_blocks(self, loader, named_blocks):\n        for child in self.each_child():\n            child.find_named_blocks(loader, named_blocks)\n\n\nclass _File(_Node):\n    def __init__(self, template, body):\n        self.template = template\n        self.body = body\n        self.line = 0\n\n    def generate(self, writer):\n        writer.write_line(\"def _tt_execute():\", self.line)\n        with writer.indent():\n            writer.write_line(\"_tt_buffer = []\", self.line)\n            writer.write_line(\"_tt_append = _tt_buffer.append\", self.line)\n            self.body.generate(writer)\n            writer.write_line(\"return _tt_utf8('').join(_tt_buffer)\", self.line)\n\n    def each_child(self):\n        return (self.body,)\n\n\nclass _ChunkList(_Node):\n    def __init__(self, chunks):\n        self.chunks = chunks\n\n    def generate(self, writer):\n        for chunk in self.chunks:\n            chunk.generate(writer)\n\n    def each_child(self):\n        return self.chunks\n\n\nclass _NamedBlock(_Node):\n    def __init__(self, name, body, template, line):\n        self.name = name\n        self.body = body\n        self.template = template\n        self.line = line\n\n    def each_child(self):\n        return (self.body,)\n\n    def generate(self, writer):\n        block = writer.named_blocks[self.name]\n        with writer.include(block.template, self.line):\n            block.body.generate(writer)\n\n    def find_named_blocks(self, loader, named_blocks):\n        named_blocks[self.name] = self\n        _Node.find_named_blocks(self, loader, named_blocks)\n\n\nclass _ExtendsBlock(_Node):\n    def __init__(self, name):\n        self.name = name\n\n\nclass _IncludeBlock(_Node):\n    def __init__(self, name, reader, line):\n        self.name = name\n        self.template_name = reader.name\n        self.line = line\n\n    def find_named_blocks(self, loader, named_blocks):\n        included = loader.load(self.name, self.template_name)\n        included.file.find_named_blocks(loader, named_blocks)\n\n    def generate(self, writer):\n        included = writer.loader.load(self.name, self.template_name)\n        with writer.include(included, self.line):\n            included.file.body.generate(writer)\n\n\nclass _ApplyBlock(_Node):\n    def __init__(self, method, line, body=None):\n        self.method = method\n        self.line = line\n        self.body = body\n\n    def each_child(self):\n        return (self.body,)\n\n    def generate(self, writer):\n        method_name = \"_tt_apply%d\" % writer.apply_counter\n        writer.apply_counter += 1\n        writer.write_line(\"def %s():\" % method_name, self.line)\n        with writer.indent():\n            writer.write_line(\"_tt_buffer = []\", self.line)\n            writer.write_line(\"_tt_append = _tt_buffer.append\", self.line)\n            self.body.generate(writer)\n            writer.write_line(\"return _tt_utf8('').join(_tt_buffer)\", self.line)\n        writer.write_line(\"_tt_append(_tt_utf8(%s(%s())))\" % (\n            self.method, method_name), self.line)\n\n\nclass _ControlBlock(_Node):\n    def __init__(self, statement, line, body=None):\n        self.statement = statement\n        self.line = line\n        self.body = body\n\n    def each_child(self):\n        return (self.body,)\n\n    def generate(self, writer):\n        writer.write_line(\"%s:\" % self.statement, self.line)\n        with writer.indent():\n            self.body.generate(writer)\n            # Just in case the body was empty\n            writer.write_line(\"pass\", self.line)\n\n\nclass _IntermediateControlBlock(_Node):\n    def __init__(self, statement, line):\n        self.statement = statement\n        self.line = line\n\n    def generate(self, writer):\n        # In case the previous block was empty\n        writer.write_line(\"pass\", self.line)\n        writer.write_line(\"%s:\" % self.statement, self.line, writer.indent_size() - 1)\n\n\nclass _Statement(_Node):\n    def __init__(self, statement, line):\n        self.statement = statement\n        self.line = line\n\n    def generate(self, writer):\n        writer.write_line(self.statement, self.line)\n\n\nclass _Expression(_Node):\n    def __init__(self, expression, line, raw=False):\n        self.expression = expression\n        self.line = line\n        self.raw = raw\n\n    def generate(self, writer):\n        writer.write_line(\"_tt_tmp = %s\" % self.expression, self.line)\n        writer.write_line(\"if isinstance(_tt_tmp, _tt_string_types):\"\n                          \" _tt_tmp = _tt_utf8(_tt_tmp)\", self.line)\n        writer.write_line(\"else: _tt_tmp = _tt_utf8(str(_tt_tmp))\", self.line)\n        if not self.raw and writer.current_template.autoescape is not None:\n            # In python3 functions like xhtml_escape return unicode,\n            # so we have to convert to utf8 again.\n            writer.write_line(\"_tt_tmp = _tt_utf8(%s(_tt_tmp))\" %\n                              writer.current_template.autoescape, self.line)\n        writer.write_line(\"_tt_append(_tt_tmp)\", self.line)\n\n\nclass _Module(_Expression):\n    def __init__(self, expression, line):\n        super(_Module, self).__init__(\"_tt_modules.\" + expression, line,\n                                      raw=True)\n\n\nclass _Text(_Node):\n    def __init__(self, value, line, whitespace):\n        self.value = value\n        self.line = line\n        self.whitespace = whitespace\n\n    def generate(self, writer):\n        value = self.value\n\n        # Compress whitespace if requested, with a crude heuristic to avoid\n        # altering preformatted whitespace.\n        if \"<pre>\" not in value:\n            value = filter_whitespace(self.whitespace, value)\n\n        if value:\n            writer.write_line('_tt_append(%r)' % escape.utf8(value), self.line)\n\n\nclass ParseError(Exception):\n    \"\"\"Raised for template syntax errors.\n\n    ``ParseError`` instances have ``filename`` and ``lineno`` attributes\n    indicating the position of the error.\n\n    .. versionchanged:: 4.3\n       Added ``filename`` and ``lineno`` attributes.\n    \"\"\"\n    def __init__(self, message, filename, lineno):\n        self.message = message\n        # The names \"filename\" and \"lineno\" are chosen for consistency\n        # with python SyntaxError.\n        self.filename = filename\n        self.lineno = lineno\n\n    def __str__(self):\n        return '%s at %s:%d' % (self.message, self.filename, self.lineno)\n\n\nclass _CodeWriter(object):\n    def __init__(self, file, named_blocks, loader, current_template):\n        self.file = file\n        self.named_blocks = named_blocks\n        self.loader = loader\n        self.current_template = current_template\n        self.apply_counter = 0\n        self.include_stack = []\n        self._indent = 0\n\n    def indent_size(self):\n        return self._indent\n\n    def indent(self):\n        class Indenter(object):\n            def __enter__(_):\n                self._indent += 1\n                return self\n\n            def __exit__(_, *args):\n                assert self._indent > 0\n                self._indent -= 1\n\n        return Indenter()\n\n    def include(self, template, line):\n        self.include_stack.append((self.current_template, line))\n        self.current_template = template\n\n        class IncludeTemplate(object):\n            def __enter__(_):\n                return self\n\n            def __exit__(_, *args):\n                self.current_template = self.include_stack.pop()[0]\n\n        return IncludeTemplate()\n\n    def write_line(self, line, line_number, indent=None):\n        if indent is None:\n            indent = self._indent\n        line_comment = '  # %s:%d' % (self.current_template.name, line_number)\n        if self.include_stack:\n            ancestors = [\"%s:%d\" % (tmpl.name, lineno)\n                         for (tmpl, lineno) in self.include_stack]\n            line_comment += ' (via %s)' % ', '.join(reversed(ancestors))\n        print(\"    \" * indent + line + line_comment, file=self.file)\n\n\nclass _TemplateReader(object):\n    def __init__(self, name, text, whitespace):\n        self.name = name\n        self.text = text\n        self.whitespace = whitespace\n        self.line = 1\n        self.pos = 0\n\n    def find(self, needle, start=0, end=None):\n        assert start >= 0, start\n        pos = self.pos\n        start += pos\n        if end is None:\n            index = self.text.find(needle, start)\n        else:\n            end += pos\n            assert end >= start\n            index = self.text.find(needle, start, end)\n        if index != -1:\n            index -= pos\n        return index\n\n    def consume(self, count=None):\n        if count is None:\n            count = len(self.text) - self.pos\n        newpos = self.pos + count\n        self.line += self.text.count(\"\\n\", self.pos, newpos)\n        s = self.text[self.pos:newpos]\n        self.pos = newpos\n        return s\n\n    def remaining(self):\n        return len(self.text) - self.pos\n\n    def __len__(self):\n        return self.remaining()\n\n    def __getitem__(self, key):\n        if type(key) is slice:\n            size = len(self)\n            start, stop, step = key.indices(size)\n            if start is None:\n                start = self.pos\n            else:\n                start += self.pos\n            if stop is not None:\n                stop += self.pos\n            return self.text[slice(start, stop, step)]\n        elif key < 0:\n            return self.text[key]\n        else:\n            return self.text[self.pos + key]\n\n    def __str__(self):\n        return self.text[self.pos:]\n\n    def raise_parse_error(self, msg):\n        raise ParseError(msg, self.name, self.line)\n\n\ndef _format_code(code):\n    lines = code.splitlines()\n    format = \"%%%dd  %%s\\n\" % len(repr(len(lines) + 1))\n    return \"\".join([format % (i + 1, line) for (i, line) in enumerate(lines)])\n\n\ndef _parse(reader, template, in_block=None, in_loop=None):\n    body = _ChunkList([])\n    while True:\n        # Find next template directive\n        curly = 0\n        while True:\n            curly = reader.find(\"{\", curly)\n            if curly == -1 or curly + 1 == reader.remaining():\n                # EOF\n                if in_block:\n                    reader.raise_parse_error(\n                        \"Missing {%% end %%} block for %s\" % in_block)\n                body.chunks.append(_Text(reader.consume(), reader.line,\n                                         reader.whitespace))\n                return body\n            # If the first curly brace is not the start of a special token,\n            # start searching from the character after it\n            if reader[curly + 1] not in (\"{\", \"%\", \"#\"):\n                curly += 1\n                continue\n            # When there are more than 2 curlies in a row, use the\n            # innermost ones.  This is useful when generating languages\n            # like latex where curlies are also meaningful\n            if (curly + 2 < reader.remaining() and\n                    reader[curly + 1] == '{' and reader[curly + 2] == '{'):\n                curly += 1\n                continue\n            break\n\n        # Append any text before the special token\n        if curly > 0:\n            cons = reader.consume(curly)\n            body.chunks.append(_Text(cons, reader.line,\n                                     reader.whitespace))\n\n        start_brace = reader.consume(2)\n        line = reader.line\n\n        # Template directives may be escaped as \"{{!\" or \"{%!\".\n        # In this case output the braces and consume the \"!\".\n        # This is especially useful in conjunction with jquery templates,\n        # which also use double braces.\n        if reader.remaining() and reader[0] == \"!\":\n            reader.consume(1)\n            body.chunks.append(_Text(start_brace, line,\n                                     reader.whitespace))\n            continue\n\n        # Comment\n        if start_brace == \"{#\":\n            end = reader.find(\"#}\")\n            if end == -1:\n                reader.raise_parse_error(\"Missing end comment #}\")\n            contents = reader.consume(end).strip()\n            reader.consume(2)\n            continue\n\n        # Expression\n        if start_brace == \"{{\":\n            end = reader.find(\"}}\")\n            if end == -1:\n                reader.raise_parse_error(\"Missing end expression }}\")\n            contents = reader.consume(end).strip()\n            reader.consume(2)\n            if not contents:\n                reader.raise_parse_error(\"Empty expression\")\n            body.chunks.append(_Expression(contents, line))\n            continue\n\n        # Block\n        assert start_brace == \"{%\", start_brace\n        end = reader.find(\"%}\")\n        if end == -1:\n            reader.raise_parse_error(\"Missing end block %}\")\n        contents = reader.consume(end).strip()\n        reader.consume(2)\n        if not contents:\n            reader.raise_parse_error(\"Empty block tag ({% %})\")\n\n        operator, space, suffix = contents.partition(\" \")\n        suffix = suffix.strip()\n\n        # Intermediate (\"else\", \"elif\", etc) blocks\n        intermediate_blocks = {\n            \"else\": set([\"if\", \"for\", \"while\", \"try\"]),\n            \"elif\": set([\"if\"]),\n            \"except\": set([\"try\"]),\n            \"finally\": set([\"try\"]),\n        }\n        allowed_parents = intermediate_blocks.get(operator)\n        if allowed_parents is not None:\n            if not in_block:\n                reader.raise_parse_error(\"%s outside %s block\" %\n                                         (operator, allowed_parents))\n            if in_block not in allowed_parents:\n                reader.raise_parse_error(\n                    \"%s block cannot be attached to %s block\" %\n                    (operator, in_block))\n            body.chunks.append(_IntermediateControlBlock(contents, line))\n            continue\n\n        # End tag\n        elif operator == \"end\":\n            if not in_block:\n                reader.raise_parse_error(\"Extra {% end %} block\")\n            return body\n\n        elif operator in (\"extends\", \"include\", \"set\", \"import\", \"from\",\n                          \"comment\", \"autoescape\", \"raw\", \"module\"):\n            if operator == \"comment\":\n                continue\n            if operator == \"extends\":\n                suffix = suffix.strip('\"').strip(\"'\")\n                if not suffix:\n                    reader.raise_parse_error(\"extends missing file path\")\n                block = _ExtendsBlock(suffix)\n            elif operator in (\"import\", \"from\"):\n                if not suffix:\n                    reader.raise_parse_error(\"import missing statement\")\n                block = _Statement(contents, line)\n            elif operator == \"include\":\n                suffix = suffix.strip('\"').strip(\"'\")\n                if not suffix:\n                    reader.raise_parse_error(\"include missing file path\")\n                block = _IncludeBlock(suffix, reader, line)\n            elif operator == \"set\":\n                if not suffix:\n                    reader.raise_parse_error(\"set missing statement\")\n                block = _Statement(suffix, line)\n            elif operator == \"autoescape\":\n                fn = suffix.strip()\n                if fn == \"None\":\n                    fn = None\n                template.autoescape = fn\n                continue\n            elif operator == \"raw\":\n                block = _Expression(suffix, line, raw=True)\n            elif operator == \"module\":\n                block = _Module(suffix, line)\n            body.chunks.append(block)\n            continue\n\n        elif operator in (\"apply\", \"block\", \"try\", \"if\", \"for\", \"while\"):\n            # parse inner body recursively\n            if operator in (\"for\", \"while\"):\n                block_body = _parse(reader, template, operator, operator)\n            elif operator == \"apply\":\n                # apply creates a nested function so syntactically it's not\n                # in the loop.\n                block_body = _parse(reader, template, operator, None)\n            else:\n                block_body = _parse(reader, template, operator, in_loop)\n\n            if operator == \"apply\":\n                if not suffix:\n                    reader.raise_parse_error(\"apply missing method name\")\n                block = _ApplyBlock(suffix, line, block_body)\n            elif operator == \"block\":\n                if not suffix:\n                    reader.raise_parse_error(\"block missing name\")\n                block = _NamedBlock(suffix, block_body, template, line)\n            else:\n                block = _ControlBlock(contents, line, block_body)\n            body.chunks.append(block)\n            continue\n\n        elif operator in (\"break\", \"continue\"):\n            if not in_loop:\n                reader.raise_parse_error(\"%s outside %s block\" %\n                                         (operator, set([\"for\", \"while\"])))\n            body.chunks.append(_Statement(contents, line))\n            continue\n\n        else:\n            reader.raise_parse_error(\"unknown operator: %r\" % operator)\n",
            "new_file_content": "#!/usr/bin/env python\n#\n# Copyright 2009 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"A simple template system that compiles templates to Python code.\n\nBasic usage looks like::\n\n    t = template.Template(\"<html>{{ myvalue }}</html>\")\n    print t.generate(myvalue=\"XXX\")\n\n`Loader` is a class that loads templates from a root directory and caches\nthe compiled templates::\n\n    loader = template.Loader(\"/home/btaylor\")\n    print loader.load(\"test.html\").generate(myvalue=\"XXX\")\n\nWe compile all templates to raw Python. Error-reporting is currently... uh,\ninteresting. Syntax for the templates::\n\n    ### base.html\n    <html>\n      <head>\n        <title>{% block title %}Default title{% end %}</title>\n      </head>\n      <body>\n        <ul>\n          {% for student in students %}\n            {% block student %}\n              <li>{{ escape(student.name) }}</li>\n            {% end %}\n          {% end %}\n        </ul>\n      </body>\n    </html>\n\n    ### bold.html\n    {% extends \"base.html\" %}\n\n    {% block title %}A bolder title{% end %}\n\n    {% block student %}\n      <li><span style=\"bold\">{{ escape(student.name) }}</span></li>\n    {% end %}\n\nUnlike most other template systems, we do not put any restrictions on the\nexpressions you can include in your statements. ``if`` and ``for`` blocks get\ntranslated exactly into Python, so you can do complex expressions like::\n\n   {% for student in [p for p in people if p.student and p.age > 23] %}\n     <li>{{ escape(student.name) }}</li>\n   {% end %}\n\nTranslating directly to Python means you can apply functions to expressions\neasily, like the ``escape()`` function in the examples above. You can pass\nfunctions in to your template just like any other variable\n(In a `.RequestHandler`, override `.RequestHandler.get_template_namespace`)::\n\n   ### Python code\n   def add(x, y):\n      return x + y\n   template.execute(add=add)\n\n   ### The template\n   {{ add(1, 2) }}\n\nWe provide the functions `escape() <.xhtml_escape>`, `.url_escape()`,\n`.json_encode()`, and `.squeeze()` to all templates by default.\n\nTypical applications do not create `Template` or `Loader` instances by\nhand, but instead use the `~.RequestHandler.render` and\n`~.RequestHandler.render_string` methods of\n`tornado.web.RequestHandler`, which load templates automatically based\non the ``template_path`` `.Application` setting.\n\nVariable names beginning with ``_tt_`` are reserved by the template\nsystem and should not be used by application code.\n\nSyntax Reference\n----------------\n\nTemplate expressions are surrounded by double curly braces: ``{{ ... }}``.\nThe contents may be any python expression, which will be escaped according\nto the current autoescape setting and inserted into the output.  Other\ntemplate directives use ``{% %}``.  These tags may be escaped as ``{{!``\nand ``{%!`` if you need to include a literal ``{{`` or ``{%`` in the output.\n\nTo comment out a section so that it is omitted from the output, surround it\nwith ``{# ... #}``.\n\n``{% apply *function* %}...{% end %}``\n    Applies a function to the output of all template code between ``apply``\n    and ``end``::\n\n        {% apply linkify %}{{name}} said: {{message}}{% end %}\n\n    Note that as an implementation detail apply blocks are implemented\n    as nested functions and thus may interact strangely with variables\n    set via ``{% set %}``, or the use of ``{% break %}`` or ``{% continue %}``\n    within loops.\n\n``{% autoescape *function* %}``\n    Sets the autoescape mode for the current file.  This does not affect\n    other files, even those referenced by ``{% include %}``.  Note that\n    autoescaping can also be configured globally, at the `.Application`\n    or `Loader`.::\n\n        {% autoescape xhtml_escape %}\n        {% autoescape None %}\n\n``{% block *name* %}...{% end %}``\n    Indicates a named, replaceable block for use with ``{% extends %}``.\n    Blocks in the parent template will be replaced with the contents of\n    the same-named block in a child template.::\n\n        <!-- base.html -->\n        <title>{% block title %}Default title{% end %}</title>\n\n        <!-- mypage.html -->\n        {% extends \"base.html\" %}\n        {% block title %}My page title{% end %}\n\n``{% comment ... %}``\n    A comment which will be removed from the template output.  Note that\n    there is no ``{% end %}`` tag; the comment goes from the word ``comment``\n    to the closing ``%}`` tag.\n\n``{% extends *filename* %}``\n    Inherit from another template.  Templates that use ``extends`` should\n    contain one or more ``block`` tags to replace content from the parent\n    template.  Anything in the child template not contained in a ``block``\n    tag will be ignored.  For an example, see the ``{% block %}`` tag.\n\n``{% for *var* in *expr* %}...{% end %}``\n    Same as the python ``for`` statement.  ``{% break %}`` and\n    ``{% continue %}`` may be used inside the loop.\n\n``{% from *x* import *y* %}``\n    Same as the python ``import`` statement.\n\n``{% if *condition* %}...{% elif *condition* %}...{% else %}...{% end %}``\n    Conditional statement - outputs the first section whose condition is\n    true.  (The ``elif`` and ``else`` sections are optional)\n\n``{% import *module* %}``\n    Same as the python ``import`` statement.\n\n``{% include *filename* %}``\n    Includes another template file.  The included file can see all the local\n    variables as if it were copied directly to the point of the ``include``\n    directive (the ``{% autoescape %}`` directive is an exception).\n    Alternately, ``{% module Template(filename, **kwargs) %}`` may be used\n    to include another template with an isolated namespace.\n\n``{% module *expr* %}``\n    Renders a `~tornado.web.UIModule`.  The output of the ``UIModule`` is\n    not escaped::\n\n        {% module Template(\"foo.html\", arg=42) %}\n\n    ``UIModules`` are a feature of the `tornado.web.RequestHandler`\n    class (and specifically its ``render`` method) and will not work\n    when the template system is used on its own in other contexts.\n\n``{% raw *expr* %}``\n    Outputs the result of the given expression without autoescaping.\n\n``{% set *x* = *y* %}``\n    Sets a local variable.\n\n``{% try %}...{% except %}...{% else %}...{% finally %}...{% end %}``\n    Same as the python ``try`` statement.\n\n``{% while *condition* %}... {% end %}``\n    Same as the python ``while`` statement.  ``{% break %}`` and\n    ``{% continue %}`` may be used inside the loop.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport datetime\nimport linecache\nimport os.path\nimport posixpath\nimport re\nimport threading\n\nfrom tornado import escape\nfrom tornado.log import app_log\nfrom tornado.util import ObjectDict, exec_in, unicode_type\n\ntry:\n    from cStringIO import StringIO  # py2\nexcept ImportError:\n    from io import StringIO  # py3\n\n_DEFAULT_AUTOESCAPE = \"xhtml_escape\"\n_UNSET = object()\n\n\ndef filter_whitespace(mode, text):\n    \"\"\"Transform whitespace in ``text`` according to ``mode``.\n\n    Available modes are:\n\n    * ``all``: Return all whitespace unmodified.\n    * ``single``: Collapse consecutive whitespace with a single whitespace\n      character, preserving newlines.\n    * ``oneline``: Collapse all runs of whitespace into a single space\n      character, removing all newlines in the process.\n\n    .. versionadded:: 4.3\n    \"\"\"\n    if mode == 'all':\n        return text\n    elif mode == 'single':\n        text = re.sub(r\"([\\t ]+)\", \" \", text)\n        text = re.sub(r\"(\\s*\\n\\s*)\", \"\\n\", text)\n        return text\n    elif mode == 'oneline':\n        return re.sub(r\"(\\s+)\", \" \", text)\n    else:\n        raise Exception(\"invalid whitespace mode %s\" % mode)\n\n\nclass Template(object):\n    \"\"\"A compiled template.\n\n    We compile into Python from the given template_string. You can generate\n    the template from variables with generate().\n    \"\"\"\n    # note that the constructor's signature is not extracted with\n    # autodoc because _UNSET looks like garbage.  When changing\n    # this signature update website/sphinx/template.rst too.\n    def __init__(self, template_string, name=\"<string>\", loader=None,\n                 compress_whitespace=_UNSET, autoescape=_UNSET,\n                 whitespace=None):\n        \"\"\"Construct a Template.\n\n        :arg str template_string: the contents of the template file.\n        :arg str name: the filename from which the template was loaded\n            (used for error message).\n        :arg tornado.template.BaseLoader loader: the `~tornado.template.BaseLoader` responsible for this template,\n            used to resolve ``{% include %}`` and ``{% extend %}``\n            directives.\n        :arg bool compress_whitespace: Deprecated since Tornado 4.3.\n            Equivalent to ``whitespace=\"single\"`` if true and\n            ``whitespace=\"all\"`` if false.\n        :arg str autoescape: The name of a function in the template\n            namespace, or ``None`` to disable escaping by default.\n        :arg str whitespace: A string specifying treatment of whitespace;\n            see `filter_whitespace` for options.\n\n        .. versionchanged:: 4.3\n           Added ``whitespace`` parameter; deprecated ``compress_whitespace``.\n        \"\"\"\n        self.name = name\n\n        if compress_whitespace is not _UNSET:\n            # Convert deprecated compress_whitespace (bool) to whitespace (str).\n            if whitespace is not None:\n                raise Exception(\"cannot set both whitespace and compress_whitespace\")\n            whitespace = \"single\" if compress_whitespace else \"all\"\n        if whitespace is None:\n            if loader and loader.whitespace:\n                whitespace = loader.whitespace\n            else:\n                # Whitespace defaults by filename.\n                if name.endswith(\".html\") or name.endswith(\".js\"):\n                    whitespace = \"single\"\n                else:\n                    whitespace = \"all\"\n        # Validate the whitespace setting.\n        filter_whitespace(whitespace, '')\n\n        if autoescape is not _UNSET:\n            self.autoescape = autoescape\n        elif loader:\n            self.autoescape = loader.autoescape\n        else:\n            self.autoescape = _DEFAULT_AUTOESCAPE\n\n        self.namespace = loader.namespace if loader else {}\n        reader = _TemplateReader(name, escape.native_str(template_string),\n                                 whitespace)\n        self.file = _File(self, _parse(reader, self))\n        self.code = self._generate_python(loader)\n        self.loader = loader\n        try:\n            # Under python2.5, the fake filename used here must match\n            # the module name used in __name__ below.\n            # The dont_inherit flag prevents template.py's future imports\n            # from being applied to the generated code.\n            self.compiled = compile(\n                escape.to_unicode(self.code),\n                \"%s.generated.py\" % self.name.replace('.', '_'),\n                \"exec\", dont_inherit=True)\n        except Exception:\n            formatted_code = _format_code(self.code).rstrip()\n            app_log.error(\"%s code:\\n%s\", self.name, formatted_code)\n            raise\n\n    def generate(self, **kwargs):\n        \"\"\"Generate this template with the given arguments.\"\"\"\n        namespace = {\n            \"escape\": escape.xhtml_escape,\n            \"xhtml_escape\": escape.xhtml_escape,\n            \"url_escape\": escape.url_escape,\n            \"json_encode\": escape.json_encode,\n            \"squeeze\": escape.squeeze,\n            \"linkify\": escape.linkify,\n            \"datetime\": datetime,\n            \"_tt_utf8\": escape.utf8,  # for internal use\n            \"_tt_string_types\": (unicode_type, bytes),\n            # __name__ and __loader__ allow the traceback mechanism to find\n            # the generated source code.\n            \"__name__\": self.name.replace('.', '_'),\n            \"__loader__\": ObjectDict(get_source=lambda name: self.code),\n        }\n        namespace.update(self.namespace)\n        namespace.update(kwargs)\n        exec_in(self.compiled, namespace)\n        execute = namespace[\"_tt_execute\"]\n        # Clear the traceback module's cache of source data now that\n        # we've generated a new template (mainly for this module's\n        # unittests, where different tests reuse the same name).\n        linecache.clearcache()\n        return execute()\n\n    def _generate_python(self, loader):\n        buffer = StringIO()\n        try:\n            # named_blocks maps from names to _NamedBlock objects\n            named_blocks = {}\n            ancestors = self._get_ancestors(loader)\n            ancestors.reverse()\n            for ancestor in ancestors:\n                ancestor.find_named_blocks(loader, named_blocks)\n            writer = _CodeWriter(buffer, named_blocks, loader,\n                                 ancestors[0].template)\n            ancestors[0].generate(writer)\n            return buffer.getvalue()\n        finally:\n            buffer.close()\n\n    def _get_ancestors(self, loader):\n        ancestors = [self.file]\n        for chunk in self.file.body.chunks:\n            if isinstance(chunk, _ExtendsBlock):\n                if not loader:\n                    raise ParseError(\"{% extends %} block found, but no \"\n                                     \"template loader\")\n                template = loader.load(chunk.name, self.name)\n                ancestors.extend(template._get_ancestors(loader))\n        return ancestors\n\n\nclass BaseLoader(object):\n    \"\"\"Base class for template loaders.\n\n    You must use a template loader to use template constructs like\n    ``{% extends %}`` and ``{% include %}``. The loader caches all\n    templates after they are loaded the first time.\n    \"\"\"\n    def __init__(self, autoescape=_DEFAULT_AUTOESCAPE, namespace=None,\n                 whitespace=None):\n        \"\"\"Construct a template loader.\n\n        :arg str autoescape: The name of a function in the template\n            namespace, such as \"xhtml_escape\", or ``None`` to disable\n            autoescaping by default.\n        :arg dict namespace: A dictionary to be added to the default template\n            namespace, or ``None``.\n        :arg str whitespace: A string specifying default behavior for\n            whitespace in templates; see `filter_whitespace` for options.\n            Default is \"single\" for files ending in \".html\" and \".js\" and\n            \"all\" for other files.\n\n        .. versionchanged:: 4.3\n           Added ``whitespace`` parameter.\n        \"\"\"\n        self.autoescape = autoescape\n        self.namespace = namespace or {}\n        self.whitespace = whitespace\n        self.templates = {}\n        # self.lock protects self.templates.  It's a reentrant lock\n        # because templates may load other templates via `include` or\n        # `extends`.  Note that thanks to the GIL this code would be safe\n        # even without the lock, but could lead to wasted work as multiple\n        # threads tried to compile the same template simultaneously.\n        self.lock = threading.RLock()\n\n    def reset(self):\n        \"\"\"Resets the cache of compiled templates.\"\"\"\n        with self.lock:\n            self.templates = {}\n\n    def resolve_path(self, name, parent_path=None):\n        \"\"\"Converts a possibly-relative path to absolute (used internally).\"\"\"\n        raise NotImplementedError()\n\n    def load(self, name, parent_path=None):\n        \"\"\"Loads a template.\"\"\"\n        name = self.resolve_path(name, parent_path=parent_path)\n        with self.lock:\n            if name not in self.templates:\n                self.templates[name] = self._create_template(name)\n            return self.templates[name]\n\n    def _create_template(self, name):\n        raise NotImplementedError()\n\n\nclass Loader(BaseLoader):\n    \"\"\"A template loader that loads from a single root directory.\n    \"\"\"\n    def __init__(self, root_directory, **kwargs):\n        super(Loader, self).__init__(**kwargs)\n        self.root = os.path.abspath(root_directory)\n\n    def resolve_path(self, name, parent_path=None):\n        if parent_path and not parent_path.startswith(\"<\") and \\\n            not parent_path.startswith(\"/\") and \\\n                not name.startswith(\"/\"):\n            current_path = os.path.join(self.root, parent_path)\n            file_dir = os.path.dirname(os.path.abspath(current_path))\n            relative_path = os.path.abspath(os.path.join(file_dir, name))\n            if relative_path.startswith(self.root):\n                name = relative_path[len(self.root) + 1:]\n        return name\n\n    def _create_template(self, name):\n        path = os.path.join(self.root, name)\n        with open(path, \"rb\") as f:\n            template = Template(f.read(), name=name, loader=self)\n            return template\n\n\nclass DictLoader(BaseLoader):\n    \"\"\"A template loader that loads from a dictionary.\"\"\"\n    def __init__(self, dict, **kwargs):\n        super(DictLoader, self).__init__(**kwargs)\n        self.dict = dict\n\n    def resolve_path(self, name, parent_path=None):\n        if parent_path and not parent_path.startswith(\"<\") and \\\n            not parent_path.startswith(\"/\") and \\\n                not name.startswith(\"/\"):\n            file_dir = posixpath.dirname(parent_path)\n            name = posixpath.normpath(posixpath.join(file_dir, name))\n        return name\n\n    def _create_template(self, name):\n        return Template(self.dict[name], name=name, loader=self)\n\n\nclass _Node(object):\n    def each_child(self):\n        return ()\n\n    def generate(self, writer):\n        raise NotImplementedError()\n\n    def find_named_blocks(self, loader, named_blocks):\n        for child in self.each_child():\n            child.find_named_blocks(loader, named_blocks)\n\n\nclass _File(_Node):\n    def __init__(self, template, body):\n        self.template = template\n        self.body = body\n        self.line = 0\n\n    def generate(self, writer):\n        writer.write_line(\"def _tt_execute():\", self.line)\n        with writer.indent():\n            writer.write_line(\"_tt_buffer = []\", self.line)\n            writer.write_line(\"_tt_append = _tt_buffer.append\", self.line)\n            self.body.generate(writer)\n            writer.write_line(\"return _tt_utf8('').join(_tt_buffer)\", self.line)\n\n    def each_child(self):\n        return (self.body,)\n\n\nclass _ChunkList(_Node):\n    def __init__(self, chunks):\n        self.chunks = chunks\n\n    def generate(self, writer):\n        for chunk in self.chunks:\n            chunk.generate(writer)\n\n    def each_child(self):\n        return self.chunks\n\n\nclass _NamedBlock(_Node):\n    def __init__(self, name, body, template, line):\n        self.name = name\n        self.body = body\n        self.template = template\n        self.line = line\n\n    def each_child(self):\n        return (self.body,)\n\n    def generate(self, writer):\n        block = writer.named_blocks[self.name]\n        with writer.include(block.template, self.line):\n            block.body.generate(writer)\n\n    def find_named_blocks(self, loader, named_blocks):\n        named_blocks[self.name] = self\n        _Node.find_named_blocks(self, loader, named_blocks)\n\n\nclass _ExtendsBlock(_Node):\n    def __init__(self, name):\n        self.name = name\n\n\nclass _IncludeBlock(_Node):\n    def __init__(self, name, reader, line):\n        self.name = name\n        self.template_name = reader.name\n        self.line = line\n\n    def find_named_blocks(self, loader, named_blocks):\n        included = loader.load(self.name, self.template_name)\n        included.file.find_named_blocks(loader, named_blocks)\n\n    def generate(self, writer):\n        included = writer.loader.load(self.name, self.template_name)\n        with writer.include(included, self.line):\n            included.file.body.generate(writer)\n\n\nclass _ApplyBlock(_Node):\n    def __init__(self, method, line, body=None):\n        self.method = method\n        self.line = line\n        self.body = body\n\n    def each_child(self):\n        return (self.body,)\n\n    def generate(self, writer):\n        method_name = \"_tt_apply%d\" % writer.apply_counter\n        writer.apply_counter += 1\n        writer.write_line(\"def %s():\" % method_name, self.line)\n        with writer.indent():\n            writer.write_line(\"_tt_buffer = []\", self.line)\n            writer.write_line(\"_tt_append = _tt_buffer.append\", self.line)\n            self.body.generate(writer)\n            writer.write_line(\"return _tt_utf8('').join(_tt_buffer)\", self.line)\n        writer.write_line(\"_tt_append(_tt_utf8(%s(%s())))\" % (\n            self.method, method_name), self.line)\n\n\nclass _ControlBlock(_Node):\n    def __init__(self, statement, line, body=None):\n        self.statement = statement\n        self.line = line\n        self.body = body\n\n    def each_child(self):\n        return (self.body,)\n\n    def generate(self, writer):\n        writer.write_line(\"%s:\" % self.statement, self.line)\n        with writer.indent():\n            self.body.generate(writer)\n            # Just in case the body was empty\n            writer.write_line(\"pass\", self.line)\n\n\nclass _IntermediateControlBlock(_Node):\n    def __init__(self, statement, line):\n        self.statement = statement\n        self.line = line\n\n    def generate(self, writer):\n        # In case the previous block was empty\n        writer.write_line(\"pass\", self.line)\n        writer.write_line(\"%s:\" % self.statement, self.line, writer.indent_size() - 1)\n\n\nclass _Statement(_Node):\n    def __init__(self, statement, line):\n        self.statement = statement\n        self.line = line\n\n    def generate(self, writer):\n        writer.write_line(self.statement, self.line)\n\n\nclass _Expression(_Node):\n    def __init__(self, expression, line, raw=False):\n        self.expression = expression\n        self.line = line\n        self.raw = raw\n\n    def generate(self, writer):\n        writer.write_line(\"_tt_tmp = %s\" % self.expression, self.line)\n        writer.write_line(\"if isinstance(_tt_tmp, _tt_string_types):\"\n                          \" _tt_tmp = _tt_utf8(_tt_tmp)\", self.line)\n        writer.write_line(\"else: _tt_tmp = _tt_utf8(str(_tt_tmp))\", self.line)\n        if not self.raw and writer.current_template.autoescape is not None:\n            # In python3 functions like xhtml_escape return unicode,\n            # so we have to convert to utf8 again.\n            writer.write_line(\"_tt_tmp = _tt_utf8(%s(_tt_tmp))\" %\n                              writer.current_template.autoescape, self.line)\n        writer.write_line(\"_tt_append(_tt_tmp)\", self.line)\n\n\nclass _Module(_Expression):\n    def __init__(self, expression, line):\n        super(_Module, self).__init__(\"_tt_modules.\" + expression, line,\n                                      raw=True)\n\n\nclass _Text(_Node):\n    def __init__(self, value, line, whitespace):\n        self.value = value\n        self.line = line\n        self.whitespace = whitespace\n\n    def generate(self, writer):\n        value = self.value\n\n        # Compress whitespace if requested, with a crude heuristic to avoid\n        # altering preformatted whitespace.\n        if \"<pre>\" not in value:\n            value = filter_whitespace(self.whitespace, value)\n\n        if value:\n            writer.write_line('_tt_append(%r)' % escape.utf8(value), self.line)\n\n\nclass ParseError(Exception):\n    \"\"\"Raised for template syntax errors.\n\n    ``ParseError`` instances have ``filename`` and ``lineno`` attributes\n    indicating the position of the error.\n\n    .. versionchanged:: 4.3\n       Added ``filename`` and ``lineno`` attributes.\n    \"\"\"\n    def __init__(self, message, filename, lineno):\n        self.message = message\n        # The names \"filename\" and \"lineno\" are chosen for consistency\n        # with python SyntaxError.\n        self.filename = filename\n        self.lineno = lineno\n\n    def __str__(self):\n        return '%s at %s:%d' % (self.message, self.filename, self.lineno)\n\n\nclass _CodeWriter(object):\n    def __init__(self, file, named_blocks, loader, current_template):\n        self.file = file\n        self.named_blocks = named_blocks\n        self.loader = loader\n        self.current_template = current_template\n        self.apply_counter = 0\n        self.include_stack = []\n        self._indent = 0\n\n    def indent_size(self):\n        return self._indent\n\n    def indent(self):\n        class Indenter(object):\n            def __enter__(_):\n                self._indent += 1\n                return self\n\n            def __exit__(_, *args):\n                assert self._indent > 0\n                self._indent -= 1\n\n        return Indenter()\n\n    def include(self, template, line):\n        self.include_stack.append((self.current_template, line))\n        self.current_template = template\n\n        class IncludeTemplate(object):\n            def __enter__(_):\n                return self\n\n            def __exit__(_, *args):\n                self.current_template = self.include_stack.pop()[0]\n\n        return IncludeTemplate()\n\n    def write_line(self, line, line_number, indent=None):\n        if indent is None:\n            indent = self._indent\n        line_comment = '  # %s:%d' % (self.current_template.name, line_number)\n        if self.include_stack:\n            ancestors = [\"%s:%d\" % (tmpl.name, lineno)\n                         for (tmpl, lineno) in self.include_stack]\n            line_comment += ' (via %s)' % ', '.join(reversed(ancestors))\n        print(\"    \" * indent + line + line_comment, file=self.file)\n\n\nclass _TemplateReader(object):\n    def __init__(self, name, text, whitespace):\n        self.name = name\n        self.text = text\n        self.whitespace = whitespace\n        self.line = 1\n        self.pos = 0\n\n    def find(self, needle, start=0, end=None):\n        assert start >= 0, start\n        pos = self.pos\n        start += pos\n        if end is None:\n            index = self.text.find(needle, start)\n        else:\n            end += pos\n            assert end >= start\n            index = self.text.find(needle, start, end)\n        if index != -1:\n            index -= pos\n        return index\n\n    def consume(self, count=None):\n        if count is None:\n            count = len(self.text) - self.pos\n        newpos = self.pos + count\n        self.line += self.text.count(\"\\n\", self.pos, newpos)\n        s = self.text[self.pos:newpos]\n        self.pos = newpos\n        return s\n\n    def remaining(self):\n        return len(self.text) - self.pos\n\n    def __len__(self):\n        return self.remaining()\n\n    def __getitem__(self, key):\n        if type(key) is slice:\n            size = len(self)\n            start, stop, step = key.indices(size)\n            if start is None:\n                start = self.pos\n            else:\n                start += self.pos\n            if stop is not None:\n                stop += self.pos\n            return self.text[slice(start, stop, step)]\n        elif key < 0:\n            return self.text[key]\n        else:\n            return self.text[self.pos + key]\n\n    def __str__(self):\n        return self.text[self.pos:]\n\n    def raise_parse_error(self, msg):\n        raise ParseError(msg, self.name, self.line)\n\n\ndef _format_code(code):\n    lines = code.splitlines()\n    format = \"%%%dd  %%s\\n\" % len(repr(len(lines) + 1))\n    return \"\".join([format % (i + 1, line) for (i, line) in enumerate(lines)])\n\n\ndef _parse(reader, template, in_block=None, in_loop=None):\n    body = _ChunkList([])\n    while True:\n        # Find next template directive\n        curly = 0\n        while True:\n            curly = reader.find(\"{\", curly)\n            if curly == -1 or curly + 1 == reader.remaining():\n                # EOF\n                if in_block:\n                    reader.raise_parse_error(\n                        \"Missing {%% end %%} block for %s\" % in_block)\n                body.chunks.append(_Text(reader.consume(), reader.line,\n                                         reader.whitespace))\n                return body\n            # If the first curly brace is not the start of a special token,\n            # start searching from the character after it\n            if reader[curly + 1] not in (\"{\", \"%\", \"#\"):\n                curly += 1\n                continue\n            # When there are more than 2 curlies in a row, use the\n            # innermost ones.  This is useful when generating languages\n            # like latex where curlies are also meaningful\n            if (curly + 2 < reader.remaining() and\n                    reader[curly + 1] == '{' and reader[curly + 2] == '{'):\n                curly += 1\n                continue\n            break\n\n        # Append any text before the special token\n        if curly > 0:\n            cons = reader.consume(curly)\n            body.chunks.append(_Text(cons, reader.line,\n                                     reader.whitespace))\n\n        start_brace = reader.consume(2)\n        line = reader.line\n\n        # Template directives may be escaped as \"{{!\" or \"{%!\".\n        # In this case output the braces and consume the \"!\".\n        # This is especially useful in conjunction with jquery templates,\n        # which also use double braces.\n        if reader.remaining() and reader[0] == \"!\":\n            reader.consume(1)\n            body.chunks.append(_Text(start_brace, line,\n                                     reader.whitespace))\n            continue\n\n        # Comment\n        if start_brace == \"{#\":\n            end = reader.find(\"#}\")\n            if end == -1:\n                reader.raise_parse_error(\"Missing end comment #}\")\n            contents = reader.consume(end).strip()\n            reader.consume(2)\n            continue\n\n        # Expression\n        if start_brace == \"{{\":\n            end = reader.find(\"}}\")\n            if end == -1:\n                reader.raise_parse_error(\"Missing end expression }}\")\n            contents = reader.consume(end).strip()\n            reader.consume(2)\n            if not contents:\n                reader.raise_parse_error(\"Empty expression\")\n            body.chunks.append(_Expression(contents, line))\n            continue\n\n        # Block\n        assert start_brace == \"{%\", start_brace\n        end = reader.find(\"%}\")\n        if end == -1:\n            reader.raise_parse_error(\"Missing end block %}\")\n        contents = reader.consume(end).strip()\n        reader.consume(2)\n        if not contents:\n            reader.raise_parse_error(\"Empty block tag ({% %})\")\n\n        operator, space, suffix = contents.partition(\" \")\n        suffix = suffix.strip()\n\n        # Intermediate (\"else\", \"elif\", etc) blocks\n        intermediate_blocks = {\n            \"else\": set([\"if\", \"for\", \"while\", \"try\"]),\n            \"elif\": set([\"if\"]),\n            \"except\": set([\"try\"]),\n            \"finally\": set([\"try\"]),\n        }\n        allowed_parents = intermediate_blocks.get(operator)\n        if allowed_parents is not None:\n            if not in_block:\n                reader.raise_parse_error(\"%s outside %s block\" %\n                                         (operator, allowed_parents))\n            if in_block not in allowed_parents:\n                reader.raise_parse_error(\n                    \"%s block cannot be attached to %s block\" %\n                    (operator, in_block))\n            body.chunks.append(_IntermediateControlBlock(contents, line))\n            continue\n\n        # End tag\n        elif operator == \"end\":\n            if not in_block:\n                reader.raise_parse_error(\"Extra {% end %} block\")\n            return body\n\n        elif operator in (\"extends\", \"include\", \"set\", \"import\", \"from\",\n                          \"comment\", \"autoescape\", \"raw\", \"module\"):\n            if operator == \"comment\":\n                continue\n            if operator == \"extends\":\n                suffix = suffix.strip('\"').strip(\"'\")\n                if not suffix:\n                    reader.raise_parse_error(\"extends missing file path\")\n                block = _ExtendsBlock(suffix)\n            elif operator in (\"import\", \"from\"):\n                if not suffix:\n                    reader.raise_parse_error(\"import missing statement\")\n                block = _Statement(contents, line)\n            elif operator == \"include\":\n                suffix = suffix.strip('\"').strip(\"'\")\n                if not suffix:\n                    reader.raise_parse_error(\"include missing file path\")\n                block = _IncludeBlock(suffix, reader, line)\n            elif operator == \"set\":\n                if not suffix:\n                    reader.raise_parse_error(\"set missing statement\")\n                block = _Statement(suffix, line)\n            elif operator == \"autoescape\":\n                fn = suffix.strip()\n                if fn == \"None\":\n                    fn = None\n                template.autoescape = fn\n                continue\n            elif operator == \"raw\":\n                block = _Expression(suffix, line, raw=True)\n            elif operator == \"module\":\n                block = _Module(suffix, line)\n            body.chunks.append(block)\n            continue\n\n        elif operator in (\"apply\", \"block\", \"try\", \"if\", \"for\", \"while\"):\n            # parse inner body recursively\n            if operator in (\"for\", \"while\"):\n                block_body = _parse(reader, template, operator, operator)\n            elif operator == \"apply\":\n                # apply creates a nested function so syntactically it's not\n                # in the loop.\n                block_body = _parse(reader, template, operator, None)\n            else:\n                block_body = _parse(reader, template, operator, in_loop)\n\n            if operator == \"apply\":\n                if not suffix:\n                    reader.raise_parse_error(\"apply missing method name\")\n                block = _ApplyBlock(suffix, line, block_body)\n            elif operator == \"block\":\n                if not suffix:\n                    reader.raise_parse_error(\"block missing name\")\n                block = _NamedBlock(suffix, block_body, template, line)\n            else:\n                block = _ControlBlock(contents, line, block_body)\n            body.chunks.append(block)\n            continue\n\n        elif operator in (\"break\", \"continue\"):\n            if not in_loop:\n                reader.raise_parse_error(\"%s outside %s block\" %\n                                         (operator, set([\"for\", \"while\"])))\n            body.chunks.append(_Statement(contents, line))\n            continue\n\n        else:\n            reader.raise_parse_error(\"unknown operator: %r\" % operator)\n",
            "header": {
                "file": {
                    "path": "tornado/template.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "d0d35b3e",
                "new_commit_hash": "9a4c6c64",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/template.py"
            },
            "plus_file": {
                "path": "b/tornado/template.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 218,
                            "length": 6
                        },
                        "new_range": {
                            "start": 218,
                            "length": 8
                        },
                        "section": "def filter_whitespace(mode, text):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "    * ``all``: Return all whitespace unmodified.",
                                "type": "context"
                            },
                            {
                                "content": "    * ``single``: Collapse consecutive whitespace with a single whitespace",
                                "type": "context"
                            },
                            {
                                "content": "      character, preserving newlines.",
                                "type": "context"
                            },
                            {
                                "content": "    * ``oneline``: Collapse all runs of whitespace into a single space",
                                "type": "added"
                            },
                            {
                                "content": "      character, removing all newlines in the process.",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    .. versionadded:: 4.3",
                                "type": "context"
                            },
                            {
                                "content": "    \"\"\"",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/template.py",
                            "type": "function",
                            "name": "filter_whitespace",
                            "content": "def filter_whitespace(mode, text):\n    \"\"\"Transform whitespace in ``text`` according to ``mode``.\n\n    Available modes are:\n\n    * ``all``: Return all whitespace unmodified.\n    * ``single``: Collapse consecutive whitespace with a single whitespace\n      character, preserving newlines.\n    * ``oneline``: Collapse all runs of whitespace into a single space\n      character, removing all newlines in the process.\n\n    .. versionadded:: 4.3\n    \"\"\"\n    if mode == 'all':\n        return text\n    elif mode == 'single':\n        text = re.sub(r\"([\\t ]+)\", \" \", text)\n        text = re.sub(r\"(\\s*\\n\\s*)\", \"\\n\", text)\n        return text\n    elif mode == 'oneline':\n        return re.sub(r\"(\\s+)\", \" \", text)\n    else:\n        raise Exception(\"invalid whitespace mode %s\" % mode)",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 213,
                            "end_lineno": 235,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 227,
                            "length": 6
                        },
                        "new_range": {
                            "start": 229,
                            "length": 8
                        },
                        "section": "def filter_whitespace(mode, text):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        text = re.sub(r\"([\\t ]+)\", \" \", text)",
                                "type": "context"
                            },
                            {
                                "content": "        text = re.sub(r\"(\\s*\\n\\s*)\", \"\\n\", text)",
                                "type": "context"
                            },
                            {
                                "content": "        return text",
                                "type": "context"
                            },
                            {
                                "content": "    elif mode == 'oneline':",
                                "type": "added"
                            },
                            {
                                "content": "        return re.sub(r\"(\\s+)\", \" \", text)",
                                "type": "added"
                            },
                            {
                                "content": "    else:",
                                "type": "context"
                            },
                            {
                                "content": "        raise Exception(\"invalid whitespace mode %s\" % mode)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/template.py",
                            "type": "function",
                            "name": "filter_whitespace",
                            "content": "def filter_whitespace(mode, text):\n    \"\"\"Transform whitespace in ``text`` according to ``mode``.\n\n    Available modes are:\n\n    * ``all``: Return all whitespace unmodified.\n    * ``single``: Collapse consecutive whitespace with a single whitespace\n      character, preserving newlines.\n    * ``oneline``: Collapse all runs of whitespace into a single space\n      character, removing all newlines in the process.\n\n    .. versionadded:: 4.3\n    \"\"\"\n    if mode == 'all':\n        return text\n    elif mode == 'single':\n        text = re.sub(r\"([\\t ]+)\", \" \", text)\n        text = re.sub(r\"(\\s*\\n\\s*)\", \"\\n\", text)\n        return text\n    elif mode == 'oneline':\n        return re.sub(r\"(\\s+)\", \" \", text)\n    else:\n        raise Exception(\"invalid whitespace mode %s\" % mode)",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 213,
                            "end_lineno": 235,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "from __future__ import absolute_import, division, print_function, with_statement\n\nimport os\nimport sys\nimport traceback\n\nfrom tornado.escape import utf8, native_str, to_unicode\nfrom tornado.template import Template, DictLoader, ParseError, Loader\nfrom tornado.test.util import unittest\nfrom tornado.util import u, ObjectDict, unicode_type\n\n\nclass TemplateTest(unittest.TestCase):\n    def test_simple(self):\n        template = Template(\"Hello {{ name }}!\")\n        self.assertEqual(template.generate(name=\"Ben\"),\n                         b\"Hello Ben!\")\n\n    def test_bytes(self):\n        template = Template(\"Hello {{ name }}!\")\n        self.assertEqual(template.generate(name=utf8(\"Ben\")),\n                         b\"Hello Ben!\")\n\n    def test_expressions(self):\n        template = Template(\"2 + 2 = {{ 2 + 2 }}\")\n        self.assertEqual(template.generate(), b\"2 + 2 = 4\")\n\n    def test_comment(self):\n        template = Template(\"Hello{# TODO i18n #} {{ name }}!\")\n        self.assertEqual(template.generate(name=utf8(\"Ben\")),\n                         b\"Hello Ben!\")\n\n    def test_include(self):\n        loader = DictLoader({\n            \"index.html\": '{% include \"header.html\" %}\\nbody text',\n            \"header.html\": \"header text\",\n        })\n        self.assertEqual(loader.load(\"index.html\").generate(),\n                         b\"header text\\nbody text\")\n\n    def test_extends(self):\n        loader = DictLoader({\n            \"base.html\": \"\"\"\\\n<title>{% block title %}default title{% end %}</title>\n<body>{% block body %}default body{% end %}</body>\n\"\"\",\n            \"page.html\": \"\"\"\\\n{% extends \"base.html\" %}\n{% block title %}page title{% end %}\n{% block body %}page body{% end %}\n\"\"\",\n        })\n        self.assertEqual(loader.load(\"page.html\").generate(),\n                         b\"<title>page title</title>\\n<body>page body</body>\\n\")\n\n    def test_relative_load(self):\n        loader = DictLoader({\n            \"a/1.html\": \"{% include '2.html' %}\",\n            \"a/2.html\": \"{% include '../b/3.html' %}\",\n            \"b/3.html\": \"ok\",\n        })\n        self.assertEqual(loader.load(\"a/1.html\").generate(),\n                         b\"ok\")\n\n    def test_escaping(self):\n        self.assertRaises(ParseError, lambda: Template(\"{{\"))\n        self.assertRaises(ParseError, lambda: Template(\"{%\"))\n        self.assertEqual(Template(\"{{!\").generate(), b\"{{\")\n        self.assertEqual(Template(\"{%!\").generate(), b\"{%\")\n        self.assertEqual(Template(\"{{ 'expr' }} {{!jquery expr}}\").generate(),\n                         b\"expr {{jquery expr}}\")\n\n    def test_unicode_template(self):\n        template = Template(utf8(u(\"\\u00e9\")))\n        self.assertEqual(template.generate(), utf8(u(\"\\u00e9\")))\n\n    def test_unicode_literal_expression(self):\n        # Unicode literals should be usable in templates.  Note that this\n        # test simulates unicode characters appearing directly in the\n        # template file (with utf8 encoding), i.e. \\u escapes would not\n        # be used in the template file itself.\n        if str is unicode_type:\n            # python 3 needs a different version of this test since\n            # 2to3 doesn't run on template internals\n            template = Template(utf8(u('{{ \"\\u00e9\" }}')))\n        else:\n            template = Template(utf8(u('{{ u\"\\u00e9\" }}')))\n        self.assertEqual(template.generate(), utf8(u(\"\\u00e9\")))\n\n    def test_custom_namespace(self):\n        loader = DictLoader({\"test.html\": \"{{ inc(5) }}\"}, namespace={\"inc\": lambda x: x + 1})\n        self.assertEqual(loader.load(\"test.html\").generate(), b\"6\")\n\n    def test_apply(self):\n        def upper(s):\n            return s.upper()\n        template = Template(utf8(\"{% apply upper %}foo{% end %}\"))\n        self.assertEqual(template.generate(upper=upper), b\"FOO\")\n\n    def test_unicode_apply(self):\n        def upper(s):\n            return to_unicode(s).upper()\n        template = Template(utf8(u(\"{% apply upper %}foo \\u00e9{% end %}\")))\n        self.assertEqual(template.generate(upper=upper), utf8(u(\"FOO \\u00c9\")))\n\n    def test_bytes_apply(self):\n        def upper(s):\n            return utf8(to_unicode(s).upper())\n        template = Template(utf8(u(\"{% apply upper %}foo \\u00e9{% end %}\")))\n        self.assertEqual(template.generate(upper=upper), utf8(u(\"FOO \\u00c9\")))\n\n    def test_if(self):\n        template = Template(utf8(\"{% if x > 4 %}yes{% else %}no{% end %}\"))\n        self.assertEqual(template.generate(x=5), b\"yes\")\n        self.assertEqual(template.generate(x=3), b\"no\")\n\n    def test_if_empty_body(self):\n        template = Template(utf8(\"{% if True %}{% else %}{% end %}\"))\n        self.assertEqual(template.generate(), b\"\")\n\n    def test_try(self):\n        template = Template(utf8(\"\"\"{% try %}\ntry{% set y = 1/x %}\n{% except %}-except\n{% else %}-else\n{% finally %}-finally\n{% end %}\"\"\"))\n        self.assertEqual(template.generate(x=1), b\"\\ntry\\n-else\\n-finally\\n\")\n        self.assertEqual(template.generate(x=0), b\"\\ntry-except\\n-finally\\n\")\n\n    def test_comment_directive(self):\n        template = Template(utf8(\"{% comment blah blah %}foo\"))\n        self.assertEqual(template.generate(), b\"foo\")\n\n    def test_break_continue(self):\n        template = Template(utf8(\"\"\"\\\n{% for i in range(10) %}\n    {% if i == 2 %}\n        {% continue %}\n    {% end %}\n    {{ i }}\n    {% if i == 6 %}\n        {% break %}\n    {% end %}\n{% end %}\"\"\"))\n        result = template.generate()\n        # remove extraneous whitespace\n        result = b''.join(result.split())\n        self.assertEqual(result, b\"013456\")\n\n    def test_break_outside_loop(self):\n        try:\n            Template(utf8(\"{% break %}\"))\n            raise Exception(\"Did not get expected exception\")\n        except ParseError:\n            pass\n\n    def test_break_in_apply(self):\n        # This test verifies current behavior, although of course it would\n        # be nice if apply didn't cause seemingly unrelated breakage\n        try:\n            Template(utf8(\"{% for i in [] %}{% apply foo %}{% break %}{% end %}{% end %}\"))\n            raise Exception(\"Did not get expected exception\")\n        except ParseError:\n            pass\n\n    @unittest.skipIf(sys.version_info >= division.getMandatoryRelease(),\n                     'no testable future imports')\n    def test_no_inherit_future(self):\n        # This file has from __future__ import division...\n        self.assertEqual(1 / 2, 0.5)\n        # ...but the template doesn't\n        template = Template('{{ 1 / 2 }}')\n        self.assertEqual(template.generate(), '0')\n\n\nclass StackTraceTest(unittest.TestCase):\n    def test_error_line_number_expression(self):\n        loader = DictLoader({\"test.html\": \"\"\"one\ntwo{{1/0}}\nthree\n        \"\"\"})\n        try:\n            loader.load(\"test.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# test.html:2\" in traceback.format_exc())\n\n    def test_error_line_number_directive(self):\n        loader = DictLoader({\"test.html\": \"\"\"one\ntwo{%if 1/0%}\nthree{%end%}\n        \"\"\"})\n        try:\n            loader.load(\"test.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# test.html:2\" in traceback.format_exc())\n\n    def test_error_line_number_module(self):\n        loader = DictLoader({\n            \"base.html\": \"{% module Template('sub.html') %}\",\n            \"sub.html\": \"{{1/0}}\",\n        }, namespace={\"_tt_modules\": ObjectDict({\"Template\": lambda path, **kwargs: loader.load(path).generate(**kwargs)})})\n        try:\n            loader.load(\"base.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            exc_stack = traceback.format_exc()\n            self.assertTrue('# base.html:1' in exc_stack)\n            self.assertTrue('# sub.html:1' in exc_stack)\n\n    def test_error_line_number_include(self):\n        loader = DictLoader({\n            \"base.html\": \"{% include 'sub.html' %}\",\n            \"sub.html\": \"{{1/0}}\",\n        })\n        try:\n            loader.load(\"base.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# sub.html:1 (via base.html:1)\" in\n                            traceback.format_exc())\n\n    def test_error_line_number_extends_base_error(self):\n        loader = DictLoader({\n            \"base.html\": \"{{1/0}}\",\n            \"sub.html\": \"{% extends 'base.html' %}\",\n        })\n        try:\n            loader.load(\"sub.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            exc_stack = traceback.format_exc()\n        self.assertTrue(\"# base.html:1\" in exc_stack)\n\n    def test_error_line_number_extends_sub_error(self):\n        loader = DictLoader({\n            \"base.html\": \"{% block 'block' %}{% end %}\",\n            \"sub.html\": \"\"\"\n{% extends 'base.html' %}\n{% block 'block' %}\n{{1/0}}\n{% end %}\n            \"\"\"})\n        try:\n            loader.load(\"sub.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# sub.html:4 (via base.html:1)\" in\n                            traceback.format_exc())\n\n    def test_multi_includes(self):\n        loader = DictLoader({\n            \"a.html\": \"{% include 'b.html' %}\",\n            \"b.html\": \"{% include 'c.html' %}\",\n            \"c.html\": \"{{1/0}}\",\n        })\n        try:\n            loader.load(\"a.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# c.html:1 (via b.html:1, a.html:1)\" in\n                            traceback.format_exc())\n\n\nclass ParseErrorDetailTest(unittest.TestCase):\n    def test_details(self):\n        loader = DictLoader({\n            \"foo.html\": \"\\n\\n{{\",\n            })\n        with self.assertRaises(ParseError) as cm:\n            loader.load(\"foo.html\")\n        self.assertEqual(\"Missing end expression }} at foo.html:3\",\n                         str(cm.exception))\n        self.assertEqual(\"foo.html\", cm.exception.filename)\n        self.assertEqual(3, cm.exception.lineno)\n\n\nclass AutoEscapeTest(unittest.TestCase):\n    def setUp(self):\n        self.templates = {\n            \"escaped.html\": \"{% autoescape xhtml_escape %}{{ name }}\",\n            \"unescaped.html\": \"{% autoescape None %}{{ name }}\",\n            \"default.html\": \"{{ name }}\",\n\n            \"include.html\": \"\"\"\\\nescaped: {% include 'escaped.html' %}\nunescaped: {% include 'unescaped.html' %}\ndefault: {% include 'default.html' %}\n\"\"\",\n\n            \"escaped_block.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% block name %}base: {{ name }}{% end %}\"\"\",\n            \"unescaped_block.html\": \"\"\"\\\n{% autoescape None %}\\\n{% block name %}base: {{ name }}{% end %}\"\"\",\n\n            # Extend a base template with different autoescape policy,\n            # with and without overriding the base's blocks\n            \"escaped_extends_unescaped.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% extends \"unescaped_block.html\" %}\"\"\",\n            \"escaped_overrides_unescaped.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% extends \"unescaped_block.html\" %}\\\n{% block name %}extended: {{ name }}{% end %}\"\"\",\n            \"unescaped_extends_escaped.html\": \"\"\"\\\n{% autoescape None %}\\\n{% extends \"escaped_block.html\" %}\"\"\",\n            \"unescaped_overrides_escaped.html\": \"\"\"\\\n{% autoescape None %}\\\n{% extends \"escaped_block.html\" %}\\\n{% block name %}extended: {{ name }}{% end %}\"\"\",\n\n            \"raw_expression.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\nexpr: {{ name }}\nraw: {% raw name %}\"\"\",\n        }\n\n    def test_default_off(self):\n        loader = DictLoader(self.templates, autoescape=None)\n        name = \"Bobby <table>s\"\n        self.assertEqual(loader.load(\"escaped.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n        self.assertEqual(loader.load(\"unescaped.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n        self.assertEqual(loader.load(\"default.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n\n        self.assertEqual(loader.load(\"include.html\").generate(name=name),\n                         b\"escaped: Bobby &lt;table&gt;s\\n\"\n                         b\"unescaped: Bobby <table>s\\n\"\n                         b\"default: Bobby <table>s\\n\")\n\n    def test_default_on(self):\n        loader = DictLoader(self.templates, autoescape=\"xhtml_escape\")\n        name = \"Bobby <table>s\"\n        self.assertEqual(loader.load(\"escaped.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n        self.assertEqual(loader.load(\"unescaped.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n        self.assertEqual(loader.load(\"default.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n\n        self.assertEqual(loader.load(\"include.html\").generate(name=name),\n                         b\"escaped: Bobby &lt;table&gt;s\\n\"\n                         b\"unescaped: Bobby <table>s\\n\"\n                         b\"default: Bobby &lt;table&gt;s\\n\")\n\n    def test_unextended_block(self):\n        loader = DictLoader(self.templates)\n        name = \"<script>\"\n        self.assertEqual(loader.load(\"escaped_block.html\").generate(name=name),\n                         b\"base: &lt;script&gt;\")\n        self.assertEqual(loader.load(\"unescaped_block.html\").generate(name=name),\n                         b\"base: <script>\")\n\n    def test_extended_block(self):\n        loader = DictLoader(self.templates)\n\n        def render(name):\n            return loader.load(name).generate(name=\"<script>\")\n        self.assertEqual(render(\"escaped_extends_unescaped.html\"),\n                         b\"base: <script>\")\n        self.assertEqual(render(\"escaped_overrides_unescaped.html\"),\n                         b\"extended: &lt;script&gt;\")\n\n        self.assertEqual(render(\"unescaped_extends_escaped.html\"),\n                         b\"base: &lt;script&gt;\")\n        self.assertEqual(render(\"unescaped_overrides_escaped.html\"),\n                         b\"extended: <script>\")\n\n    def test_raw_expression(self):\n        loader = DictLoader(self.templates)\n\n        def render(name):\n            return loader.load(name).generate(name='<>&\"')\n        self.assertEqual(render(\"raw_expression.html\"),\n                         b\"expr: &lt;&gt;&amp;&quot;\\n\"\n                         b\"raw: <>&\\\"\")\n\n    def test_custom_escape(self):\n        loader = DictLoader({\"foo.py\":\n                             \"{% autoescape py_escape %}s = {{ name }}\\n\"})\n\n        def py_escape(s):\n            self.assertEqual(type(s), bytes)\n            return repr(native_str(s))\n\n        def render(template, name):\n            return loader.load(template).generate(py_escape=py_escape,\n                                                  name=name)\n        self.assertEqual(render(\"foo.py\", \"<html>\"),\n                         b\"s = '<html>'\\n\")\n        self.assertEqual(render(\"foo.py\", \"';sys.exit()\"),\n                         b\"\"\"s = \"';sys.exit()\"\\n\"\"\")\n        self.assertEqual(render(\"foo.py\", [\"not a string\"]),\n                         b\"\"\"s = \"['not a string']\"\\n\"\"\")\n\n    def test_manual_minimize_whitespace(self):\n        # Whitespace including newlines is allowed within template tags\n        # and directives, and this is one way to avoid long lines while\n        # keeping extra whitespace out of the rendered output.\n        loader = DictLoader({'foo.txt': \"\"\"\\\n{% for i in items\n  %}{% if i > 0 %}, {% end %}{#\n  #}{{i\n  }}{% end\n%}\"\"\",\n                             })\n        self.assertEqual(loader.load(\"foo.txt\").generate(items=range(5)),\n                         b\"0, 1, 2, 3, 4\")\n\n    def test_whitespace_by_filename(self):\n        # Default whitespace handling depends on the template filename.\n        loader = DictLoader({\n            \"foo.html\": \"   \\n\\t\\n asdf\\t   \",\n            \"bar.js\": \" \\n\\n\\n\\t qwer     \",\n            \"baz.txt\": \"\\t    zxcv\\n\\n\",\n            \"include.html\": \"  {% include baz.txt %} \\n \",\n            \"include.txt\": \"\\t\\t{% include foo.html %}    \",\n        })\n\n        # HTML and JS files have whitespace compressed by default.\n        self.assertEqual(loader.load(\"foo.html\").generate(),\n                         b\"\\nasdf \")\n        self.assertEqual(loader.load(\"bar.js\").generate(),\n                         b\"\\nqwer \")\n        # TXT files do not.\n        self.assertEqual(loader.load(\"baz.txt\").generate(),\n                         b\"\\t    zxcv\\n\\n\")\n\n        # Each file maintains its own status even when included in\n        # a file of the other type.\n        self.assertEqual(loader.load(\"include.html\").generate(),\n                         b\" \\t    zxcv\\n\\n\\n\")\n        self.assertEqual(loader.load(\"include.txt\").generate(),\n                         b\"\\t\\t\\nasdf     \")\n\n    def test_whitespace_by_loader(self):\n        templates = {\n            \"foo.html\": \"\\t\\tfoo\",\n            \"bar.txt\": \"\\t\\tbar\",\n            }\n        loader = DictLoader(templates, whitespace='all')\n        self.assertEqual(loader.load(\"foo.html\").generate(), b\"\\t\\tfoo\")\n        self.assertEqual(loader.load(\"bar.txt\").generate(), b\"\\t\\tbar\")\n        loader = DictLoader(templates, whitespace='single')\n        self.assertEqual(loader.load(\"foo.html\").generate(), b\" foo\")\n        self.assertEqual(loader.load(\"bar.txt\").generate(), b\" bar\")\n\n\nclass TemplateLoaderTest(unittest.TestCase):\n    def setUp(self):\n        self.loader = Loader(os.path.join(os.path.dirname(__file__), \"templates\"))\n\n    def test_utf8_in_file(self):\n        tmpl = self.loader.load(\"utf8.html\")\n        result = tmpl.generate()\n        self.assertEqual(to_unicode(result).strip(), u(\"H\\u00e9llo\"))\n",
            "new_file_content": "from __future__ import absolute_import, division, print_function, with_statement\n\nimport os\nimport sys\nimport traceback\n\nfrom tornado.escape import utf8, native_str, to_unicode\nfrom tornado.template import Template, DictLoader, ParseError, Loader\nfrom tornado.test.util import unittest\nfrom tornado.util import u, ObjectDict, unicode_type\n\n\nclass TemplateTest(unittest.TestCase):\n    def test_simple(self):\n        template = Template(\"Hello {{ name }}!\")\n        self.assertEqual(template.generate(name=\"Ben\"),\n                         b\"Hello Ben!\")\n\n    def test_bytes(self):\n        template = Template(\"Hello {{ name }}!\")\n        self.assertEqual(template.generate(name=utf8(\"Ben\")),\n                         b\"Hello Ben!\")\n\n    def test_expressions(self):\n        template = Template(\"2 + 2 = {{ 2 + 2 }}\")\n        self.assertEqual(template.generate(), b\"2 + 2 = 4\")\n\n    def test_comment(self):\n        template = Template(\"Hello{# TODO i18n #} {{ name }}!\")\n        self.assertEqual(template.generate(name=utf8(\"Ben\")),\n                         b\"Hello Ben!\")\n\n    def test_include(self):\n        loader = DictLoader({\n            \"index.html\": '{% include \"header.html\" %}\\nbody text',\n            \"header.html\": \"header text\",\n        })\n        self.assertEqual(loader.load(\"index.html\").generate(),\n                         b\"header text\\nbody text\")\n\n    def test_extends(self):\n        loader = DictLoader({\n            \"base.html\": \"\"\"\\\n<title>{% block title %}default title{% end %}</title>\n<body>{% block body %}default body{% end %}</body>\n\"\"\",\n            \"page.html\": \"\"\"\\\n{% extends \"base.html\" %}\n{% block title %}page title{% end %}\n{% block body %}page body{% end %}\n\"\"\",\n        })\n        self.assertEqual(loader.load(\"page.html\").generate(),\n                         b\"<title>page title</title>\\n<body>page body</body>\\n\")\n\n    def test_relative_load(self):\n        loader = DictLoader({\n            \"a/1.html\": \"{% include '2.html' %}\",\n            \"a/2.html\": \"{% include '../b/3.html' %}\",\n            \"b/3.html\": \"ok\",\n        })\n        self.assertEqual(loader.load(\"a/1.html\").generate(),\n                         b\"ok\")\n\n    def test_escaping(self):\n        self.assertRaises(ParseError, lambda: Template(\"{{\"))\n        self.assertRaises(ParseError, lambda: Template(\"{%\"))\n        self.assertEqual(Template(\"{{!\").generate(), b\"{{\")\n        self.assertEqual(Template(\"{%!\").generate(), b\"{%\")\n        self.assertEqual(Template(\"{{ 'expr' }} {{!jquery expr}}\").generate(),\n                         b\"expr {{jquery expr}}\")\n\n    def test_unicode_template(self):\n        template = Template(utf8(u(\"\\u00e9\")))\n        self.assertEqual(template.generate(), utf8(u(\"\\u00e9\")))\n\n    def test_unicode_literal_expression(self):\n        # Unicode literals should be usable in templates.  Note that this\n        # test simulates unicode characters appearing directly in the\n        # template file (with utf8 encoding), i.e. \\u escapes would not\n        # be used in the template file itself.\n        if str is unicode_type:\n            # python 3 needs a different version of this test since\n            # 2to3 doesn't run on template internals\n            template = Template(utf8(u('{{ \"\\u00e9\" }}')))\n        else:\n            template = Template(utf8(u('{{ u\"\\u00e9\" }}')))\n        self.assertEqual(template.generate(), utf8(u(\"\\u00e9\")))\n\n    def test_custom_namespace(self):\n        loader = DictLoader({\"test.html\": \"{{ inc(5) }}\"}, namespace={\"inc\": lambda x: x + 1})\n        self.assertEqual(loader.load(\"test.html\").generate(), b\"6\")\n\n    def test_apply(self):\n        def upper(s):\n            return s.upper()\n        template = Template(utf8(\"{% apply upper %}foo{% end %}\"))\n        self.assertEqual(template.generate(upper=upper), b\"FOO\")\n\n    def test_unicode_apply(self):\n        def upper(s):\n            return to_unicode(s).upper()\n        template = Template(utf8(u(\"{% apply upper %}foo \\u00e9{% end %}\")))\n        self.assertEqual(template.generate(upper=upper), utf8(u(\"FOO \\u00c9\")))\n\n    def test_bytes_apply(self):\n        def upper(s):\n            return utf8(to_unicode(s).upper())\n        template = Template(utf8(u(\"{% apply upper %}foo \\u00e9{% end %}\")))\n        self.assertEqual(template.generate(upper=upper), utf8(u(\"FOO \\u00c9\")))\n\n    def test_if(self):\n        template = Template(utf8(\"{% if x > 4 %}yes{% else %}no{% end %}\"))\n        self.assertEqual(template.generate(x=5), b\"yes\")\n        self.assertEqual(template.generate(x=3), b\"no\")\n\n    def test_if_empty_body(self):\n        template = Template(utf8(\"{% if True %}{% else %}{% end %}\"))\n        self.assertEqual(template.generate(), b\"\")\n\n    def test_try(self):\n        template = Template(utf8(\"\"\"{% try %}\ntry{% set y = 1/x %}\n{% except %}-except\n{% else %}-else\n{% finally %}-finally\n{% end %}\"\"\"))\n        self.assertEqual(template.generate(x=1), b\"\\ntry\\n-else\\n-finally\\n\")\n        self.assertEqual(template.generate(x=0), b\"\\ntry-except\\n-finally\\n\")\n\n    def test_comment_directive(self):\n        template = Template(utf8(\"{% comment blah blah %}foo\"))\n        self.assertEqual(template.generate(), b\"foo\")\n\n    def test_break_continue(self):\n        template = Template(utf8(\"\"\"\\\n{% for i in range(10) %}\n    {% if i == 2 %}\n        {% continue %}\n    {% end %}\n    {{ i }}\n    {% if i == 6 %}\n        {% break %}\n    {% end %}\n{% end %}\"\"\"))\n        result = template.generate()\n        # remove extraneous whitespace\n        result = b''.join(result.split())\n        self.assertEqual(result, b\"013456\")\n\n    def test_break_outside_loop(self):\n        try:\n            Template(utf8(\"{% break %}\"))\n            raise Exception(\"Did not get expected exception\")\n        except ParseError:\n            pass\n\n    def test_break_in_apply(self):\n        # This test verifies current behavior, although of course it would\n        # be nice if apply didn't cause seemingly unrelated breakage\n        try:\n            Template(utf8(\"{% for i in [] %}{% apply foo %}{% break %}{% end %}{% end %}\"))\n            raise Exception(\"Did not get expected exception\")\n        except ParseError:\n            pass\n\n    @unittest.skipIf(sys.version_info >= division.getMandatoryRelease(),\n                     'no testable future imports')\n    def test_no_inherit_future(self):\n        # This file has from __future__ import division...\n        self.assertEqual(1 / 2, 0.5)\n        # ...but the template doesn't\n        template = Template('{{ 1 / 2 }}')\n        self.assertEqual(template.generate(), '0')\n\n\nclass StackTraceTest(unittest.TestCase):\n    def test_error_line_number_expression(self):\n        loader = DictLoader({\"test.html\": \"\"\"one\ntwo{{1/0}}\nthree\n        \"\"\"})\n        try:\n            loader.load(\"test.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# test.html:2\" in traceback.format_exc())\n\n    def test_error_line_number_directive(self):\n        loader = DictLoader({\"test.html\": \"\"\"one\ntwo{%if 1/0%}\nthree{%end%}\n        \"\"\"})\n        try:\n            loader.load(\"test.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# test.html:2\" in traceback.format_exc())\n\n    def test_error_line_number_module(self):\n        loader = DictLoader({\n            \"base.html\": \"{% module Template('sub.html') %}\",\n            \"sub.html\": \"{{1/0}}\",\n        }, namespace={\"_tt_modules\": ObjectDict({\"Template\": lambda path, **kwargs: loader.load(path).generate(**kwargs)})})\n        try:\n            loader.load(\"base.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            exc_stack = traceback.format_exc()\n            self.assertTrue('# base.html:1' in exc_stack)\n            self.assertTrue('# sub.html:1' in exc_stack)\n\n    def test_error_line_number_include(self):\n        loader = DictLoader({\n            \"base.html\": \"{% include 'sub.html' %}\",\n            \"sub.html\": \"{{1/0}}\",\n        })\n        try:\n            loader.load(\"base.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# sub.html:1 (via base.html:1)\" in\n                            traceback.format_exc())\n\n    def test_error_line_number_extends_base_error(self):\n        loader = DictLoader({\n            \"base.html\": \"{{1/0}}\",\n            \"sub.html\": \"{% extends 'base.html' %}\",\n        })\n        try:\n            loader.load(\"sub.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            exc_stack = traceback.format_exc()\n        self.assertTrue(\"# base.html:1\" in exc_stack)\n\n    def test_error_line_number_extends_sub_error(self):\n        loader = DictLoader({\n            \"base.html\": \"{% block 'block' %}{% end %}\",\n            \"sub.html\": \"\"\"\n{% extends 'base.html' %}\n{% block 'block' %}\n{{1/0}}\n{% end %}\n            \"\"\"})\n        try:\n            loader.load(\"sub.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# sub.html:4 (via base.html:1)\" in\n                            traceback.format_exc())\n\n    def test_multi_includes(self):\n        loader = DictLoader({\n            \"a.html\": \"{% include 'b.html' %}\",\n            \"b.html\": \"{% include 'c.html' %}\",\n            \"c.html\": \"{{1/0}}\",\n        })\n        try:\n            loader.load(\"a.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# c.html:1 (via b.html:1, a.html:1)\" in\n                            traceback.format_exc())\n\n\nclass ParseErrorDetailTest(unittest.TestCase):\n    def test_details(self):\n        loader = DictLoader({\n            \"foo.html\": \"\\n\\n{{\",\n            })\n        with self.assertRaises(ParseError) as cm:\n            loader.load(\"foo.html\")\n        self.assertEqual(\"Missing end expression }} at foo.html:3\",\n                         str(cm.exception))\n        self.assertEqual(\"foo.html\", cm.exception.filename)\n        self.assertEqual(3, cm.exception.lineno)\n\n\nclass AutoEscapeTest(unittest.TestCase):\n    def setUp(self):\n        self.templates = {\n            \"escaped.html\": \"{% autoescape xhtml_escape %}{{ name }}\",\n            \"unescaped.html\": \"{% autoescape None %}{{ name }}\",\n            \"default.html\": \"{{ name }}\",\n\n            \"include.html\": \"\"\"\\\nescaped: {% include 'escaped.html' %}\nunescaped: {% include 'unescaped.html' %}\ndefault: {% include 'default.html' %}\n\"\"\",\n\n            \"escaped_block.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% block name %}base: {{ name }}{% end %}\"\"\",\n            \"unescaped_block.html\": \"\"\"\\\n{% autoescape None %}\\\n{% block name %}base: {{ name }}{% end %}\"\"\",\n\n            # Extend a base template with different autoescape policy,\n            # with and without overriding the base's blocks\n            \"escaped_extends_unescaped.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% extends \"unescaped_block.html\" %}\"\"\",\n            \"escaped_overrides_unescaped.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% extends \"unescaped_block.html\" %}\\\n{% block name %}extended: {{ name }}{% end %}\"\"\",\n            \"unescaped_extends_escaped.html\": \"\"\"\\\n{% autoescape None %}\\\n{% extends \"escaped_block.html\" %}\"\"\",\n            \"unescaped_overrides_escaped.html\": \"\"\"\\\n{% autoescape None %}\\\n{% extends \"escaped_block.html\" %}\\\n{% block name %}extended: {{ name }}{% end %}\"\"\",\n\n            \"raw_expression.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\nexpr: {{ name }}\nraw: {% raw name %}\"\"\",\n        }\n\n    def test_default_off(self):\n        loader = DictLoader(self.templates, autoescape=None)\n        name = \"Bobby <table>s\"\n        self.assertEqual(loader.load(\"escaped.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n        self.assertEqual(loader.load(\"unescaped.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n        self.assertEqual(loader.load(\"default.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n\n        self.assertEqual(loader.load(\"include.html\").generate(name=name),\n                         b\"escaped: Bobby &lt;table&gt;s\\n\"\n                         b\"unescaped: Bobby <table>s\\n\"\n                         b\"default: Bobby <table>s\\n\")\n\n    def test_default_on(self):\n        loader = DictLoader(self.templates, autoescape=\"xhtml_escape\")\n        name = \"Bobby <table>s\"\n        self.assertEqual(loader.load(\"escaped.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n        self.assertEqual(loader.load(\"unescaped.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n        self.assertEqual(loader.load(\"default.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n\n        self.assertEqual(loader.load(\"include.html\").generate(name=name),\n                         b\"escaped: Bobby &lt;table&gt;s\\n\"\n                         b\"unescaped: Bobby <table>s\\n\"\n                         b\"default: Bobby &lt;table&gt;s\\n\")\n\n    def test_unextended_block(self):\n        loader = DictLoader(self.templates)\n        name = \"<script>\"\n        self.assertEqual(loader.load(\"escaped_block.html\").generate(name=name),\n                         b\"base: &lt;script&gt;\")\n        self.assertEqual(loader.load(\"unescaped_block.html\").generate(name=name),\n                         b\"base: <script>\")\n\n    def test_extended_block(self):\n        loader = DictLoader(self.templates)\n\n        def render(name):\n            return loader.load(name).generate(name=\"<script>\")\n        self.assertEqual(render(\"escaped_extends_unescaped.html\"),\n                         b\"base: <script>\")\n        self.assertEqual(render(\"escaped_overrides_unescaped.html\"),\n                         b\"extended: &lt;script&gt;\")\n\n        self.assertEqual(render(\"unescaped_extends_escaped.html\"),\n                         b\"base: &lt;script&gt;\")\n        self.assertEqual(render(\"unescaped_overrides_escaped.html\"),\n                         b\"extended: <script>\")\n\n    def test_raw_expression(self):\n        loader = DictLoader(self.templates)\n\n        def render(name):\n            return loader.load(name).generate(name='<>&\"')\n        self.assertEqual(render(\"raw_expression.html\"),\n                         b\"expr: &lt;&gt;&amp;&quot;\\n\"\n                         b\"raw: <>&\\\"\")\n\n    def test_custom_escape(self):\n        loader = DictLoader({\"foo.py\":\n                             \"{% autoescape py_escape %}s = {{ name }}\\n\"})\n\n        def py_escape(s):\n            self.assertEqual(type(s), bytes)\n            return repr(native_str(s))\n\n        def render(template, name):\n            return loader.load(template).generate(py_escape=py_escape,\n                                                  name=name)\n        self.assertEqual(render(\"foo.py\", \"<html>\"),\n                         b\"s = '<html>'\\n\")\n        self.assertEqual(render(\"foo.py\", \"';sys.exit()\"),\n                         b\"\"\"s = \"';sys.exit()\"\\n\"\"\")\n        self.assertEqual(render(\"foo.py\", [\"not a string\"]),\n                         b\"\"\"s = \"['not a string']\"\\n\"\"\")\n\n    def test_manual_minimize_whitespace(self):\n        # Whitespace including newlines is allowed within template tags\n        # and directives, and this is one way to avoid long lines while\n        # keeping extra whitespace out of the rendered output.\n        loader = DictLoader({'foo.txt': \"\"\"\\\n{% for i in items\n  %}{% if i > 0 %}, {% end %}{#\n  #}{{i\n  }}{% end\n%}\"\"\",\n                             })\n        self.assertEqual(loader.load(\"foo.txt\").generate(items=range(5)),\n                         b\"0, 1, 2, 3, 4\")\n\n    def test_whitespace_by_filename(self):\n        # Default whitespace handling depends on the template filename.\n        loader = DictLoader({\n            \"foo.html\": \"   \\n\\t\\n asdf\\t   \",\n            \"bar.js\": \" \\n\\n\\n\\t qwer     \",\n            \"baz.txt\": \"\\t    zxcv\\n\\n\",\n            \"include.html\": \"  {% include baz.txt %} \\n \",\n            \"include.txt\": \"\\t\\t{% include foo.html %}    \",\n        })\n\n        # HTML and JS files have whitespace compressed by default.\n        self.assertEqual(loader.load(\"foo.html\").generate(),\n                         b\"\\nasdf \")\n        self.assertEqual(loader.load(\"bar.js\").generate(),\n                         b\"\\nqwer \")\n        # TXT files do not.\n        self.assertEqual(loader.load(\"baz.txt\").generate(),\n                         b\"\\t    zxcv\\n\\n\")\n\n        # Each file maintains its own status even when included in\n        # a file of the other type.\n        self.assertEqual(loader.load(\"include.html\").generate(),\n                         b\" \\t    zxcv\\n\\n\\n\")\n        self.assertEqual(loader.load(\"include.txt\").generate(),\n                         b\"\\t\\t\\nasdf     \")\n\n    def test_whitespace_by_loader(self):\n        templates = {\n            \"foo.html\": \"\\t\\tfoo\\n\\n\",\n            \"bar.txt\": \"\\t\\tbar\\n\\n\",\n            }\n        loader = DictLoader(templates, whitespace='all')\n        self.assertEqual(loader.load(\"foo.html\").generate(), b\"\\t\\tfoo\\n\\n\")\n        self.assertEqual(loader.load(\"bar.txt\").generate(), b\"\\t\\tbar\\n\\n\")\n\n        loader = DictLoader(templates, whitespace='single')\n        self.assertEqual(loader.load(\"foo.html\").generate(), b\" foo\\n\")\n        self.assertEqual(loader.load(\"bar.txt\").generate(), b\" bar\\n\")\n\n        loader = DictLoader(templates, whitespace='oneline')\n        self.assertEqual(loader.load(\"foo.html\").generate(), b\" foo \")\n        self.assertEqual(loader.load(\"bar.txt\").generate(), b\" bar \")\n\n\nclass TemplateLoaderTest(unittest.TestCase):\n    def setUp(self):\n        self.loader = Loader(os.path.join(os.path.dirname(__file__), \"templates\"))\n\n    def test_utf8_in_file(self):\n        tmpl = self.loader.load(\"utf8.html\")\n        result = tmpl.generate()\n        self.assertEqual(to_unicode(result).strip(), u(\"H\\u00e9llo\"))\n",
            "header": {
                "file": {
                    "path": "tornado/test/template_test.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "3808bb33",
                "new_commit_hash": "833276ae",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/test/template_test.py"
            },
            "plus_file": {
                "path": "b/tornado/test/template_test.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 442,
                            "length": 15
                        },
                        "new_range": {
                            "start": 442,
                            "length": 20
                        },
                        "section": "raw: {% raw name %}\"\"\","
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_whitespace_by_loader(self):",
                                "type": "context"
                            },
                            {
                                "content": "        templates = {",
                                "type": "context"
                            },
                            {
                                "content": "            \"foo.html\": \"\\t\\tfoo\",",
                                "type": "deleted"
                            },
                            {
                                "content": "            \"bar.txt\": \"\\t\\tbar\",",
                                "type": "deleted"
                            },
                            {
                                "content": "            \"foo.html\": \"\\t\\tfoo\\n\\n\",",
                                "type": "added"
                            },
                            {
                                "content": "            \"bar.txt\": \"\\t\\tbar\\n\\n\",",
                                "type": "added"
                            },
                            {
                                "content": "            }",
                                "type": "context"
                            },
                            {
                                "content": "        loader = DictLoader(templates, whitespace='all')",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(loader.load(\"foo.html\").generate(), b\"\\t\\tfoo\")",
                                "type": "deleted"
                            },
                            {
                                "content": "        self.assertEqual(loader.load(\"bar.txt\").generate(), b\"\\t\\tbar\")",
                                "type": "deleted"
                            },
                            {
                                "content": "        self.assertEqual(loader.load(\"foo.html\").generate(), b\"\\t\\tfoo\\n\\n\")",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(loader.load(\"bar.txt\").generate(), b\"\\t\\tbar\\n\\n\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        loader = DictLoader(templates, whitespace='single')",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(loader.load(\"foo.html\").generate(), b\" foo\")",
                                "type": "deleted"
                            },
                            {
                                "content": "        self.assertEqual(loader.load(\"bar.txt\").generate(), b\" bar\")",
                                "type": "deleted"
                            },
                            {
                                "content": "        self.assertEqual(loader.load(\"foo.html\").generate(), b\" foo\\n\")",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(loader.load(\"bar.txt\").generate(), b\" bar\\n\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        loader = DictLoader(templates, whitespace='oneline')",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(loader.load(\"foo.html\").generate(), b\" foo \")",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(loader.load(\"bar.txt\").generate(), b\" bar \")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "class TemplateLoaderTest(unittest.TestCase):",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/template_test.py",
                            "type": "class",
                            "name": "AutoEscapeTest",
                            "content": "class AutoEscapeTest(unittest.TestCase):\n    def setUp(self):\n        self.templates = {\n            \"escaped.html\": \"{% autoescape xhtml_escape %}{{ name }}\",\n            \"unescaped.html\": \"{% autoescape None %}{{ name }}\",\n            \"default.html\": \"{{ name }}\",\n\n            \"include.html\": \"\"\"\\\nescaped: {% include 'escaped.html' %}\nunescaped: {% include 'unescaped.html' %}\ndefault: {% include 'default.html' %}\n\"\"\",\n\n            \"escaped_block.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% block name %}base: {{ name }}{% end %}\"\"\",\n            \"unescaped_block.html\": \"\"\"\\\n{% autoescape None %}\\\n{% block name %}base: {{ name }}{% end %}\"\"\",\n\n            # Extend a base template with different autoescape policy,\n            # with and without overriding the base's blocks\n            \"escaped_extends_unescaped.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% extends \"unescaped_block.html\" %}\"\"\",\n            \"escaped_overrides_unescaped.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% extends \"unescaped_block.html\" %}\\\n{% block name %}extended: {{ name }}{% end %}\"\"\",\n            \"unescaped_extends_escaped.html\": \"\"\"\\\n{% autoescape None %}\\\n{% extends \"escaped_block.html\" %}\"\"\",\n            \"unescaped_overrides_escaped.html\": \"\"\"\\\n{% autoescape None %}\\\n{% extends \"escaped_block.html\" %}\\\n{% block name %}extended: {{ name }}{% end %}\"\"\",\n\n            \"raw_expression.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\nexpr: {{ name }}\nraw: {% raw name %}\"\"\",\n        }\n\n    def test_default_off(self):\n        loader = DictLoader(self.templates, autoescape=None)\n        name = \"Bobby <table>s\"\n        self.assertEqual(loader.load(\"escaped.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n        self.assertEqual(loader.load(\"unescaped.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n        self.assertEqual(loader.load(\"default.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n\n        self.assertEqual(loader.load(\"include.html\").generate(name=name),\n                         b\"escaped: Bobby &lt;table&gt;s\\n\"\n                         b\"unescaped: Bobby <table>s\\n\"\n                         b\"default: Bobby <table>s\\n\")\n\n    def test_default_on(self):\n        loader = DictLoader(self.templates, autoescape=\"xhtml_escape\")\n        name = \"Bobby <table>s\"\n        self.assertEqual(loader.load(\"escaped.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n        self.assertEqual(loader.load(\"unescaped.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n        self.assertEqual(loader.load(\"default.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n\n        self.assertEqual(loader.load(\"include.html\").generate(name=name),\n                         b\"escaped: Bobby &lt;table&gt;s\\n\"\n                         b\"unescaped: Bobby <table>s\\n\"\n                         b\"default: Bobby &lt;table&gt;s\\n\")\n\n    def test_unextended_block(self):\n        loader = DictLoader(self.templates)\n        name = \"<script>\"\n        self.assertEqual(loader.load(\"escaped_block.html\").generate(name=name),\n                         b\"base: &lt;script&gt;\")\n        self.assertEqual(loader.load(\"unescaped_block.html\").generate(name=name),\n                         b\"base: <script>\")\n\n    def test_extended_block(self):\n        loader = DictLoader(self.templates)\n\n        def render(name):\n            return loader.load(name).generate(name=\"<script>\")\n        self.assertEqual(render(\"escaped_extends_unescaped.html\"),\n                         b\"base: <script>\")\n        self.assertEqual(render(\"escaped_overrides_unescaped.html\"),\n                         b\"extended: &lt;script&gt;\")\n\n        self.assertEqual(render(\"unescaped_extends_escaped.html\"),\n                         b\"base: &lt;script&gt;\")\n        self.assertEqual(render(\"unescaped_overrides_escaped.html\"),\n                         b\"extended: <script>\")\n\n    def test_raw_expression(self):\n        loader = DictLoader(self.templates)\n\n        def render(name):\n            return loader.load(name).generate(name='<>&\"')\n        self.assertEqual(render(\"raw_expression.html\"),\n                         b\"expr: &lt;&gt;&amp;&quot;\\n\"\n                         b\"raw: <>&\\\"\")\n\n    def test_custom_escape(self):\n        loader = DictLoader({\"foo.py\":\n                             \"{% autoescape py_escape %}s = {{ name }}\\n\"})\n\n        def py_escape(s):\n            self.assertEqual(type(s), bytes)\n            return repr(native_str(s))\n\n        def render(template, name):\n            return loader.load(template).generate(py_escape=py_escape,\n                                                  name=name)\n        self.assertEqual(render(\"foo.py\", \"<html>\"),\n                         b\"s = '<html>'\\n\")\n        self.assertEqual(render(\"foo.py\", \"';sys.exit()\"),\n                         b\"\"\"s = \"';sys.exit()\"\\n\"\"\")\n        self.assertEqual(render(\"foo.py\", [\"not a string\"]),\n                         b\"\"\"s = \"['not a string']\"\\n\"\"\")\n\n    def test_manual_minimize_whitespace(self):\n        # Whitespace including newlines is allowed within template tags\n        # and directives, and this is one way to avoid long lines while\n        # keeping extra whitespace out of the rendered output.\n        loader = DictLoader({'foo.txt': \"\"\"\\\n{% for i in items\n  %}{% if i > 0 %}, {% end %}{#\n  #}{{i\n  }}{% end\n%}\"\"\",\n                             })\n        self.assertEqual(loader.load(\"foo.txt\").generate(items=range(5)),\n                         b\"0, 1, 2, 3, 4\")\n\n    def test_whitespace_by_filename(self):\n        # Default whitespace handling depends on the template filename.\n        loader = DictLoader({\n            \"foo.html\": \"   \\n\\t\\n asdf\\t   \",\n            \"bar.js\": \" \\n\\n\\n\\t qwer     \",\n            \"baz.txt\": \"\\t    zxcv\\n\\n\",\n            \"include.html\": \"  {% include baz.txt %} \\n \",\n            \"include.txt\": \"\\t\\t{% include foo.html %}    \",\n        })\n\n        # HTML and JS files have whitespace compressed by default.\n        self.assertEqual(loader.load(\"foo.html\").generate(),\n                         b\"\\nasdf \")\n        self.assertEqual(loader.load(\"bar.js\").generate(),\n                         b\"\\nqwer \")\n        # TXT files do not.\n        self.assertEqual(loader.load(\"baz.txt\").generate(),\n                         b\"\\t    zxcv\\n\\n\")\n\n        # Each file maintains its own status even when included in\n        # a file of the other type.\n        self.assertEqual(loader.load(\"include.html\").generate(),\n                         b\" \\t    zxcv\\n\\n\\n\")\n        self.assertEqual(loader.load(\"include.txt\").generate(),\n                         b\"\\t\\t\\nasdf     \")\n\n    def test_whitespace_by_loader(self):\n        templates = {\n            \"foo.html\": \"\\t\\tfoo\",\n            \"bar.txt\": \"\\t\\tbar\",\n            }\n        loader = DictLoader(templates, whitespace='all')\n        self.assertEqual(loader.load(\"foo.html\").generate(), b\"\\t\\tfoo\")\n        self.assertEqual(loader.load(\"bar.txt\").generate(), b\"\\t\\tbar\")\n        loader = DictLoader(templates, whitespace='single')\n        self.assertEqual(loader.load(\"foo.html\").generate(), b\" foo\")\n        self.assertEqual(loader.load(\"bar.txt\").generate(), b\" bar\")",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 280,
                            "end_lineno": 453,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/test/template_test.py",
                            "type": "method",
                            "name": "AutoEscapeTest.test_whitespace_by_loader",
                            "content": "class AutoEscapeTest(unittest.TestCase):\n    def setUp(self):\n        self.templates = {\n            \"escaped.html\": \"{% autoescape xhtml_escape %}{{ name }}\",\n            \"unescaped.html\": \"{% autoescape None %}{{ name }}\",\n            \"default.html\": \"{{ name }}\",\n\n            \"include.html\": \"\"\"\\\nescaped: {% include 'escaped.html' %}\nunescaped: {% include 'unescaped.html' %}\ndefault: {% include 'default.html' %}\n\"\"\",\n\n            \"escaped_block.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% block name %}base: {{ name }}{% end %}\"\"\",\n            \"unescaped_block.html\": \"\"\"\\\n{% autoescape None %}\\\n{% block name %}base: {{ name }}{% end %}\"\"\",\n\n            # Extend a base template with different autoescape policy,\n            # with and without overriding the base's blocks\n            \"escaped_extends_unescaped.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% extends \"unescaped_block.html\" %}\"\"\",\n            \"escaped_overrides_unescaped.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% extends \"unescaped_block.html\" %}\\\n{% block name %}extended: {{ name }}{% end %}\"\"\",\n            \"unescaped_extends_escaped.html\": \"\"\"\\\n{% autoescape None %}\\\n{% extends \"escaped_block.html\" %}\"\"\",\n            \"unescaped_overrides_escaped.html\": \"\"\"\\\n{% autoescape None %}\\\n{% extends \"escaped_block.html\" %}\\\n{% block name %}extended: {{ name }}{% end %}\"\"\",\n\n            \"raw_expression.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\nexpr: {{ name }}\nraw: {% raw name %}\"\"\",\n        }\n\n    def test_default_off(self):\n        loader = DictLoader(self.templates, autoescape=None)\n        name = \"Bobby <table>s\"\n        self.assertEqual(loader.load(\"escaped.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n        self.assertEqual(loader.load(\"unescaped.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n        self.assertEqual(loader.load(\"default.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n\n        self.assertEqual(loader.load(\"include.html\").generate(name=name),\n                         b\"escaped: Bobby &lt;table&gt;s\\n\"\n                         b\"unescaped: Bobby <table>s\\n\"\n                         b\"default: Bobby <table>s\\n\")\n\n    def test_default_on(self):\n        loader = DictLoader(self.templates, autoescape=\"xhtml_escape\")\n        name = \"Bobby <table>s\"\n        self.assertEqual(loader.load(\"escaped.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n        self.assertEqual(loader.load(\"unescaped.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n        self.assertEqual(loader.load(\"default.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n\n        self.assertEqual(loader.load(\"include.html\").generate(name=name),\n                         b\"escaped: Bobby &lt;table&gt;s\\n\"\n                         b\"unescaped: Bobby <table>s\\n\"\n                         b\"default: Bobby &lt;table&gt;s\\n\")\n\n    def test_unextended_block(self):\n        loader = DictLoader(self.templates)\n        name = \"<script>\"\n        self.assertEqual(loader.load(\"escaped_block.html\").generate(name=name),\n                         b\"base: &lt;script&gt;\")\n        self.assertEqual(loader.load(\"unescaped_block.html\").generate(name=name),\n                         b\"base: <script>\")\n\n    def test_extended_block(self):\n        loader = DictLoader(self.templates)\n\n        def render(name):\n            return loader.load(name).generate(name=\"<script>\")\n        self.assertEqual(render(\"escaped_extends_unescaped.html\"),\n                         b\"base: <script>\")\n        self.assertEqual(render(\"escaped_overrides_unescaped.html\"),\n                         b\"extended: &lt;script&gt;\")\n\n        self.assertEqual(render(\"unescaped_extends_escaped.html\"),\n                         b\"base: &lt;script&gt;\")\n        self.assertEqual(render(\"unescaped_overrides_escaped.html\"),\n                         b\"extended: <script>\")\n\n    def test_raw_expression(self):\n        loader = DictLoader(self.templates)\n\n        def render(name):\n            return loader.load(name).generate(name='<>&\"')\n        self.assertEqual(render(\"raw_expression.html\"),\n                         b\"expr: &lt;&gt;&amp;&quot;\\n\"\n                         b\"raw: <>&\\\"\")\n\n    def test_custom_escape(self):\n        loader = DictLoader({\"foo.py\":\n                             \"{% autoescape py_escape %}s = {{ name }}\\n\"})\n\n        def py_escape(s):\n            self.assertEqual(type(s), bytes)\n            return repr(native_str(s))\n\n        def render(template, name):\n            return loader.load(template).generate(py_escape=py_escape,\n                                                  name=name)\n        self.assertEqual(render(\"foo.py\", \"<html>\"),\n                         b\"s = '<html>'\\n\")\n        self.assertEqual(render(\"foo.py\", \"';sys.exit()\"),\n                         b\"\"\"s = \"';sys.exit()\"\\n\"\"\")\n        self.assertEqual(render(\"foo.py\", [\"not a string\"]),\n                         b\"\"\"s = \"['not a string']\"\\n\"\"\")\n\n    def test_manual_minimize_whitespace(self):\n        # Whitespace including newlines is allowed within template tags\n        # and directives, and this is one way to avoid long lines while\n        # keeping extra whitespace out of the rendered output.\n        loader = DictLoader({'foo.txt': \"\"\"\\\n{% for i in items\n  %}{% if i > 0 %}, {% end %}{#\n  #}{{i\n  }}{% end\n%}\"\"\",\n                             })\n        self.assertEqual(loader.load(\"foo.txt\").generate(items=range(5)),\n                         b\"0, 1, 2, 3, 4\")\n\n    def test_whitespace_by_filename(self):\n        # Default whitespace handling depends on the template filename.\n        loader = DictLoader({\n            \"foo.html\": \"   \\n\\t\\n asdf\\t   \",\n            \"bar.js\": \" \\n\\n\\n\\t qwer     \",\n            \"baz.txt\": \"\\t    zxcv\\n\\n\",\n            \"include.html\": \"  {% include baz.txt %} \\n \",\n            \"include.txt\": \"\\t\\t{% include foo.html %}    \",\n        })\n\n        # HTML and JS files have whitespace compressed by default.\n        self.assertEqual(loader.load(\"foo.html\").generate(),\n                         b\"\\nasdf \")\n        self.assertEqual(loader.load(\"bar.js\").generate(),\n                         b\"\\nqwer \")\n        # TXT files do not.\n        self.assertEqual(loader.load(\"baz.txt\").generate(),\n                         b\"\\t    zxcv\\n\\n\")\n\n        # Each file maintains its own status even when included in\n        # a file of the other type.\n        self.assertEqual(loader.load(\"include.html\").generate(),\n                         b\" \\t    zxcv\\n\\n\\n\")\n        self.assertEqual(loader.load(\"include.txt\").generate(),\n                         b\"\\t\\t\\nasdf     \")\n\n    def test_whitespace_by_loader(self):\n        templates = {\n            \"foo.html\": \"\\t\\tfoo\",\n            \"bar.txt\": \"\\t\\tbar\",\n            }\n        loader = DictLoader(templates, whitespace='all')\n        self.assertEqual(loader.load(\"foo.html\").generate(), b\"\\t\\tfoo\")\n        self.assertEqual(loader.load(\"bar.txt\").generate(), b\"\\t\\tbar\")\n        loader = DictLoader(templates, whitespace='single')\n        self.assertEqual(loader.load(\"foo.html\").generate(), b\" foo\")\n        self.assertEqual(loader.load(\"bar.txt\").generate(), b\" bar\")",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 443,
                            "end_lineno": 453,
                            "parent": {
                                "file_name": "tornado/test/template_test.py",
                                "type": "class",
                                "name": "AutoEscapeTest",
                                "content": "class AutoEscapeTest(unittest.TestCase):\n    def setUp(self):\n        self.templates = {\n            \"escaped.html\": \"{% autoescape xhtml_escape %}{{ name }}\",\n            \"unescaped.html\": \"{% autoescape None %}{{ name }}\",\n            \"default.html\": \"{{ name }}\",\n\n            \"include.html\": \"\"\"\\\nescaped: {% include 'escaped.html' %}\nunescaped: {% include 'unescaped.html' %}\ndefault: {% include 'default.html' %}\n\"\"\",\n\n            \"escaped_block.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% block name %}base: {{ name }}{% end %}\"\"\",\n            \"unescaped_block.html\": \"\"\"\\\n{% autoescape None %}\\\n{% block name %}base: {{ name }}{% end %}\"\"\",\n\n            # Extend a base template with different autoescape policy,\n            # with and without overriding the base's blocks\n            \"escaped_extends_unescaped.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% extends \"unescaped_block.html\" %}\"\"\",\n            \"escaped_overrides_unescaped.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% extends \"unescaped_block.html\" %}\\\n{% block name %}extended: {{ name }}{% end %}\"\"\",\n            \"unescaped_extends_escaped.html\": \"\"\"\\\n{% autoescape None %}\\\n{% extends \"escaped_block.html\" %}\"\"\",\n            \"unescaped_overrides_escaped.html\": \"\"\"\\\n{% autoescape None %}\\\n{% extends \"escaped_block.html\" %}\\\n{% block name %}extended: {{ name }}{% end %}\"\"\",\n\n            \"raw_expression.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\nexpr: {{ name }}\nraw: {% raw name %}\"\"\",\n        }\n\n    def test_default_off(self):\n        loader = DictLoader(self.templates, autoescape=None)\n        name = \"Bobby <table>s\"\n        self.assertEqual(loader.load(\"escaped.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n        self.assertEqual(loader.load(\"unescaped.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n        self.assertEqual(loader.load(\"default.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n\n        self.assertEqual(loader.load(\"include.html\").generate(name=name),\n                         b\"escaped: Bobby &lt;table&gt;s\\n\"\n                         b\"unescaped: Bobby <table>s\\n\"\n                         b\"default: Bobby <table>s\\n\")\n\n    def test_default_on(self):\n        loader = DictLoader(self.templates, autoescape=\"xhtml_escape\")\n        name = \"Bobby <table>s\"\n        self.assertEqual(loader.load(\"escaped.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n        self.assertEqual(loader.load(\"unescaped.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n        self.assertEqual(loader.load(\"default.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n\n        self.assertEqual(loader.load(\"include.html\").generate(name=name),\n                         b\"escaped: Bobby &lt;table&gt;s\\n\"\n                         b\"unescaped: Bobby <table>s\\n\"\n                         b\"default: Bobby &lt;table&gt;s\\n\")\n\n    def test_unextended_block(self):\n        loader = DictLoader(self.templates)\n        name = \"<script>\"\n        self.assertEqual(loader.load(\"escaped_block.html\").generate(name=name),\n                         b\"base: &lt;script&gt;\")\n        self.assertEqual(loader.load(\"unescaped_block.html\").generate(name=name),\n                         b\"base: <script>\")\n\n    def test_extended_block(self):\n        loader = DictLoader(self.templates)\n\n        def render(name):\n            return loader.load(name).generate(name=\"<script>\")\n        self.assertEqual(render(\"escaped_extends_unescaped.html\"),\n                         b\"base: <script>\")\n        self.assertEqual(render(\"escaped_overrides_unescaped.html\"),\n                         b\"extended: &lt;script&gt;\")\n\n        self.assertEqual(render(\"unescaped_extends_escaped.html\"),\n                         b\"base: &lt;script&gt;\")\n        self.assertEqual(render(\"unescaped_overrides_escaped.html\"),\n                         b\"extended: <script>\")\n\n    def test_raw_expression(self):\n        loader = DictLoader(self.templates)\n\n        def render(name):\n            return loader.load(name).generate(name='<>&\"')\n        self.assertEqual(render(\"raw_expression.html\"),\n                         b\"expr: &lt;&gt;&amp;&quot;\\n\"\n                         b\"raw: <>&\\\"\")\n\n    def test_custom_escape(self):\n        loader = DictLoader({\"foo.py\":\n                             \"{% autoescape py_escape %}s = {{ name }}\\n\"})\n\n        def py_escape(s):\n            self.assertEqual(type(s), bytes)\n            return repr(native_str(s))\n\n        def render(template, name):\n            return loader.load(template).generate(py_escape=py_escape,\n                                                  name=name)\n        self.assertEqual(render(\"foo.py\", \"<html>\"),\n                         b\"s = '<html>'\\n\")\n        self.assertEqual(render(\"foo.py\", \"';sys.exit()\"),\n                         b\"\"\"s = \"';sys.exit()\"\\n\"\"\")\n        self.assertEqual(render(\"foo.py\", [\"not a string\"]),\n                         b\"\"\"s = \"['not a string']\"\\n\"\"\")\n\n    def test_manual_minimize_whitespace(self):\n        # Whitespace including newlines is allowed within template tags\n        # and directives, and this is one way to avoid long lines while\n        # keeping extra whitespace out of the rendered output.\n        loader = DictLoader({'foo.txt': \"\"\"\\\n{% for i in items\n  %}{% if i > 0 %}, {% end %}{#\n  #}{{i\n  }}{% end\n%}\"\"\",\n                             })\n        self.assertEqual(loader.load(\"foo.txt\").generate(items=range(5)),\n                         b\"0, 1, 2, 3, 4\")\n\n    def test_whitespace_by_filename(self):\n        # Default whitespace handling depends on the template filename.\n        loader = DictLoader({\n            \"foo.html\": \"   \\n\\t\\n asdf\\t   \",\n            \"bar.js\": \" \\n\\n\\n\\t qwer     \",\n            \"baz.txt\": \"\\t    zxcv\\n\\n\",\n            \"include.html\": \"  {% include baz.txt %} \\n \",\n            \"include.txt\": \"\\t\\t{% include foo.html %}    \",\n        })\n\n        # HTML and JS files have whitespace compressed by default.\n        self.assertEqual(loader.load(\"foo.html\").generate(),\n                         b\"\\nasdf \")\n        self.assertEqual(loader.load(\"bar.js\").generate(),\n                         b\"\\nqwer \")\n        # TXT files do not.\n        self.assertEqual(loader.load(\"baz.txt\").generate(),\n                         b\"\\t    zxcv\\n\\n\")\n\n        # Each file maintains its own status even when included in\n        # a file of the other type.\n        self.assertEqual(loader.load(\"include.html\").generate(),\n                         b\" \\t    zxcv\\n\\n\\n\")\n        self.assertEqual(loader.load(\"include.txt\").generate(),\n                         b\"\\t\\t\\nasdf     \")\n\n    def test_whitespace_by_loader(self):\n        templates = {\n            \"foo.html\": \"\\t\\tfoo\",\n            \"bar.txt\": \"\\t\\tbar\",\n            }\n        loader = DictLoader(templates, whitespace='all')\n        self.assertEqual(loader.load(\"foo.html\").generate(), b\"\\t\\tfoo\")\n        self.assertEqual(loader.load(\"bar.txt\").generate(), b\"\\t\\tbar\")\n        loader = DictLoader(templates, whitespace='single')\n        self.assertEqual(loader.load(\"foo.html\").generate(), b\" foo\")\n        self.assertEqual(loader.load(\"bar.txt\").generate(), b\" bar\")",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 280,
                                "end_lineno": 453,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "254783a0da0f395c46423094170bb7cabba8a8f3^",
    "new_commit_hash": "254783a0da0f395c46423094170bb7cabba8a8f3",
    "commit_message": "Introduce `oneline` template whitespace mode.\n\nThis slightly-more-aggressive whitespace removal doesn't actually\nsave any space, but it removes the very conspicuous blank lines\nthat are often left around template directives.\n\nCloses #291.\nCloses #1083.",
    "commit_date": "2015-07-05T17:13:07-04:00",
    "metadata": {}
}
{
    "repo_name": "tornado",
    "new_commit_hash": "254783a0da0f395c46423094170bb7cabba8a8f3",
    "test_file_codes": [
        "from __future__ import absolute_import, division, print_function, with_statement\n\nimport os\nimport sys\nimport traceback\n\nfrom tornado.escape import utf8, native_str, to_unicode\nfrom tornado.template import Template, DictLoader, ParseError, Loader\nfrom tornado.test.util import unittest\nfrom tornado.util import u, ObjectDict, unicode_type\n\n\nclass TemplateTest(unittest.TestCase):\n    def test_simple(self):\n        template = Template(\"Hello {{ name }}!\")\n        self.assertEqual(template.generate(name=\"Ben\"),\n                         b\"Hello Ben!\")\n\n    def test_bytes(self):\n        template = Template(\"Hello {{ name }}!\")\n        self.assertEqual(template.generate(name=utf8(\"Ben\")),\n                         b\"Hello Ben!\")\n\n    def test_expressions(self):\n        template = Template(\"2 + 2 = {{ 2 + 2 }}\")\n        self.assertEqual(template.generate(), b\"2 + 2 = 4\")\n\n    def test_comment(self):\n        template = Template(\"Hello{# TODO i18n #} {{ name }}!\")\n        self.assertEqual(template.generate(name=utf8(\"Ben\")),\n                         b\"Hello Ben!\")\n\n    def test_include(self):\n        loader = DictLoader({\n            \"index.html\": '{% include \"header.html\" %}\\nbody text',\n            \"header.html\": \"header text\",\n        })\n        self.assertEqual(loader.load(\"index.html\").generate(),\n                         b\"header text\\nbody text\")\n\n    def test_extends(self):\n        loader = DictLoader({\n            \"base.html\": \"\"\"\\\n<title>{% block title %}default title{% end %}</title>\n<body>{% block body %}default body{% end %}</body>\n\"\"\",\n            \"page.html\": \"\"\"\\\n{% extends \"base.html\" %}\n{% block title %}page title{% end %}\n{% block body %}page body{% end %}\n\"\"\",\n        })\n        self.assertEqual(loader.load(\"page.html\").generate(),\n                         b\"<title>page title</title>\\n<body>page body</body>\\n\")\n\n    def test_relative_load(self):\n        loader = DictLoader({\n            \"a/1.html\": \"{% include '2.html' %}\",\n            \"a/2.html\": \"{% include '../b/3.html' %}\",\n            \"b/3.html\": \"ok\",\n        })\n        self.assertEqual(loader.load(\"a/1.html\").generate(),\n                         b\"ok\")\n\n    def test_escaping(self):\n        self.assertRaises(ParseError, lambda: Template(\"{{\"))\n        self.assertRaises(ParseError, lambda: Template(\"{%\"))\n        self.assertEqual(Template(\"{{!\").generate(), b\"{{\")\n        self.assertEqual(Template(\"{%!\").generate(), b\"{%\")\n        self.assertEqual(Template(\"{{ 'expr' }} {{!jquery expr}}\").generate(),\n                         b\"expr {{jquery expr}}\")\n\n    def test_unicode_template(self):\n        template = Template(utf8(u(\"\\u00e9\")))\n        self.assertEqual(template.generate(), utf8(u(\"\\u00e9\")))\n\n    def test_unicode_literal_expression(self):\n        # Unicode literals should be usable in templates.  Note that this\n        # test simulates unicode characters appearing directly in the\n        # template file (with utf8 encoding), i.e. \\u escapes would not\n        # be used in the template file itself.\n        if str is unicode_type:\n            # python 3 needs a different version of this test since\n            # 2to3 doesn't run on template internals\n            template = Template(utf8(u('{{ \"\\u00e9\" }}')))\n        else:\n            template = Template(utf8(u('{{ u\"\\u00e9\" }}')))\n        self.assertEqual(template.generate(), utf8(u(\"\\u00e9\")))\n\n    def test_custom_namespace(self):\n        loader = DictLoader({\"test.html\": \"{{ inc(5) }}\"}, namespace={\"inc\": lambda x: x + 1})\n        self.assertEqual(loader.load(\"test.html\").generate(), b\"6\")\n\n    def test_apply(self):\n        def upper(s):\n            return s.upper()\n        template = Template(utf8(\"{% apply upper %}foo{% end %}\"))\n        self.assertEqual(template.generate(upper=upper), b\"FOO\")\n\n    def test_unicode_apply(self):\n        def upper(s):\n            return to_unicode(s).upper()\n        template = Template(utf8(u(\"{% apply upper %}foo \\u00e9{% end %}\")))\n        self.assertEqual(template.generate(upper=upper), utf8(u(\"FOO \\u00c9\")))\n\n    def test_bytes_apply(self):\n        def upper(s):\n            return utf8(to_unicode(s).upper())\n        template = Template(utf8(u(\"{% apply upper %}foo \\u00e9{% end %}\")))\n        self.assertEqual(template.generate(upper=upper), utf8(u(\"FOO \\u00c9\")))\n\n    def test_if(self):\n        template = Template(utf8(\"{% if x > 4 %}yes{% else %}no{% end %}\"))\n        self.assertEqual(template.generate(x=5), b\"yes\")\n        self.assertEqual(template.generate(x=3), b\"no\")\n\n    def test_if_empty_body(self):\n        template = Template(utf8(\"{% if True %}{% else %}{% end %}\"))\n        self.assertEqual(template.generate(), b\"\")\n\n    def test_try(self):\n        template = Template(utf8(\"\"\"{% try %}\ntry{% set y = 1/x %}\n{% except %}-except\n{% else %}-else\n{% finally %}-finally\n{% end %}\"\"\"))\n        self.assertEqual(template.generate(x=1), b\"\\ntry\\n-else\\n-finally\\n\")\n        self.assertEqual(template.generate(x=0), b\"\\ntry-except\\n-finally\\n\")\n\n    def test_comment_directive(self):\n        template = Template(utf8(\"{% comment blah blah %}foo\"))\n        self.assertEqual(template.generate(), b\"foo\")\n\n    def test_break_continue(self):\n        template = Template(utf8(\"\"\"\\\n{% for i in range(10) %}\n    {% if i == 2 %}\n        {% continue %}\n    {% end %}\n    {{ i }}\n    {% if i == 6 %}\n        {% break %}\n    {% end %}\n{% end %}\"\"\"))\n        result = template.generate()\n        # remove extraneous whitespace\n        result = b''.join(result.split())\n        self.assertEqual(result, b\"013456\")\n\n    def test_break_outside_loop(self):\n        try:\n            Template(utf8(\"{% break %}\"))\n            raise Exception(\"Did not get expected exception\")\n        except ParseError:\n            pass\n\n    def test_break_in_apply(self):\n        # This test verifies current behavior, although of course it would\n        # be nice if apply didn't cause seemingly unrelated breakage\n        try:\n            Template(utf8(\"{% for i in [] %}{% apply foo %}{% break %}{% end %}{% end %}\"))\n            raise Exception(\"Did not get expected exception\")\n        except ParseError:\n            pass\n\n    @unittest.skipIf(sys.version_info >= division.getMandatoryRelease(),\n                     'no testable future imports')\n    def test_no_inherit_future(self):\n        # This file has from __future__ import division...\n        self.assertEqual(1 / 2, 0.5)\n        # ...but the template doesn't\n        template = Template('{{ 1 / 2 }}')\n        self.assertEqual(template.generate(), '0')\n\n\nclass StackTraceTest(unittest.TestCase):\n    def test_error_line_number_expression(self):\n        loader = DictLoader({\"test.html\": \"\"\"one\ntwo{{1/0}}\nthree\n        \"\"\"})\n        try:\n            loader.load(\"test.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# test.html:2\" in traceback.format_exc())\n\n    def test_error_line_number_directive(self):\n        loader = DictLoader({\"test.html\": \"\"\"one\ntwo{%if 1/0%}\nthree{%end%}\n        \"\"\"})\n        try:\n            loader.load(\"test.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# test.html:2\" in traceback.format_exc())\n\n    def test_error_line_number_module(self):\n        loader = DictLoader({\n            \"base.html\": \"{% module Template('sub.html') %}\",\n            \"sub.html\": \"{{1/0}}\",\n        }, namespace={\"_tt_modules\": ObjectDict({\"Template\": lambda path, **kwargs: loader.load(path).generate(**kwargs)})})\n        try:\n            loader.load(\"base.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            exc_stack = traceback.format_exc()\n            self.assertTrue('# base.html:1' in exc_stack)\n            self.assertTrue('# sub.html:1' in exc_stack)\n\n    def test_error_line_number_include(self):\n        loader = DictLoader({\n            \"base.html\": \"{% include 'sub.html' %}\",\n            \"sub.html\": \"{{1/0}}\",\n        })\n        try:\n            loader.load(\"base.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# sub.html:1 (via base.html:1)\" in\n                            traceback.format_exc())\n\n    def test_error_line_number_extends_base_error(self):\n        loader = DictLoader({\n            \"base.html\": \"{{1/0}}\",\n            \"sub.html\": \"{% extends 'base.html' %}\",\n        })\n        try:\n            loader.load(\"sub.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            exc_stack = traceback.format_exc()\n        self.assertTrue(\"# base.html:1\" in exc_stack)\n\n    def test_error_line_number_extends_sub_error(self):\n        loader = DictLoader({\n            \"base.html\": \"{% block 'block' %}{% end %}\",\n            \"sub.html\": \"\"\"\n{% extends 'base.html' %}\n{% block 'block' %}\n{{1/0}}\n{% end %}\n            \"\"\"})\n        try:\n            loader.load(\"sub.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# sub.html:4 (via base.html:1)\" in\n                            traceback.format_exc())\n\n    def test_multi_includes(self):\n        loader = DictLoader({\n            \"a.html\": \"{% include 'b.html' %}\",\n            \"b.html\": \"{% include 'c.html' %}\",\n            \"c.html\": \"{{1/0}}\",\n        })\n        try:\n            loader.load(\"a.html\").generate()\n            self.fail(\"did not get expected exception\")\n        except ZeroDivisionError:\n            self.assertTrue(\"# c.html:1 (via b.html:1, a.html:1)\" in\n                            traceback.format_exc())\n\n\nclass ParseErrorDetailTest(unittest.TestCase):\n    def test_details(self):\n        loader = DictLoader({\n            \"foo.html\": \"\\n\\n{{\",\n            })\n        with self.assertRaises(ParseError) as cm:\n            loader.load(\"foo.html\")\n        self.assertEqual(\"Missing end expression }} at foo.html:3\",\n                         str(cm.exception))\n        self.assertEqual(\"foo.html\", cm.exception.filename)\n        self.assertEqual(3, cm.exception.lineno)\n\n\nclass AutoEscapeTest(unittest.TestCase):\n    def setUp(self):\n        self.templates = {\n            \"escaped.html\": \"{% autoescape xhtml_escape %}{{ name }}\",\n            \"unescaped.html\": \"{% autoescape None %}{{ name }}\",\n            \"default.html\": \"{{ name }}\",\n\n            \"include.html\": \"\"\"\\\nescaped: {% include 'escaped.html' %}\nunescaped: {% include 'unescaped.html' %}\ndefault: {% include 'default.html' %}\n\"\"\",\n\n            \"escaped_block.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% block name %}base: {{ name }}{% end %}\"\"\",\n            \"unescaped_block.html\": \"\"\"\\\n{% autoescape None %}\\\n{% block name %}base: {{ name }}{% end %}\"\"\",\n\n            # Extend a base template with different autoescape policy,\n            # with and without overriding the base's blocks\n            \"escaped_extends_unescaped.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% extends \"unescaped_block.html\" %}\"\"\",\n            \"escaped_overrides_unescaped.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\n{% extends \"unescaped_block.html\" %}\\\n{% block name %}extended: {{ name }}{% end %}\"\"\",\n            \"unescaped_extends_escaped.html\": \"\"\"\\\n{% autoescape None %}\\\n{% extends \"escaped_block.html\" %}\"\"\",\n            \"unescaped_overrides_escaped.html\": \"\"\"\\\n{% autoescape None %}\\\n{% extends \"escaped_block.html\" %}\\\n{% block name %}extended: {{ name }}{% end %}\"\"\",\n\n            \"raw_expression.html\": \"\"\"\\\n{% autoescape xhtml_escape %}\\\nexpr: {{ name }}\nraw: {% raw name %}\"\"\",\n        }\n\n    def test_default_off(self):\n        loader = DictLoader(self.templates, autoescape=None)\n        name = \"Bobby <table>s\"\n        self.assertEqual(loader.load(\"escaped.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n        self.assertEqual(loader.load(\"unescaped.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n        self.assertEqual(loader.load(\"default.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n\n        self.assertEqual(loader.load(\"include.html\").generate(name=name),\n                         b\"escaped: Bobby &lt;table&gt;s\\n\"\n                         b\"unescaped: Bobby <table>s\\n\"\n                         b\"default: Bobby <table>s\\n\")\n\n    def test_default_on(self):\n        loader = DictLoader(self.templates, autoescape=\"xhtml_escape\")\n        name = \"Bobby <table>s\"\n        self.assertEqual(loader.load(\"escaped.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n        self.assertEqual(loader.load(\"unescaped.html\").generate(name=name),\n                         b\"Bobby <table>s\")\n        self.assertEqual(loader.load(\"default.html\").generate(name=name),\n                         b\"Bobby &lt;table&gt;s\")\n\n        self.assertEqual(loader.load(\"include.html\").generate(name=name),\n                         b\"escaped: Bobby &lt;table&gt;s\\n\"\n                         b\"unescaped: Bobby <table>s\\n\"\n                         b\"default: Bobby &lt;table&gt;s\\n\")\n\n    def test_unextended_block(self):\n        loader = DictLoader(self.templates)\n        name = \"<script>\"\n        self.assertEqual(loader.load(\"escaped_block.html\").generate(name=name),\n                         b\"base: &lt;script&gt;\")\n        self.assertEqual(loader.load(\"unescaped_block.html\").generate(name=name),\n                         b\"base: <script>\")\n\n    def test_extended_block(self):\n        loader = DictLoader(self.templates)\n\n        def render(name):\n            return loader.load(name).generate(name=\"<script>\")\n        self.assertEqual(render(\"escaped_extends_unescaped.html\"),\n                         b\"base: <script>\")\n        self.assertEqual(render(\"escaped_overrides_unescaped.html\"),\n                         b\"extended: &lt;script&gt;\")\n\n        self.assertEqual(render(\"unescaped_extends_escaped.html\"),\n                         b\"base: &lt;script&gt;\")\n        self.assertEqual(render(\"unescaped_overrides_escaped.html\"),\n                         b\"extended: <script>\")\n\n    def test_raw_expression(self):\n        loader = DictLoader(self.templates)\n\n        def render(name):\n            return loader.load(name).generate(name='<>&\"')\n        self.assertEqual(render(\"raw_expression.html\"),\n                         b\"expr: &lt;&gt;&amp;&quot;\\n\"\n                         b\"raw: <>&\\\"\")\n\n    def test_custom_escape(self):\n        loader = DictLoader({\"foo.py\":\n                             \"{% autoescape py_escape %}s = {{ name }}\\n\"})\n\n        def py_escape(s):\n            self.assertEqual(type(s), bytes)\n            return repr(native_str(s))\n\n        def render(template, name):\n            return loader.load(template).generate(py_escape=py_escape,\n                                                  name=name)\n        self.assertEqual(render(\"foo.py\", \"<html>\"),\n                         b\"s = '<html>'\\n\")\n        self.assertEqual(render(\"foo.py\", \"';sys.exit()\"),\n                         b\"\"\"s = \"';sys.exit()\"\\n\"\"\")\n        self.assertEqual(render(\"foo.py\", [\"not a string\"]),\n                         b\"\"\"s = \"['not a string']\"\\n\"\"\")\n\n    def test_manual_minimize_whitespace(self):\n        # Whitespace including newlines is allowed within template tags\n        # and directives, and this is one way to avoid long lines while\n        # keeping extra whitespace out of the rendered output.\n        loader = DictLoader({'foo.txt': \"\"\"\\\n{% for i in items\n  %}{% if i > 0 %}, {% end %}{#\n  #}{{i\n  }}{% end\n%}\"\"\",\n                             })\n        self.assertEqual(loader.load(\"foo.txt\").generate(items=range(5)),\n                         b\"0, 1, 2, 3, 4\")\n\n    def test_whitespace_by_filename(self):\n        # Default whitespace handling depends on the template filename.\n        loader = DictLoader({\n            \"foo.html\": \"   \\n\\t\\n asdf\\t   \",\n            \"bar.js\": \" \\n\\n\\n\\t qwer     \",\n            \"baz.txt\": \"\\t    zxcv\\n\\n\",\n            \"include.html\": \"  {% include baz.txt %} \\n \",\n            \"include.txt\": \"\\t\\t{% include foo.html %}    \",\n        })\n\n        # HTML and JS files have whitespace compressed by default.\n        self.assertEqual(loader.load(\"foo.html\").generate(),\n                         b\"\\nasdf \")\n        self.assertEqual(loader.load(\"bar.js\").generate(),\n                         b\"\\nqwer \")\n        # TXT files do not.\n        self.assertEqual(loader.load(\"baz.txt\").generate(),\n                         b\"\\t    zxcv\\n\\n\")\n\n        # Each file maintains its own status even when included in\n        # a file of the other type.\n        self.assertEqual(loader.load(\"include.html\").generate(),\n                         b\" \\t    zxcv\\n\\n\\n\")\n        self.assertEqual(loader.load(\"include.txt\").generate(),\n                         b\"\\t\\t\\nasdf     \")\n\n    def test_whitespace_by_loader(self):\n        templates = {\n            \"foo.html\": \"\\t\\tfoo\\n\\n\",\n            \"bar.txt\": \"\\t\\tbar\\n\\n\",\n            }\n        loader = DictLoader(templates, whitespace='all')\n        self.assertEqual(loader.load(\"foo.html\").generate(), b\"\\t\\tfoo\\n\\n\")\n        self.assertEqual(loader.load(\"bar.txt\").generate(), b\"\\t\\tbar\\n\\n\")\n\n        loader = DictLoader(templates, whitespace='single')\n        self.assertEqual(loader.load(\"foo.html\").generate(), b\" foo\\n\")\n        self.assertEqual(loader.load(\"bar.txt\").generate(), b\" bar\\n\")\n\n        loader = DictLoader(templates, whitespace='oneline')\n        self.assertEqual(loader.load(\"foo.html\").generate(), b\" foo \")\n        self.assertEqual(loader.load(\"bar.txt\").generate(), b\" bar \")\n\n\nclass TemplateLoaderTest(unittest.TestCase):\n    def setUp(self):\n        self.loader = Loader(os.path.join(os.path.dirname(__file__), \"templates\"))\n\n    def test_utf8_in_file(self):\n        tmpl = self.loader.load(\"utf8.html\")\n        result = tmpl.generate()\n        self.assertEqual(to_unicode(result).strip(), u(\"H\\u00e9llo\"))\n",
        "#!/usr/bin/env python\nimport unittest\nimport sys\nimport time\nimport traceback\nimport platform\nimport os\n\n\nclass PytestLikeResult(unittest.TestResult):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.start_time = None\n        # Store (test, outcome, info) for each test:\n        #   outcome ∈ { \"passed\", \"failed\", \"error\", \"skipped\" }\n        #   info can hold the exception or skip reason, etc.\n        self.results = []\n\n    def startTestRun(self):\n        \"\"\"Called once before all tests.\"\"\"\n        self.start_time = time.time()\n        # Print a header similar to pytest\n        print(\"=\" * 29 + \" test session starts \" + \"=\" * 29)\n        # You can customize the platform/versions/paths as you like:\n        print(\n            f\"platform {platform.system().lower()} -- Python {platform.python_version()}\"\n        )\n        print(f\"rootdir: {os.path.abspath(os.curdir)}\")\n\n    def stopTestRun(self):\n        \"\"\"Called once after all tests are done.\"\"\"\n        elapsed = time.time() - self.start_time\n        print()  # blank line after final dot\n\n        # Summarize\n        ntests = len(self.results)\n        print(f\"collected {ntests} items\")\n\n        # Show details of failures/errors\n        failures = [r for r in self.results if r[1] == \"failed\"]\n        errors = [r for r in self.results if r[1] == \"error\"]\n\n        if failures:\n            print(\"\\n\" + \"=\" * 35 + \" FAILURES \" + \"=\" * 35)\n            for test, outcome, err_info in failures:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n        if errors:\n            print(\"\\n\" + \"=\" * 35 + \" ERRORS \" + \"=\" * 37)\n            for test, outcome, err_info in errors:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n\n        # Optional short summary lines for passes/fails/skips\n        print(\"\\n==================== short test summary info ====================\")\n        for test, outcome, info in self.results:\n            if outcome in (\"passed\", \"failed\", \"error\", \"skipped\"):\n                print(f\"{outcome.upper()} {test}\")\n\n        # Final one-line summary: “1 failed, 1 errors, 10 passed in 2.04s”\n        passed_count = sum(1 for r in self.results if r[1] == \"passed\")\n        failed_count = len(failures)\n        error_count = len(errors)\n        skipped_count = sum(1 for r in self.results if r[1] == \"skipped\")\n\n        summary_bits = []\n        if failed_count:\n            summary_bits.append(f\"{failed_count} failed\")\n        if error_count:\n            summary_bits.append(f\"{error_count} error{'s' if error_count != 1 else ''}\")\n        if passed_count:\n            summary_bits.append(f\"{passed_count} passed\")\n        if skipped_count:\n            summary_bits.append(f\"{skipped_count} skipped\")\n\n        summary_str = \", \".join(summary_bits) if summary_bits else \"no tests run\"\n        print(\n            f\"=================== {summary_str} in {elapsed:.2f}s ===================\"\n        )\n\n    def startTest(self, test):\n        \"\"\"Called right before each test method.\"\"\"\n        super().startTest(test)\n        # Print a dot or some indicator\n        print(\".\", end=\"\", flush=True)\n\n    def addSuccess(self, test):\n        super().addSuccess(test)\n        self.results.append((self._test_id(test), \"passed\", None))\n\n    def addFailure(self, test, err):\n        super().addFailure(test, err)\n        self.results.append((self._test_id(test), \"failed\", err))\n\n    def addError(self, test, err):\n        super().addError(test, err)\n        self.results.append((self._test_id(test), \"error\", err))\n\n    def addSkip(self, test, reason):\n        super().addSkip(test, reason)\n        self.results.append((self._test_id(test), \"skipped\", reason))\n\n    def _print_traceback(self, err_info):\n        \"\"\"Helper to print the traceback like pytest does.\"\"\"\n        if isinstance(err_info, tuple) and len(err_info) == 3:\n            exc_type, exc_value, tb = err_info\n            traceback.print_exception(exc_type, exc_value, tb, file=sys.stdout)\n        else:\n            print(str(err_info))\n\n    def _test_id(self, test):\n        try:\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}::{test._testMethodName}\"\n        except AttributeError:\n            # Fallback for _ErrorHolder objects\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}\"\n\n\nclass PytestLikeRunner(unittest.TextTestRunner):\n    \"\"\"A custom TextTestRunner that uses the PytestLikeResult.\"\"\"\n\n    resultclass = PytestLikeResult\n\n    def run(self, test):\n        result = self._makeResult()\n        # Overriding run to ensure we call startTestRun/stopTestRun\n        result.startTestRun()\n        test(result)\n        result.stopTestRun()\n        return result\n\n    def tearDown(self):\n        # Reset signal handlers\n        from twisted.internet import reactor\n\n        reactor.removeAll()\n        reactor.stop()\n        super().tearDown()\n\n\ndef main():\n    loader = unittest.TestLoader()\n    suite = loader.discover(\".\", pattern=\"test_*.py\")  # discover tests in r2e_tests/\n    runner = PytestLikeRunner(verbosity=0)\n    result = runner.run(suite)\n    # Exit with code 0 if all tests passed/skipped, 1 if there were fails/errors\n    sys.exit(not result.wasSuccessful())\n\n\nif __name__ == \"__main__\":\n    main()\n"
    ],
    "test_file_names": [
        "test_1.py",
        "tornado_unittest_runner.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "",
    "setup_res_stderr": "Using CPython 3.9.21\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 1 package in 903ms\nPrepared 1 package in 1.43s\nInstalled 1 package in 6ms\n + tornado==4.3.dev1 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3)\nResolved 29 packages in 15ms\nInstalled 29 packages in 108ms\n + attrs==24.3.0\n + automat==24.8.1\n + cachetools==5.5.0\n + cffi==1.17.1\n + chardet==5.2.0\n + colorama==0.4.6\n + constantly==23.10.4\n + distlib==0.3.9\n + exceptiongroup==1.2.2\n + filelock==3.16.1\n + hyperlink==21.0.0\n + idna==3.10\n + incremental==24.7.2\n + iniconfig==2.0.0\n + packaging==24.2\n + platformdirs==4.3.6\n + pluggy==1.5.0\n + pycares==4.5.0\n + pycparser==2.22\n + pycurl==7.45.4\n + pyproject-api==1.8.0\n + pytest==8.3.4\n + setuptools==75.6.0\n + tomli==2.2.1\n + tox==4.23.2\n + twisted==24.11.0\n + typing-extensions==4.12.2\n + virtualenv==20.28.0\n + zope-interface==7.2\n",
    "new_commit_res_code": 1,
    "new_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3\n........................................\ncollected 40 items\n\n=================================== ERRORS =====================================\n__________ TemplateLoaderTest.test_utf8_in_file __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3/r2e_tests/test_1.py\", line 466, in test_utf8_in_file\n    tmpl = self.loader.load(\"utf8.html\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3/tornado/template.py\", line 419, in load\n    self.templates[name] = self._create_template(name)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3/tornado/template.py\", line 446, in _create_template\n    with open(path, \"rb\") as f:\nFileNotFoundError: [Errno 2] No such file or directory: '/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3/r2e_tests/templates/utf8.html'\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::AutoEscapeTest::test_custom_escape\nPASSED r2e_tests.test_1::AutoEscapeTest::test_default_off\nPASSED r2e_tests.test_1::AutoEscapeTest::test_default_on\nPASSED r2e_tests.test_1::AutoEscapeTest::test_extended_block\nPASSED r2e_tests.test_1::AutoEscapeTest::test_manual_minimize_whitespace\nPASSED r2e_tests.test_1::AutoEscapeTest::test_raw_expression\nPASSED r2e_tests.test_1::AutoEscapeTest::test_unextended_block\nPASSED r2e_tests.test_1::AutoEscapeTest::test_whitespace_by_filename\nPASSED r2e_tests.test_1::AutoEscapeTest::test_whitespace_by_loader\nPASSED r2e_tests.test_1::ParseErrorDetailTest::test_details\nPASSED r2e_tests.test_1::StackTraceTest::test_error_line_number_directive\nPASSED r2e_tests.test_1::StackTraceTest::test_error_line_number_expression\nPASSED r2e_tests.test_1::StackTraceTest::test_error_line_number_extends_base_error\nPASSED r2e_tests.test_1::StackTraceTest::test_error_line_number_extends_sub_error\nPASSED r2e_tests.test_1::StackTraceTest::test_error_line_number_include\nPASSED r2e_tests.test_1::StackTraceTest::test_error_line_number_module\nPASSED r2e_tests.test_1::StackTraceTest::test_multi_includes\nERROR r2e_tests.test_1::TemplateLoaderTest::test_utf8_in_file\nPASSED r2e_tests.test_1::TemplateTest::test_apply\nPASSED r2e_tests.test_1::TemplateTest::test_break_continue\nPASSED r2e_tests.test_1::TemplateTest::test_break_in_apply\nPASSED r2e_tests.test_1::TemplateTest::test_break_outside_loop\nPASSED r2e_tests.test_1::TemplateTest::test_bytes\nPASSED r2e_tests.test_1::TemplateTest::test_bytes_apply\nPASSED r2e_tests.test_1::TemplateTest::test_comment\nPASSED r2e_tests.test_1::TemplateTest::test_comment_directive\nPASSED r2e_tests.test_1::TemplateTest::test_custom_namespace\nPASSED r2e_tests.test_1::TemplateTest::test_escaping\nPASSED r2e_tests.test_1::TemplateTest::test_expressions\nPASSED r2e_tests.test_1::TemplateTest::test_extends\nPASSED r2e_tests.test_1::TemplateTest::test_if\nPASSED r2e_tests.test_1::TemplateTest::test_if_empty_body\nPASSED r2e_tests.test_1::TemplateTest::test_include\nSKIPPED r2e_tests.test_1::TemplateTest::test_no_inherit_future\nPASSED r2e_tests.test_1::TemplateTest::test_relative_load\nPASSED r2e_tests.test_1::TemplateTest::test_simple\nPASSED r2e_tests.test_1::TemplateTest::test_try\nPASSED r2e_tests.test_1::TemplateTest::test_unicode_apply\nPASSED r2e_tests.test_1::TemplateTest::test_unicode_literal_expression\nPASSED r2e_tests.test_1::TemplateTest::test_unicode_template\n=================== 1 error, 38 passed, 1 skipped in 0.02s ===================\n",
    "new_commit_res_stderr": "",
    "old_commit_res_code": 1,
    "old_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3\n........................................\ncollected 40 items\n\n=================================== ERRORS =====================================\n__________ AutoEscapeTest.test_whitespace_by_loader __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3/r2e_tests/test_1.py\", line 457, in test_whitespace_by_loader\n    self.assertEqual(loader.load(\"foo.html\").generate(), b\" foo \")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3/tornado/template.py\", line 415, in load\n    self.templates[name] = self._create_template(name)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3/tornado/template.py\", line 462, in _create_template\n    return Template(self.dict[name], name=name, loader=self)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3/tornado/template.py\", line 282, in __init__\n    filter_whitespace(whitespace, '')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3/tornado/template.py\", line 231, in filter_whitespace\n    raise Exception(\"invalid whitespace mode %s\" % mode)\nException: invalid whitespace mode oneline\n__________ TemplateLoaderTest.test_utf8_in_file __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3/r2e_tests/test_1.py\", line 466, in test_utf8_in_file\n    tmpl = self.loader.load(\"utf8.html\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3/tornado/template.py\", line 415, in load\n    self.templates[name] = self._create_template(name)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3/tornado/template.py\", line 442, in _create_template\n    with open(path, \"rb\") as f:\nFileNotFoundError: [Errno 2] No such file or directory: '/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_254783a0da0f395c46423094170bb7cabba8a8f3/r2e_tests/templates/utf8.html'\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::AutoEscapeTest::test_custom_escape\nPASSED r2e_tests.test_1::AutoEscapeTest::test_default_off\nPASSED r2e_tests.test_1::AutoEscapeTest::test_default_on\nPASSED r2e_tests.test_1::AutoEscapeTest::test_extended_block\nPASSED r2e_tests.test_1::AutoEscapeTest::test_manual_minimize_whitespace\nPASSED r2e_tests.test_1::AutoEscapeTest::test_raw_expression\nPASSED r2e_tests.test_1::AutoEscapeTest::test_unextended_block\nPASSED r2e_tests.test_1::AutoEscapeTest::test_whitespace_by_filename\nERROR r2e_tests.test_1::AutoEscapeTest::test_whitespace_by_loader\nPASSED r2e_tests.test_1::ParseErrorDetailTest::test_details\nPASSED r2e_tests.test_1::StackTraceTest::test_error_line_number_directive\nPASSED r2e_tests.test_1::StackTraceTest::test_error_line_number_expression\nPASSED r2e_tests.test_1::StackTraceTest::test_error_line_number_extends_base_error\nPASSED r2e_tests.test_1::StackTraceTest::test_error_line_number_extends_sub_error\nPASSED r2e_tests.test_1::StackTraceTest::test_error_line_number_include\nPASSED r2e_tests.test_1::StackTraceTest::test_error_line_number_module\nPASSED r2e_tests.test_1::StackTraceTest::test_multi_includes\nERROR r2e_tests.test_1::TemplateLoaderTest::test_utf8_in_file\nPASSED r2e_tests.test_1::TemplateTest::test_apply\nPASSED r2e_tests.test_1::TemplateTest::test_break_continue\nPASSED r2e_tests.test_1::TemplateTest::test_break_in_apply\nPASSED r2e_tests.test_1::TemplateTest::test_break_outside_loop\nPASSED r2e_tests.test_1::TemplateTest::test_bytes\nPASSED r2e_tests.test_1::TemplateTest::test_bytes_apply\nPASSED r2e_tests.test_1::TemplateTest::test_comment\nPASSED r2e_tests.test_1::TemplateTest::test_comment_directive\nPASSED r2e_tests.test_1::TemplateTest::test_custom_namespace\nPASSED r2e_tests.test_1::TemplateTest::test_escaping\nPASSED r2e_tests.test_1::TemplateTest::test_expressions\nPASSED r2e_tests.test_1::TemplateTest::test_extends\nPASSED r2e_tests.test_1::TemplateTest::test_if\nPASSED r2e_tests.test_1::TemplateTest::test_if_empty_body\nPASSED r2e_tests.test_1::TemplateTest::test_include\nSKIPPED r2e_tests.test_1::TemplateTest::test_no_inherit_future\nPASSED r2e_tests.test_1::TemplateTest::test_relative_load\nPASSED r2e_tests.test_1::TemplateTest::test_simple\nPASSED r2e_tests.test_1::TemplateTest::test_try\nPASSED r2e_tests.test_1::TemplateTest::test_unicode_apply\nPASSED r2e_tests.test_1::TemplateTest::test_unicode_literal_expression\nPASSED r2e_tests.test_1::TemplateTest::test_unicode_template\n=================== 2 errors, 37 passed, 1 skipped in 0.02s ===================\n",
    "old_commit_res_stderr": ""
}
tornado/template.py tornado/test/template_test.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]

**Title:**
Exception Raised When Using Unsupported 'oneline' Whitespace Mode

**Description:**
When configuring the template loader with the `whitespace` mode set to `'oneline'`, an exception is thrown indicating that the whitespace mode is invalid. This prevents the use of the `'oneline'` mode for removing excessive whitespace in templates.

**Example Code:**
```python
from tornado.template import DictLoader

def test_oneline_whitespace_mode():
    templates = {'example.html': '\n\n<div>Content</div>\n\n'}
    loader = DictLoader(templates, whitespace='oneline')
    loader.load('example.html').generate()
```

**Expected Behavior:**
The template should be processed by collapsing all runs of whitespace into a single space and removing all newlines, resulting in the HTML being rendered without unnecessary blank lines.

**Actual Behavior:**
An exception is raised with the message: `Exception: invalid whitespace mode oneline`

[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### tornado/template.py
#!/usr/bin/env python
#
# Copyright 2009 Facebook
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""A simple template system that compiles templates to Python code.

Basic usage looks like::

    t = template.Template("<html>{{ myvalue }}</html>")
    print t.generate(myvalue="XXX")

`Loader` is a class that loads templates from a root directory and caches
the compiled templates::

    loader = template.Loader("/home/btaylor")
    print loader.load("test.html").generate(myvalue="XXX")

We compile all templates to raw Python. Error-reporting is currently... uh,
interesting. Syntax for the templates::

    ### base.html
    <html>
      <head>
        <title>{% block title %}Default title{% end %}</title>
      </head>
      <body>
        <ul>
          {% for student in students %}
            {% block student %}
              <li>{{ escape(student.name) }}</li>
            {% end %}
          {% end %}
        </ul>
      </body>
    </html>

    ### bold.html
    {% extends "base.html" %}

    {% block title %}A bolder title{% end %}

    {% block student %}
      <li><span style="bold">{{ escape(student.name) }}</span></li>
    {% end %}

Unlike most other template systems, we do not put any restrictions on the
expressions you can include in your statements. ``if`` and ``for`` blocks get
translated exactly into Python, so you can do complex expressions like::

   {% for student in [p for p in people if p.student and p.age > 23] %}
     <li>{{ escape(student.name) }}</li>
   {% end %}

Translating directly to Python means you can apply functions to expressions
easily, like the ``escape()`` function in the examples above. You can pass
functions in to your template just like any other variable
(In a `.RequestHandler`, override `.RequestHandler.get_template_namespace`)::

   ### Python code
   def add(x, y):
      return x + y
   template.execute(add=add)

   ### The template
   {{ add(1, 2) }}

We provide the functions `escape() <.xhtml_escape>`, `.url_escape()`,
`.json_encode()`, and `.squeeze()` to all templates by default.

Typical applications do not create `Template` or `Loader` instances by
hand, but instead use the `~.RequestHandler.render` and
`~.RequestHandler.render_string` methods of
`tornado.web.RequestHandler`, which load templates automatically based
on the ``template_path`` `.Application` setting.

Variable names beginning with ``_tt_`` are reserved by the template
system and should not be used by application code.

Syntax Reference
----------------

Template expressions are surrounded by double curly braces: ``{{ ... }}``.
The contents may be any python expression, which will be escaped according
to the current autoescape setting and inserted into the output.  Other
template directives use ``{% %}``.  These tags may be escaped as ``{{!``
and ``{%!`` if you need to include a literal ``{{`` or ``{%`` in the output.

To comment out a section so that it is omitted from the output, surround it
with ``{# ... #}``.

``{% apply *function* %}...{% end %}``
    Applies a function to the output of all template code between ``apply``
    and ``end``::

        {% apply linkify %}{{name}} said: {{message}}{% end %}

    Note that as an implementation detail apply blocks are implemented
    as nested functions and thus may interact strangely with variables
    set via ``{% set %}``, or the use of ``{% break %}`` or ``{% continue %}``
    within loops.

``{% autoescape *function* %}``
    Sets the autoescape mode for the current file.  This does not affect
    other files, even those referenced by ``{% include %}``.  Note that
    autoescaping can also be configured globally, at the `.Application`
    or `Loader`.::

        {% autoescape xhtml_escape %}
        {% autoescape None %}

``{% block *name* %}...{% end %}``
    Indicates a named, replaceable block for use with ``{% extends %}``.
    Blocks in the parent template will be replaced with the contents of
    the same-named block in a child template.::

        <!-- base.html -->
        <title>{% block title %}Default title{% end %}</title>

        <!-- mypage.html -->
        {% extends "base.html" %}
        {% block title %}My page title{% end %}

``{% comment ... %}``
    A comment which will be removed from the template output.  Note that
    there is no ``{% end %}`` tag; the comment goes from the word ``comment``
    to the closing ``%}`` tag.

``{% extends *filename* %}``
    Inherit from another template.  Templates that use ``extends`` should
    contain one or more ``block`` tags to replace content from the parent
    template.  Anything in the child template not contained in a ``block``
    tag will be ignored.  For an example, see the ``{% block %}`` tag.

``{% for *var* in *expr* %}...{% end %}``
    Same as the python ``for`` statement.  ``{% break %}`` and
    ``{% continue %}`` may be used inside the loop.

``{% from *x* import *y* %}``
    Same as the python ``import`` statement.

``{% if *condition* %}...{% elif *condition* %}...{% else %}...{% end %}``
    Conditional statement - outputs the first section whose condition is
    true.  (The ``elif`` and ``else`` sections are optional)

``{% import *module* %}``
    Same as the python ``import`` statement.

``{% include *filename* %}``
    Includes another template file.  The included file can see all the local
    variables as if it were copied directly to the point of the ``include``
    directive (the ``{% autoescape %}`` directive is an exception).
    Alternately, ``{% module Template(filename, **kwargs) %}`` may be used
    to include another template with an isolated namespace.

``{% module *expr* %}``
    Renders a `~tornado.web.UIModule`.  The output of the ``UIModule`` is
    not escaped::

        {% module Template("foo.html", arg=42) %}

    ``UIModules`` are a feature of the `tornado.web.RequestHandler`
    class (and specifically its ``render`` method) and will not work
    when the template system is used on its own in other contexts.

``{% raw *expr* %}``
    Outputs the result of the given expression without autoescaping.

``{% set *x* = *y* %}``
    Sets a local variable.

``{% try %}...{% except %}...{% else %}...{% finally %}...{% end %}``
    Same as the python ``try`` statement.

``{% while *condition* %}... {% end %}``
    Same as the python ``while`` statement.  ``{% break %}`` and
    ``{% continue %}`` may be used inside the loop.
"""

from __future__ import absolute_import, division, print_function, with_statement

import datetime
import linecache
import os.path
import posixpath
import re
import threading

from tornado import escape
from tornado.log import app_log
from tornado.util import ObjectDict, exec_in, unicode_type

try:
    from cStringIO import StringIO  # py2
except ImportError:
    from io import StringIO  # py3

_DEFAULT_AUTOESCAPE = "xhtml_escape"
_UNSET = object()


def filter_whitespace(mode, text):
    """Transform whitespace in ``text`` according to ``mode``.

    Available modes are:

    * ``all``: Return all whitespace unmodified.
    * ``single``: Collapse consecutive whitespace with a single whitespace
      character, preserving newlines.

    .. versionadded:: 4.3
    """
    if mode == 'all':
        return text
    elif mode == 'single':
        text = re.sub(r"([\t ]+)", " ", text)
        text = re.sub(r"(\s*\n\s*)", "\n", text)
        return text
    else:
        raise Exception("invalid whitespace mode %s" % mode)


class Template(object):
    """A compiled template.

    We compile into Python from the given template_string. You can generate
    the template from variables with generate().
    """
    # note that the constructor's signature is not extracted with
    # autodoc because _UNSET looks like garbage.  When changing
    # this signature update website/sphinx/template.rst too.
    def __init__(self, template_string, name="<string>", loader=None,
                 compress_whitespace=_UNSET, autoescape=_UNSET,
                 whitespace=None):
        """Construct a Template.

        :arg str template_string: the contents of the template file.
        :arg str name: the filename from which the template was loaded
            (used for error message).
        :arg tornado.template.BaseLoader loader: the `~tornado.template.BaseLoader` responsible for this template,
            used to resolve ``{% include %}`` and ``{% extend %}``
            directives.
        :arg bool compress_whitespace: Deprecated since Tornado 4.3.
            Equivalent to ``whitespace="single"`` if true and
            ``whitespace="all"`` if false.
        :arg str autoescape: The name of a function in the template
            namespace, or ``None`` to disable escaping by default.
        :arg str whitespace: A string specifying treatment of whitespace;
            see `filter_whitespace` for options.

        .. versionchanged:: 4.3
           Added ``whitespace`` parameter; deprecated ``compress_whitespace``.
        """
        self.name = name

        if compress_whitespace is not _UNSET:
            # Convert deprecated compress_whitespace (bool) to whitespace (str).
            if whitespace is not None:
                raise Exception("cannot set both whitespace and compress_whitespace")
            whitespace = "single" if compress_whitespace else "all"
        if whitespace is None:
            if loader and loader.whitespace:
                whitespace = loader.whitespace
            else:
                # Whitespace defaults by filename.
                if name.endswith(".html") or name.endswith(".js"):
                    whitespace = "single"
                else:
                    whitespace = "all"
        # Validate the whitespace setting.
        filter_whitespace(whitespace, '')

        if autoescape is not _UNSET:
            self.autoescape = autoescape
        elif loader:
            self.autoescape = loader.autoescape
        else:
            self.autoescape = _DEFAULT_AUTOESCAPE

        self.namespace = loader.namespace if loader else {}
        reader = _TemplateReader(name, escape.native_str(template_string),
                                 whitespace)
        self.file = _File(self, _parse(reader, self))
        self.code = self._generate_python(loader)
        self.loader = loader
        try:
            # Under python2.5, the fake filename used here must match
            # the module name used in __name__ below.
            # The dont_inherit flag prevents template.py's future imports
            # from being applied to the generated code.
            self.compiled = compile(
                escape.to_unicode(self.code),
                "%s.generated.py" % self.name.replace('.', '_'),
                "exec", dont_inherit=True)
        except Exception:
            formatted_code = _format_code(self.code).rstrip()
            app_log.error("%s code:\n%s", self.name, formatted_code)
            raise

    def generate(self, **kwargs):
        """Generate this template with the given arguments."""
        namespace = {
            "escape": escape.xhtml_escape,
            "xhtml_escape": escape.xhtml_escape,
            "url_escape": escape.url_escape,
            "json_encode": escape.json_encode,
            "squeeze": escape.squeeze,
            "linkify": escape.linkify,
            "datetime": datetime,
            "_tt_utf8": escape.utf8,  # for internal use
            "_tt_string_types": (unicode_type, bytes),
            # __name__ and __loader__ allow the traceback mechanism to find
            # the generated source code.
            "__name__": self.name.replace('.', '_'),
            "__loader__": ObjectDict(get_source=lambda name: self.code),
        }
        namespace.update(self.namespace)
        namespace.update(kwargs)
        exec_in(self.compiled, namespace)
        execute = namespace["_tt_execute"]
        # Clear the traceback module's cache of source data now that
        # we've generated a new template (mainly for this module's
        # unittests, where different tests reuse the same name).
        linecache.clearcache()
        return execute()

    def _generate_python(self, loader):
        buffer = StringIO()
        try:
            # named_blocks maps from names to _NamedBlock objects
            named_blocks = {}
            ancestors = self._get_ancestors(loader)
            ancestors.reverse()
            for ancestor in ancestors:
                ancestor.find_named_blocks(loader, named_blocks)
            writer = _CodeWriter(buffer, named_blocks, loader,
                                 ancestors[0].template)
            ancestors[0].generate(writer)
            return buffer.getvalue()
        finally:
            buffer.close()

    def _get_ancestors(self, loader):
        ancestors = [self.file]
        for chunk in self.file.body.chunks:
            if isinstance(chunk, _ExtendsBlock):
                if not loader:
                    raise ParseError("{% extends %} block found, but no "
                                     "template loader")
                template = loader.load(chunk.name, self.name)
                ancestors.extend(template._get_ancestors(loader))
        return ancestors


class BaseLoader(object):
    """Base class for template loaders.

    You must use a template loader to use template constructs like
    ``{% extends %}`` and ``{% include %}``. The loader caches all
    templates after they are loaded the first time.
    """
    def __init__(self, autoescape=_DEFAULT_AUTOESCAPE, namespace=None,
                 whitespace=None):
        """Construct a template loader.

        :arg str autoescape: The name of a function in the template
            namespace, such as "xhtml_escape", or ``None`` to disable
            autoescaping by default.
        :arg dict namespace: A dictionary to be added to the default template
            namespace, or ``None``.
        :arg str whitespace: A string specifying default behavior for
            whitespace in templates; see `filter_whitespace` for options.
            Default is "single" for files ending in ".html" and ".js" and
            "all" for other files.

        .. versionchanged:: 4.3
           Added ``whitespace`` parameter.
        """
        self.autoescape = autoescape
        self.namespace = namespace or {}
        self.whitespace = whitespace
        self.templates = {}
        # self.lock protects self.templates.  It's a reentrant lock
        # because templates may load other templates via `include` or
        # `extends`.  Note that thanks to the GIL this code would be safe
        # even without the lock, but could lead to wasted work as multiple
        # threads tried to compile the same template simultaneously.
        self.lock = threading.RLock()

    def reset(self):
        """Resets the cache of compiled templates."""
        with self.lock:
            self.templates = {}

    def resolve_path(self, name, parent_path=None):
        """Converts a possibly-relative path to absolute (used internally)."""
        raise NotImplementedError()

    def load(self, name, parent_path=None):
        """Loads a template."""
        name = self.resolve_path(name, parent_path=parent_path)
        with self.lock:
            if name not in self.templates:
                self.templates[name] = self._create_template(name)
            return self.templates[name]

    def _create_template(self, name):
        raise NotImplementedError()


class Loader(BaseLoader):
    """A template loader that loads from a single root directory.
    """
    def __init__(self, root_directory, **kwargs):
        super(Loader, self).__init__(**kwargs)
        self.root = os.path.abspath(root_directory)

    def resolve_path(self, name, parent_path=None):
        if parent_path and not parent_path.startswith("<") and \
            not parent_path.startswith("/") and \
                not name.startswith("/"):
            current_path = os.path.join(self.root, parent_path)
            file_dir = os.path.dirname(os.path.abspath(current_path))
            relative_path = os.path.abspath(os.path.join(file_dir, name))
            if relative_path.startswith(self.root):
                name = relative_path[len(self.root) + 1:]
        return name

    def _create_template(self, name):
        path = os.path.join(self.root, name)
        with open(path, "rb") as f:
            template = Template(f.read(), name=name, loader=self)
            return template


class DictLoader(BaseLoader):
    """A template loader that loads from a dictionary."""
    def __init__(self, dict, **kwargs):
        super(DictLoader, self).__init__(**kwargs)
        self.dict = dict

    def resolve_path(self, name, parent_path=None):
        if parent_path and not parent_path.startswith("<") and \
            not parent_path.startswith("/") and \
                not name.startswith("/"):
            file_dir = posixpath.dirname(parent_path)
            name = posixpath.normpath(posixpath.join(file_dir, name))
        return name

    def _create_template(self, name):
        return Template(self.dict[name], name=name, loader=self)


class _Node(object):
    def each_child(self):
        return ()

    def generate(self, writer):
        raise NotImplementedError()

    def find_named_blocks(self, loader, named_blocks):
        for child in self.each_child():
            child.find_named_blocks(loader, named_blocks)


class _File(_Node):
    def __init__(self, template, body):
        self.template = template
        self.body = body
        self.line = 0

    def generate(self, writer):
        writer.write_line("def _tt_execute():", self.line)
        with writer.indent():
            writer.write_line("_tt_buffer = []", self.line)
            writer.write_line("_tt_append = _tt_buffer.append", self.line)
            self.body.generate(writer)
            writer.write_line("return _tt_utf8('').join(_tt_buffer)", self.line)

    def each_child(self):
        return (self.body,)


class _ChunkList(_Node):
    def __init__(self, chunks):
        self.chunks = chunks

    def generate(self, writer):
        for chunk in self.chunks:
            chunk.generate(writer)

    def each_child(self):
        return self.chunks


class _NamedBlock(_Node):
    def __init__(self, name, body, template, line):
        self.name = name
        self.body = body
        self.template = template
        self.line = line

    def each_child(self):
        return (self.body,)

    def generate(self, writer):
        block = writer.named_blocks[self.name]
        with writer.include(block.template, self.line):
            block.body.generate(writer)

    def find_named_blocks(self, loader, named_blocks):
        named_blocks[self.name] = self
        _Node.find_named_blocks(self, loader, named_blocks)


class _ExtendsBlock(_Node):
    def __init__(self, name):
        self.name = name


class _IncludeBlock(_Node):
    def __init__(self, name, reader, line):
        self.name = name
        self.template_name = reader.name
        self.line = line

    def find_named_blocks(self, loader, named_blocks):
        included = loader.load(self.name, self.template_name)
        included.file.find_named_blocks(loader, named_blocks)

    def generate(self, writer):
        included = writer.loader.load(self.name, self.template_name)
        with writer.include(included, self.line):
            included.file.body.generate(writer)


class _ApplyBlock(_Node):
    def __init__(self, method, line, body=None):
        self.method = method
        self.line = line
        self.body = body

    def each_child(self):
        return (self.body,)

    def generate(self, writer):
        method_name = "_tt_apply%d" % writer.apply_counter
        writer.apply_counter += 1
        writer.write_line("def %s():" % method_name, self.line)
        with writer.indent():
            writer.write_line("_tt_buffer = []", self.line)
            writer.write_line("_tt_append = _tt_buffer.append", self.line)
            self.body.generate(writer)
            writer.write_line("return _tt_utf8('').join(_tt_buffer)", self.line)
        writer.write_line("_tt_append(_tt_utf8(%s(%s())))" % (
            self.method, method_name), self.line)


class _ControlBlock(_Node):
    def __init__(self, statement, line, body=None):
        self.statement = statement
        self.line = line
        self.body = body

    def each_child(self):
        return (self.body,)

    def generate(self, writer):
        writer.write_line("%s:" % self.statement, self.line)
        with writer.indent():
            self.body.generate(writer)
            # Just in case the body was empty
            writer.write_line("pass", self.line)


class _IntermediateControlBlock(_Node):
    def __init__(self, statement, line):
        self.statement = statement
        self.line = line

    def generate(self, writer):
        # In case the previous block was empty
        writer.write_line("pass", self.line)
        writer.write_line("%s:" % self.statement, self.line, writer.indent_size() - 1)


class _Statement(_Node):
    def __init__(self, statement, line):
        self.statement = statement
        self.line = line

    def generate(self, writer):
        writer.write_line(self.statement, self.line)


class _Expression(_Node):
    def __init__(self, expression, line, raw=False):
        self.expression = expression
        self.line = line
        self.raw = raw

    def generate(self, writer):
        writer.write_line("_tt_tmp = %s" % self.expression, self.line)
        writer.write_line("if isinstance(_tt_tmp, _tt_string_types):"
                          " _tt_tmp = _tt_utf8(_tt_tmp)", self.line)
        writer.write_line("else: _tt_tmp = _tt_utf8(str(_tt_tmp))", self.line)
        if not self.raw and writer.current_template.autoescape is not None:
            # In python3 functions like xhtml_escape return unicode,
            # so we have to convert to utf8 again.
            writer.write_line("_tt_tmp = _tt_utf8(%s(_tt_tmp))" %
                              writer.current_template.autoescape, self.line)
        writer.write_line("_tt_append(_tt_tmp)", self.line)


class _Module(_Expression):
    def __init__(self, expression, line):
        super(_Module, self).__init__("_tt_modules." + expression, line,
                                      raw=True)


class _Text(_Node):
    def __init__(self, value, line, whitespace):
        self.value = value
        self.line = line
        self.whitespace = whitespace

    def generate(self, writer):
        value = self.value

        # Compress whitespace if requested, with a crude heuristic to avoid
        # altering preformatted whitespace.
        if "<pre>" not in value:
            value = filter_whitespace(self.whitespace, value)

        if value:
            writer.write_line('_tt_append(%r)' % escape.utf8(value), self.line)


class ParseError(Exception):
    """Raised for template syntax errors.

    ``ParseError`` instances have ``filename`` and ``lineno`` attributes
    indicating the position of the error.

    .. versionchanged:: 4.3
       Added ``filename`` and ``lineno`` attributes.
    """
    def __init__(self, message, filename, lineno):
        self.message = message
        # The names "filename" and "lineno" are chosen for consistency
        # with python SyntaxError.
        self.filename = filename
        self.lineno = lineno

    def __str__(self):
        return '%s at %s:%d' % (self.message, self.filename, self.lineno)


class _CodeWriter(object):
    def __init__(self, file, named_blocks, loader, current_template):
        self.file = file
        self.named_blocks = named_blocks
        self.loader = loader
        self.current_template = current_template
        self.apply_counter = 0
        self.include_stack = []
        self._indent = 0

    def indent_size(self):
        return self._indent

    def indent(self):
        class Indenter(object):
            def __enter__(_):
                self._indent += 1
                return self

            def __exit__(_, *args):
                assert self._indent > 0
                self._indent -= 1

        return Indenter()

    def include(self, template, line):
        self.include_stack.append((self.current_template, line))
        self.current_template = template

        class IncludeTemplate(object):
            def __enter__(_):
                return self

            def __exit__(_, *args):
                self.current_template = self.include_stack.pop()[0]

        return IncludeTemplate()

    def write_line(self, line, line_number, indent=None):
        if indent is None:
            indent = self._indent
        line_comment = '  # %s:%d' % (self.current_template.name, line_number)
        if self.include_stack:
            ancestors = ["%s:%d" % (tmpl.name, lineno)
                         for (tmpl, lineno) in self.include_stack]
            line_comment += ' (via %s)' % ', '.join(reversed(ancestors))
        print("    " * indent + line + line_comment, file=self.file)


class _TemplateReader(object):
    def __init__(self, name, text, whitespace):
        self.name = name
        self.text = text
        self.whitespace = whitespace
        self.line = 1
        self.pos = 0

    def find(self, needle, start=0, end=None):
        assert start >= 0, start
        pos = self.pos
        start += pos
        if end is None:
            index = self.text.find(needle, start)
        else:
            end += pos
            assert end >= start
            index = self.text.find(needle, start, end)
        if index != -1:
            index -= pos
        return index

    def consume(self, count=None):
        if count is None:
            count = len(self.text) - self.pos
        newpos = self.pos + count
        self.line += self.text.count("\n", self.pos, newpos)
        s = self.text[self.pos:newpos]
        self.pos = newpos
        return s

    def remaining(self):
        return len(self.text) - self.pos

    def __len__(self):
        return self.remaining()

    def __getitem__(self, key):
        if type(key) is slice:
            size = len(self)
            start, stop, step = key.indices(size)
            if start is None:
                start = self.pos
            else:
                start += self.pos
            if stop is not None:
                stop += self.pos
            return self.text[slice(start, stop, step)]
        elif key < 0:
            return self.text[key]
        else:
            return self.text[self.pos + key]

    def __str__(self):
        return self.text[self.pos:]

    def raise_parse_error(self, msg):
        raise ParseError(msg, self.name, self.line)


def _format_code(code):
    lines = code.splitlines()
    format = "%%%dd  %%s\n" % len(repr(len(lines) + 1))
    return "".join([format % (i + 1, line) for (i, line) in enumerate(lines)])


def _parse(reader, template, in_block=None, in_loop=None):
    body = _ChunkList([])
    while True:
        # Find next template directive
        curly = 0
        while True:
            curly = reader.find("{", curly)
            if curly == -1 or curly + 1 == reader.remaining():
                # EOF
                if in_block:
                    reader.raise_parse_error(
                        "Missing {%% end %%} block for %s" % in_block)
                body.chunks.append(_Text(reader.consume(), reader.line,
                                         reader.whitespace))
                return body
            # If the first curly brace is not the start of a special token,
            # start searching from the character after it
            if reader[curly + 1] not in ("{", "%", "#"):
                curly += 1
                continue
            # When there are more than 2 curlies in a row, use the
            # innermost ones.  This is useful when generating languages
            # like latex where curlies are also meaningful
            if (curly + 2 < reader.remaining() and
                    reader[curly + 1] == '{' and reader[curly + 2] == '{'):
                curly += 1
                continue
            break

        # Append any text before the special token
        if curly > 0:
            cons = reader.consume(curly)
            body.chunks.append(_Text(cons, reader.line,
                                     reader.whitespace))

        start_brace = reader.consume(2)
        line = reader.line

        # Template directives may be escaped as "{{!" or "{%!".
        # In this case output the braces and consume the "!".
        # This is especially useful in conjunction with jquery templates,
        # which also use double braces.
        if reader.remaining() and reader[0] == "!":
            reader.consume(1)
            body.chunks.append(_Text(start_brace, line,
                                     reader.whitespace))
            continue

        # Comment
        if start_brace == "{#":
            end = reader.find("#}")
            if end == -1:
                reader.raise_parse_error("Missing end comment #}")
            contents = reader.consume(end).strip()
            reader.consume(2)
            continue

        # Expression
        if start_brace == "{{":
            end = reader.find("}}")
            if end == -1:
                reader.raise_parse_error("Missing end expression }}")
            contents = reader.consume(end).strip()
            reader.consume(2)
            if not contents:
                reader.raise_parse_error("Empty expression")
            body.chunks.append(_Expression(contents, line))
            continue

        # Block
        assert start_brace == "{%", start_brace
        end = reader.find("%}")
        if end == -1:
            reader.raise_parse_error("Missing end block %}")
        contents = reader.consume(end).strip()
        reader.consume(2)
        if not contents:
            reader.raise_parse_error("Empty block tag ({% %})")

        operator, space, suffix = contents.partition(" ")
        suffix = suffix.strip()

        # Intermediate ("else", "elif", etc) blocks
        intermediate_blocks = {
            "else": set(["if", "for", "while", "try"]),
            "elif": set(["if"]),
            "except": set(["try"]),
            "finally": set(["try"]),
        }
        allowed_parents = intermediate_blocks.get(operator)
        if allowed_parents is not None:
            if not in_block:
                reader.raise_parse_error("%s outside %s block" %
                                         (operator, allowed_parents))
            if in_block not in allowed_parents:
                reader.raise_parse_error(
                    "%s block cannot be attached to %s block" %
                    (operator, in_block))
            body.chunks.append(_IntermediateControlBlock(contents, line))
            continue

        # End tag
        elif operator == "end":
            if not in_block:
                reader.raise_parse_error("Extra {% end %} block")
            return body

        elif operator in ("extends", "include", "set", "import", "from",
                          "comment", "autoescape", "raw", "module"):
            if operator == "comment":
                continue
            if operator == "extends":
                suffix = suffix.strip('"').strip("'")
                if not suffix:
                    reader.raise_parse_error("extends missing file path")
                block = _ExtendsBlock(suffix)
            elif operator in ("import", "from"):
                if not suffix:
                    reader.raise_parse_error("import missing statement")
                block = _Statement(contents, line)
            elif operator == "include":
                suffix = suffix.strip('"').strip("'")
                if not suffix:
                    reader.raise_parse_error("include missing file path")
                block = _IncludeBlock(suffix, reader, line)
            elif operator == "set":
                if not suffix:
                    reader.raise_parse_error("set missing statement")
                block = _Statement(suffix, line)
            elif operator == "autoescape":
                fn = suffix.strip()
                if fn == "None":
                    fn = None
                template.autoescape = fn
                continue
            elif operator == "raw":
                block = _Expression(suffix, line, raw=True)
            elif operator == "module":
                block = _Module(suffix, line)
            body.chunks.append(block)
            continue

        elif operator in ("apply", "block", "try", "if", "for", "while"):
            # parse inner body recursively
            if operator in ("for", "while"):
                block_body = _parse(reader, template, operator, operator)
            elif operator == "apply":
                # apply creates a nested function so syntactically it's not
                # in the loop.
                block_body = _parse(reader, template, operator, None)
            else:
                block_body = _parse(reader, template, operator, in_loop)

            if operator == "apply":
                if not suffix:
                    reader.raise_parse_error("apply missing method name")
                block = _ApplyBlock(suffix, line, block_body)
            elif operator == "block":
                if not suffix:
                    reader.raise_parse_error("block missing name")
                block = _NamedBlock(suffix, block_body, template, line)
            else:
                block = _ControlBlock(contents, line, block_body)
            body.chunks.append(block)
            continue

        elif operator in ("break", "continue"):
            if not in_loop:
                reader.raise_parse_error("%s outside %s block" %
                                         (operator, set(["for", "while"])))
            body.chunks.append(_Statement(contents, line))
            continue

        else:
            reader.raise_parse_error("unknown operator: %r" % operator)

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
[ISSUE]

**Title:**
Exception Raised When Using Unsupported 'oneline' Whitespace Mode

**Description:**
When configuring the template loader with the `whitespace` mode set to `'oneline'`, an exception is thrown indicating that the whitespace mode is invalid. This prevents the use of the `'oneline'` mode for removing excessive whitespace in templates.

**Example Code:**
```python
from tornado.template import DictLoader

def test_oneline_whitespace_mode():
    templates = {'example.html': '\n\n<div>Content</div>\n\n'}
    loader = DictLoader(templates, whitespace='oneline')
    loader.load('example.html').generate()
```

**Expected Behavior:**
The template should be processed by collapsing all runs of whitespace into a single space and removing all newlines, resulting in the HTML being rendered without unnecessary blank lines.

**Actual Behavior:**
An exception is raised with the message: `Exception: invalid whitespace mode oneline`

[/ISSUE]
{
    "AutoEscapeTest.test_custom_escape": "PASSED",
    "AutoEscapeTest.test_default_off": "PASSED",
    "AutoEscapeTest.test_default_on": "PASSED",
    "AutoEscapeTest.test_extended_block": "PASSED",
    "AutoEscapeTest.test_manual_minimize_whitespace": "PASSED",
    "AutoEscapeTest.test_raw_expression": "PASSED",
    "AutoEscapeTest.test_unextended_block": "PASSED",
    "AutoEscapeTest.test_whitespace_by_filename": "PASSED",
    "AutoEscapeTest.test_whitespace_by_loader": "PASSED",
    "ParseErrorDetailTest.test_details": "PASSED",
    "StackTraceTest.test_error_line_number_directive": "PASSED",
    "StackTraceTest.test_error_line_number_expression": "PASSED",
    "StackTraceTest.test_error_line_number_extends_base_error": "PASSED",
    "StackTraceTest.test_error_line_number_extends_sub_error": "PASSED",
    "StackTraceTest.test_error_line_number_include": "PASSED",
    "StackTraceTest.test_error_line_number_module": "PASSED",
    "StackTraceTest.test_multi_includes": "PASSED",
    "TemplateLoaderTest.test_utf8_in_file": "ERROR",
    "TemplateTest.test_apply": "PASSED",
    "TemplateTest.test_break_continue": "PASSED",
    "TemplateTest.test_break_in_apply": "PASSED",
    "TemplateTest.test_break_outside_loop": "PASSED",
    "TemplateTest.test_bytes": "PASSED",
    "TemplateTest.test_bytes_apply": "PASSED",
    "TemplateTest.test_comment": "PASSED",
    "TemplateTest.test_comment_directive": "PASSED",
    "TemplateTest.test_custom_namespace": "PASSED",
    "TemplateTest.test_escaping": "PASSED",
    "TemplateTest.test_expressions": "PASSED",
    "TemplateTest.test_extends": "PASSED",
    "TemplateTest.test_if": "PASSED",
    "TemplateTest.test_if_empty_body": "PASSED",
    "TemplateTest.test_include": "PASSED",
    "TemplateTest.test_relative_load": "PASSED",
    "TemplateTest.test_simple": "PASSED",
    "TemplateTest.test_try": "PASSED",
    "TemplateTest.test_unicode_apply": "PASSED",
    "TemplateTest.test_unicode_literal_expression": "PASSED",
    "TemplateTest.test_unicode_template": "PASSED"
}
diff --git a/tornado/template.py b/tornado/template.py
index d0d35b3e..9a4c6c64 100644
--- a/tornado/template.py
+++ b/tornado/template.py
@@ -218,6 +218,8 @@ def filter_whitespace(mode, text):
     * ``all``: Return all whitespace unmodified.
     * ``single``: Collapse consecutive whitespace with a single whitespace
       character, preserving newlines.
+    * ``oneline``: Collapse all runs of whitespace into a single space
+      character, removing all newlines in the process.
 
     .. versionadded:: 4.3
     """
@@ -227,6 +229,8 @@ def filter_whitespace(mode, text):
         text = re.sub(r"([\t ]+)", " ", text)
         text = re.sub(r"(\s*\n\s*)", "\n", text)
         return text
+    elif mode == 'oneline':
+        return re.sub(r"(\s+)", " ", text)
     else:
         raise Exception("invalid whitespace mode %s" % mode)
 

{"tornado/template.py": "#!/usr/bin/env python\n#\n# Copyright 2009 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"A simple template system that compiles templates to Python code.\n\nBasic usage looks like::\n\n    t = template.Template(\"<html>{{ myvalue }}</html>\")\n    print t.generate(myvalue=\"XXX\")\n\n`Loader` is a class that loads templates from a root directory and caches\nthe compiled templates::\n\n    loader = template.Loader(\"/home/btaylor\")\n    print loader.load(\"test.html\").generate(myvalue=\"XXX\")\n\nWe compile all templates to raw Python. Error-reporting is currently... uh,\ninteresting. Syntax for the templates::\n\n    ### base.html\n    <html>\n      <head>\n        <title>{% block title %}Default title{% end %}</title>\n      </head>\n      <body>\n        <ul>\n          {% for student in students %}\n            {% block student %}\n              <li>{{ escape(student.name) }}</li>\n            {% end %}\n          {% end %}\n        </ul>\n      </body>\n    </html>\n\n    ### bold.html\n    {% extends \"base.html\" %}\n\n    {% block title %}A bolder title{% end %}\n\n    {% block student %}\n      <li><span style=\"bold\">{{ escape(student.name) }}</span></li>\n    {% end %}\n\nUnlike most other template systems, we do not put any restrictions on the\nexpressions you can include in your statements. ``if`` and ``for`` blocks get\ntranslated exactly into Python, so you can do complex expressions like::\n\n   {% for student in [p for p in people if p.student and p.age > 23] %}\n     <li>{{ escape(student.name) }}</li>\n   {% end %}\n\nTranslating directly to Python means you can apply functions to expressions\neasily, like the ``escape()`` function in the examples above. You can pass\nfunctions in to your template just like any other variable\n(In a `.RequestHandler`, override `.RequestHandler.get_template_namespace`)::\n\n   ### Python code\n   def add(x, y):\n      return x + y\n   template.execute(add=add)\n\n   ### The template\n   {{ add(1, 2) }}\n\nWe provide the functions `escape() <.xhtml_escape>`, `.url_escape()`,\n`.json_encode()`, and `.squeeze()` to all templates by default.\n\nTypical applications do not create `Template` or `Loader` instances by\nhand, but instead use the `~.RequestHandler.render` and\n`~.RequestHandler.render_string` methods of\n`tornado.web.RequestHandler`, which load templates automatically based\non the ``template_path`` `.Application` setting.\n\nVariable names beginning with ``_tt_`` are reserved by the template\nsystem and should not be used by application code.\n\nSyntax Reference\n----------------\n\nTemplate expressions are surrounded by double curly braces: ``{{ ... }}``.\nThe contents may be any python expression, which will be escaped according\nto the current autoescape setting and inserted into the output.  Other\ntemplate directives use ``{% %}``.  These tags may be escaped as ``{{!``\nand ``{%!`` if you need to include a literal ``{{`` or ``{%`` in the output.\n\nTo comment out a section so that it is omitted from the output, surround it\nwith ``{# ... #}``.\n\n``{% apply *function* %}...{% end %}``\n    Applies a function to the output of all template code between ``apply``\n    and ``end``::\n\n        {% apply linkify %}{{name}} said: {{message}}{% end %}\n\n    Note that as an implementation detail apply blocks are implemented\n    as nested functions and thus may interact strangely with variables\n    set via ``{% set %}``, or the use of ``{% break %}`` or ``{% continue %}``\n    within loops.\n\n``{% autoescape *function* %}``\n    Sets the autoescape mode for the current file.  This does not affect\n    other files, even those referenced by ``{% include %}``.  Note that\n    autoescaping can also be configured globally, at the `.Application`\n    or `Loader`.::\n\n        {% autoescape xhtml_escape %}\n        {% autoescape None %}\n\n``{% block *name* %}...{% end %}``\n    Indicates a named, replaceable block for use with ``{% extends %}``.\n    Blocks in the parent template will be replaced with the contents of\n    the same-named block in a child template.::\n\n        <!-- base.html -->\n        <title>{% block title %}Default title{% end %}</title>\n\n        <!-- mypage.html -->\n        {% extends \"base.html\" %}\n        {% block title %}My page title{% end %}\n\n``{% comment ... %}``\n    A comment which will be removed from the template output.  Note that\n    there is no ``{% end %}`` tag; the comment goes from the word ``comment``\n    to the closing ``%}`` tag.\n\n``{% extends *filename* %}``\n    Inherit from another template.  Templates that use ``extends`` should\n    contain one or more ``block`` tags to replace content from the parent\n    template.  Anything in the child template not contained in a ``block``\n    tag will be ignored.  For an example, see the ``{% block %}`` tag.\n\n``{% for *var* in *expr* %}...{% end %}``\n    Same as the python ``for`` statement.  ``{% break %}`` and\n    ``{% continue %}`` may be used inside the loop.\n\n``{% from *x* import *y* %}``\n    Same as the python ``import`` statement.\n\n``{% if *condition* %}...{% elif *condition* %}...{% else %}...{% end %}``\n    Conditional statement - outputs the first section whose condition is\n    true.  (The ``elif`` and ``else`` sections are optional)\n\n``{% import *module* %}``\n    Same as the python ``import`` statement.\n\n``{% include *filename* %}``\n    Includes another template file.  The included file can see all the local\n    variables as if it were copied directly to the point of the ``include``\n    directive (the ``{% autoescape %}`` directive is an exception).\n    Alternately, ``{% module Template(filename, **kwargs) %}`` may be used\n    to include another template with an isolated namespace.\n\n``{% module *expr* %}``\n    Renders a `~tornado.web.UIModule`.  The output of the ``UIModule`` is\n    not escaped::\n\n        {% module Template(\"foo.html\", arg=42) %}\n\n    ``UIModules`` are a feature of the `tornado.web.RequestHandler`\n    class (and specifically its ``render`` method) and will not work\n    when the template system is used on its own in other contexts.\n\n``{% raw *expr* %}``\n    Outputs the result of the given expression without autoescaping.\n\n``{% set *x* = *y* %}``\n    Sets a local variable.\n\n``{% try %}...{% except %}...{% else %}...{% finally %}...{% end %}``\n    Same as the python ``try`` statement.\n\n``{% while *condition* %}... {% end %}``\n    Same as the python ``while`` statement.  ``{% break %}`` and\n    ``{% continue %}`` may be used inside the loop.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport datetime\nimport linecache\nimport os.path\nimport posixpath\nimport re\nimport threading\n\nfrom tornado import escape\nfrom tornado.log import app_log\nfrom tornado.util import ObjectDict, exec_in, unicode_type\n\ntry:\n    from cStringIO import StringIO  # py2\nexcept ImportError:\n    from io import StringIO  # py3\n\n_DEFAULT_AUTOESCAPE = \"xhtml_escape\"\n_UNSET = object()\n\n\ndef filter_whitespace(mode, text):\n    \"\"\"Transform whitespace in ``text`` according to ``mode``.\n\n    Available modes are:\n\n    * ``all``: Return all whitespace unmodified.\n    * ``single``: Collapse consecutive whitespace with a single whitespace\n      character, preserving newlines.\n\n    .. versionadded:: 4.3\n    \"\"\"\n    if mode == 'all':\n        return text\n    elif mode == 'single':\n        text = re.sub(r\"([\\t ]+)\", \" \", text)\n        text = re.sub(r\"(\\s*\\n\\s*)\", \"\\n\", text)\n        return text\n    else:\n        raise Exception(\"invalid whitespace mode %s\" % mode)\n\n\nclass Template(object):\n    \"\"\"A compiled template.\n\n    We compile into Python from the given template_string. You can generate\n    the template from variables with generate().\n    \"\"\"\n    # note that the constructor's signature is not extracted with\n    # autodoc because _UNSET looks like garbage.  When changing\n    # this signature update website/sphinx/template.rst too.\n    def __init__(self, template_string, name=\"<string>\", loader=None,\n                 compress_whitespace=_UNSET, autoescape=_UNSET,\n                 whitespace=None):\n        \"\"\"Construct a Template.\n\n        :arg str template_string: the contents of the template file.\n        :arg str name: the filename from which the template was loaded\n            (used for error message).\n        :arg tornado.template.BaseLoader loader: the `~tornado.template.BaseLoader` responsible for this template,\n            used to resolve ``{% include %}`` and ``{% extend %}``\n            directives.\n        :arg bool compress_whitespace: Deprecated since Tornado 4.3.\n            Equivalent to ``whitespace=\"single\"`` if true and\n            ``whitespace=\"all\"`` if false.\n        :arg str autoescape: The name of a function in the template\n            namespace, or ``None`` to disable escaping by default.\n        :arg str whitespace: A string specifying treatment of whitespace;\n            see `filter_whitespace` for options.\n\n        .. versionchanged:: 4.3\n           Added ``whitespace`` parameter; deprecated ``compress_whitespace``.\n        \"\"\"\n        self.name = name\n\n        if compress_whitespace is not _UNSET:\n            # Convert deprecated compress_whitespace (bool) to whitespace (str).\n            if whitespace is not None:\n                raise Exception(\"cannot set both whitespace and compress_whitespace\")\n            whitespace = \"single\" if compress_whitespace else \"all\"\n        if whitespace is None:\n            if loader and loader.whitespace:\n                whitespace = loader.whitespace\n            else:\n                # Whitespace defaults by filename.\n                if name.endswith(\".html\") or name.endswith(\".js\"):\n                    whitespace = \"single\"\n                else:\n                    whitespace = \"all\"\n        # Validate the whitespace setting.\n        filter_whitespace(whitespace, '')\n\n        if autoescape is not _UNSET:\n            self.autoescape = autoescape\n        elif loader:\n            self.autoescape = loader.autoescape\n        else:\n            self.autoescape = _DEFAULT_AUTOESCAPE\n\n        self.namespace = loader.namespace if loader else {}\n        reader = _TemplateReader(name, escape.native_str(template_string),\n                                 whitespace)\n        self.file = _File(self, _parse(reader, self))\n        self.code = self._generate_python(loader)\n        self.loader = loader\n        try:\n            # Under python2.5, the fake filename used here must match\n            # the module name used in __name__ below.\n            # The dont_inherit flag prevents template.py's future imports\n            # from being applied to the generated code.\n            self.compiled = compile(\n                escape.to_unicode(self.code),\n                \"%s.generated.py\" % self.name.replace('.', '_'),\n                \"exec\", dont_inherit=True)\n        except Exception:\n            formatted_code = _format_code(self.code).rstrip()\n            app_log.error(\"%s code:\\n%s\", self.name, formatted_code)\n            raise\n\n    def generate(self, **kwargs):\n        \"\"\"Generate this template with the given arguments.\"\"\"\n        namespace = {\n            \"escape\": escape.xhtml_escape,\n            \"xhtml_escape\": escape.xhtml_escape,\n            \"url_escape\": escape.url_escape,\n            \"json_encode\": escape.json_encode,\n            \"squeeze\": escape.squeeze,\n            \"linkify\": escape.linkify,\n            \"datetime\": datetime,\n            \"_tt_utf8\": escape.utf8,  # for internal use\n            \"_tt_string_types\": (unicode_type, bytes),\n            # __name__ and __loader__ allow the traceback mechanism to find\n            # the generated source code.\n            \"__name__\": self.name.replace('.', '_'),\n            \"__loader__\": ObjectDict(get_source=lambda name: self.code),\n        }\n        namespace.update(self.namespace)\n        namespace.update(kwargs)\n        exec_in(self.compiled, namespace)\n        execute = namespace[\"_tt_execute\"]\n        # Clear the traceback module's cache of source data now that\n        # we've generated a new template (mainly for this module's\n        # unittests, where different tests reuse the same name).\n        linecache.clearcache()\n        return execute()\n\n    def _generate_python(self, loader):\n        buffer = StringIO()\n        try:\n            # named_blocks maps from names to _NamedBlock objects\n            named_blocks = {}\n            ancestors = self._get_ancestors(loader)\n            ancestors.reverse()\n            for ancestor in ancestors:\n                ancestor.find_named_blocks(loader, named_blocks)\n            writer = _CodeWriter(buffer, named_blocks, loader,\n                                 ancestors[0].template)\n            ancestors[0].generate(writer)\n            return buffer.getvalue()\n        finally:\n            buffer.close()\n\n    def _get_ancestors(self, loader):\n        ancestors = [self.file]\n        for chunk in self.file.body.chunks:\n            if isinstance(chunk, _ExtendsBlock):\n                if not loader:\n                    raise ParseError(\"{% extends %} block found, but no \"\n                                     \"template loader\")\n                template = loader.load(chunk.name, self.name)\n                ancestors.extend(template._get_ancestors(loader))\n        return ancestors\n\n\nclass BaseLoader(object):\n    \"\"\"Base class for template loaders.\n\n    You must use a template loader to use template constructs like\n    ``{% extends %}`` and ``{% include %}``. The loader caches all\n    templates after they are loaded the first time.\n    \"\"\"\n    def __init__(self, autoescape=_DEFAULT_AUTOESCAPE, namespace=None,\n                 whitespace=None):\n        \"\"\"Construct a template loader.\n\n        :arg str autoescape: The name of a function in the template\n            namespace, such as \"xhtml_escape\", or ``None`` to disable\n            autoescaping by default.\n        :arg dict namespace: A dictionary to be added to the default template\n            namespace, or ``None``.\n        :arg str whitespace: A string specifying default behavior for\n            whitespace in templates; see `filter_whitespace` for options.\n            Default is \"single\" for files ending in \".html\" and \".js\" and\n            \"all\" for other files.\n\n        .. versionchanged:: 4.3\n           Added ``whitespace`` parameter.\n        \"\"\"\n        self.autoescape = autoescape\n        self.namespace = namespace or {}\n        self.whitespace = whitespace\n        self.templates = {}\n        # self.lock protects self.templates.  It's a reentrant lock\n        # because templates may load other templates via `include` or\n        # `extends`.  Note that thanks to the GIL this code would be safe\n        # even without the lock, but could lead to wasted work as multiple\n        # threads tried to compile the same template simultaneously.\n        self.lock = threading.RLock()\n\n    def reset(self):\n        \"\"\"Resets the cache of compiled templates.\"\"\"\n        with self.lock:\n            self.templates = {}\n\n    def resolve_path(self, name, parent_path=None):\n        \"\"\"Converts a possibly-relative path to absolute (used internally).\"\"\"\n        raise NotImplementedError()\n\n    def load(self, name, parent_path=None):\n        \"\"\"Loads a template.\"\"\"\n        name = self.resolve_path(name, parent_path=parent_path)\n        with self.lock:\n            if name not in self.templates:\n                self.templates[name] = self._create_template(name)\n            return self.templates[name]\n\n    def _create_template(self, name):\n        raise NotImplementedError()\n\n\nclass Loader(BaseLoader):\n    \"\"\"A template loader that loads from a single root directory.\n    \"\"\"\n    def __init__(self, root_directory, **kwargs):\n        super(Loader, self).__init__(**kwargs)\n        self.root = os.path.abspath(root_directory)\n\n    def resolve_path(self, name, parent_path=None):\n        if parent_path and not parent_path.startswith(\"<\") and \\\n            not parent_path.startswith(\"/\") and \\\n                not name.startswith(\"/\"):\n            current_path = os.path.join(self.root, parent_path)\n            file_dir = os.path.dirname(os.path.abspath(current_path))\n            relative_path = os.path.abspath(os.path.join(file_dir, name))\n            if relative_path.startswith(self.root):\n                name = relative_path[len(self.root) + 1:]\n        return name\n\n    def _create_template(self, name):\n        path = os.path.join(self.root, name)\n        with open(path, \"rb\") as f:\n            template = Template(f.read(), name=name, loader=self)\n            return template\n\n\nclass DictLoader(BaseLoader):\n    \"\"\"A template loader that loads from a dictionary.\"\"\"\n    def __init__(self, dict, **kwargs):\n        super(DictLoader, self).__init__(**kwargs)\n        self.dict = dict\n\n    def resolve_path(self, name, parent_path=None):\n        if parent_path and not parent_path.startswith(\"<\") and \\\n            not parent_path.startswith(\"/\") and \\\n                not name.startswith(\"/\"):\n            file_dir = posixpath.dirname(parent_path)\n            name = posixpath.normpath(posixpath.join(file_dir, name))\n        return name\n\n    def _create_template(self, name):\n        return Template(self.dict[name], name=name, loader=self)\n\n\nclass _Node(object):\n    def each_child(self):\n        return ()\n\n    def generate(self, writer):\n        raise NotImplementedError()\n\n    def find_named_blocks(self, loader, named_blocks):\n        for child in self.each_child():\n            child.find_named_blocks(loader, named_blocks)\n\n\nclass _File(_Node):\n    def __init__(self, template, body):\n        self.template = template\n        self.body = body\n        self.line = 0\n\n    def generate(self, writer):\n        writer.write_line(\"def _tt_execute():\", self.line)\n        with writer.indent():\n            writer.write_line(\"_tt_buffer = []\", self.line)\n            writer.write_line(\"_tt_append = _tt_buffer.append\", self.line)\n            self.body.generate(writer)\n            writer.write_line(\"return _tt_utf8('').join(_tt_buffer)\", self.line)\n\n    def each_child(self):\n        return (self.body,)\n\n\nclass _ChunkList(_Node):\n    def __init__(self, chunks):\n        self.chunks = chunks\n\n    def generate(self, writer):\n        for chunk in self.chunks:\n            chunk.generate(writer)\n\n    def each_child(self):\n        return self.chunks\n\n\nclass _NamedBlock(_Node):\n    def __init__(self, name, body, template, line):\n        self.name = name\n        self.body = body\n        self.template = template\n        self.line = line\n\n    def each_child(self):\n        return (self.body,)\n\n    def generate(self, writer):\n        block = writer.named_blocks[self.name]\n        with writer.include(block.template, self.line):\n            block.body.generate(writer)\n\n    def find_named_blocks(self, loader, named_blocks):\n        named_blocks[self.name] = self\n        _Node.find_named_blocks(self, loader, named_blocks)\n\n\nclass _ExtendsBlock(_Node):\n    def __init__(self, name):\n        self.name = name\n\n\nclass _IncludeBlock(_Node):\n    def __init__(self, name, reader, line):\n        self.name = name\n        self.template_name = reader.name\n        self.line = line\n\n    def find_named_blocks(self, loader, named_blocks):\n        included = loader.load(self.name, self.template_name)\n        included.file.find_named_blocks(loader, named_blocks)\n\n    def generate(self, writer):\n        included = writer.loader.load(self.name, self.template_name)\n        with writer.include(included, self.line):\n            included.file.body.generate(writer)\n\n\nclass _ApplyBlock(_Node):\n    def __init__(self, method, line, body=None):\n        self.method = method\n        self.line = line\n        self.body = body\n\n    def each_child(self):\n        return (self.body,)\n\n    def generate(self, writer):\n        method_name = \"_tt_apply%d\" % writer.apply_counter\n        writer.apply_counter += 1\n        writer.write_line(\"def %s():\" % method_name, self.line)\n        with writer.indent():\n            writer.write_line(\"_tt_buffer = []\", self.line)\n            writer.write_line(\"_tt_append = _tt_buffer.append\", self.line)\n            self.body.generate(writer)\n            writer.write_line(\"return _tt_utf8('').join(_tt_buffer)\", self.line)\n        writer.write_line(\"_tt_append(_tt_utf8(%s(%s())))\" % (\n            self.method, method_name), self.line)\n\n\nclass _ControlBlock(_Node):\n    def __init__(self, statement, line, body=None):\n        self.statement = statement\n        self.line = line\n        self.body = body\n\n    def each_child(self):\n        return (self.body,)\n\n    def generate(self, writer):\n        writer.write_line(\"%s:\" % self.statement, self.line)\n        with writer.indent():\n            self.body.generate(writer)\n            # Just in case the body was empty\n            writer.write_line(\"pass\", self.line)\n\n\nclass _IntermediateControlBlock(_Node):\n    def __init__(self, statement, line):\n        self.statement = statement\n        self.line = line\n\n    def generate(self, writer):\n        # In case the previous block was empty\n        writer.write_line(\"pass\", self.line)\n        writer.write_line(\"%s:\" % self.statement, self.line, writer.indent_size() - 1)\n\n\nclass _Statement(_Node):\n    def __init__(self, statement, line):\n        self.statement = statement\n        self.line = line\n\n    def generate(self, writer):\n        writer.write_line(self.statement, self.line)\n\n\nclass _Expression(_Node):\n    def __init__(self, expression, line, raw=False):\n        self.expression = expression\n        self.line = line\n        self.raw = raw\n\n    def generate(self, writer):\n        writer.write_line(\"_tt_tmp = %s\" % self.expression, self.line)\n        writer.write_line(\"if isinstance(_tt_tmp, _tt_string_types):\"\n                          \" _tt_tmp = _tt_utf8(_tt_tmp)\", self.line)\n        writer.write_line(\"else: _tt_tmp = _tt_utf8(str(_tt_tmp))\", self.line)\n        if not self.raw and writer.current_template.autoescape is not None:\n            # In python3 functions like xhtml_escape return unicode,\n            # so we have to convert to utf8 again.\n            writer.write_line(\"_tt_tmp = _tt_utf8(%s(_tt_tmp))\" %\n                              writer.current_template.autoescape, self.line)\n        writer.write_line(\"_tt_append(_tt_tmp)\", self.line)\n\n\nclass _Module(_Expression):\n    def __init__(self, expression, line):\n        super(_Module, self).__init__(\"_tt_modules.\" + expression, line,\n                                      raw=True)\n\n\nclass _Text(_Node):\n    def __init__(self, value, line, whitespace):\n        self.value = value\n        self.line = line\n        self.whitespace = whitespace\n\n    def generate(self, writer):\n        value = self.value\n\n        # Compress whitespace if requested, with a crude heuristic to avoid\n        # altering preformatted whitespace.\n        if \"<pre>\" not in value:\n            value = filter_whitespace(self.whitespace, value)\n\n        if value:\n            writer.write_line('_tt_append(%r)' % escape.utf8(value), self.line)\n\n\nclass ParseError(Exception):\n    \"\"\"Raised for template syntax errors.\n\n    ``ParseError`` instances have ``filename`` and ``lineno`` attributes\n    indicating the position of the error.\n\n    .. versionchanged:: 4.3\n       Added ``filename`` and ``lineno`` attributes.\n    \"\"\"\n    def __init__(self, message, filename, lineno):\n        self.message = message\n        # The names \"filename\" and \"lineno\" are chosen for consistency\n        # with python SyntaxError.\n        self.filename = filename\n        self.lineno = lineno\n\n    def __str__(self):\n        return '%s at %s:%d' % (self.message, self.filename, self.lineno)\n\n\nclass _CodeWriter(object):\n    def __init__(self, file, named_blocks, loader, current_template):\n        self.file = file\n        self.named_blocks = named_blocks\n        self.loader = loader\n        self.current_template = current_template\n        self.apply_counter = 0\n        self.include_stack = []\n        self._indent = 0\n\n    def indent_size(self):\n        return self._indent\n\n    def indent(self):\n        class Indenter(object):\n            def __enter__(_):\n                self._indent += 1\n                return self\n\n            def __exit__(_, *args):\n                assert self._indent > 0\n                self._indent -= 1\n\n        return Indenter()\n\n    def include(self, template, line):\n        self.include_stack.append((self.current_template, line))\n        self.current_template = template\n\n        class IncludeTemplate(object):\n            def __enter__(_):\n                return self\n\n            def __exit__(_, *args):\n                self.current_template = self.include_stack.pop()[0]\n\n        return IncludeTemplate()\n\n    def write_line(self, line, line_number, indent=None):\n        if indent is None:\n            indent = self._indent\n        line_comment = '  # %s:%d' % (self.current_template.name, line_number)\n        if self.include_stack:\n            ancestors = [\"%s:%d\" % (tmpl.name, lineno)\n                         for (tmpl, lineno) in self.include_stack]\n            line_comment += ' (via %s)' % ', '.join(reversed(ancestors))\n        print(\"    \" * indent + line + line_comment, file=self.file)\n\n\nclass _TemplateReader(object):\n    def __init__(self, name, text, whitespace):\n        self.name = name\n        self.text = text\n        self.whitespace = whitespace\n        self.line = 1\n        self.pos = 0\n\n    def find(self, needle, start=0, end=None):\n        assert start >= 0, start\n        pos = self.pos\n        start += pos\n        if end is None:\n            index = self.text.find(needle, start)\n        else:\n            end += pos\n            assert end >= start\n            index = self.text.find(needle, start, end)\n        if index != -1:\n            index -= pos\n        return index\n\n    def consume(self, count=None):\n        if count is None:\n            count = len(self.text) - self.pos\n        newpos = self.pos + count\n        self.line += self.text.count(\"\\n\", self.pos, newpos)\n        s = self.text[self.pos:newpos]\n        self.pos = newpos\n        return s\n\n    def remaining(self):\n        return len(self.text) - self.pos\n\n    def __len__(self):\n        return self.remaining()\n\n    def __getitem__(self, key):\n        if type(key) is slice:\n            size = len(self)\n            start, stop, step = key.indices(size)\n            if start is None:\n                start = self.pos\n            else:\n                start += self.pos\n            if stop is not None:\n                stop += self.pos\n            return self.text[slice(start, stop, step)]\n        elif key < 0:\n            return self.text[key]\n        else:\n            return self.text[self.pos + key]\n\n    def __str__(self):\n        return self.text[self.pos:]\n\n    def raise_parse_error(self, msg):\n        raise ParseError(msg, self.name, self.line)\n\n\ndef _format_code(code):\n    lines = code.splitlines()\n    format = \"%%%dd  %%s\\n\" % len(repr(len(lines) + 1))\n    return \"\".join([format % (i + 1, line) for (i, line) in enumerate(lines)])\n\n\ndef _parse(reader, template, in_block=None, in_loop=None):\n    body = _ChunkList([])\n    while True:\n        # Find next template directive\n        curly = 0\n        while True:\n            curly = reader.find(\"{\", curly)\n            if curly == -1 or curly + 1 == reader.remaining():\n                # EOF\n                if in_block:\n                    reader.raise_parse_error(\n                        \"Missing {%% end %%} block for %s\" % in_block)\n                body.chunks.append(_Text(reader.consume(), reader.line,\n                                         reader.whitespace))\n                return body\n            # If the first curly brace is not the start of a special token,\n            # start searching from the character after it\n            if reader[curly + 1] not in (\"{\", \"%\", \"#\"):\n                curly += 1\n                continue\n            # When there are more than 2 curlies in a row, use the\n            # innermost ones.  This is useful when generating languages\n            # like latex where curlies are also meaningful\n            if (curly + 2 < reader.remaining() and\n                    reader[curly + 1] == '{' and reader[curly + 2] == '{'):\n                curly += 1\n                continue\n            break\n\n        # Append any text before the special token\n        if curly > 0:\n            cons = reader.consume(curly)\n            body.chunks.append(_Text(cons, reader.line,\n                                     reader.whitespace))\n\n        start_brace = reader.consume(2)\n        line = reader.line\n\n        # Template directives may be escaped as \"{{!\" or \"{%!\".\n        # In this case output the braces and consume the \"!\".\n        # This is especially useful in conjunction with jquery templates,\n        # which also use double braces.\n        if reader.remaining() and reader[0] == \"!\":\n            reader.consume(1)\n            body.chunks.append(_Text(start_brace, line,\n                                     reader.whitespace))\n            continue\n\n        # Comment\n        if start_brace == \"{#\":\n            end = reader.find(\"#}\")\n            if end == -1:\n                reader.raise_parse_error(\"Missing end comment #}\")\n            contents = reader.consume(end).strip()\n            reader.consume(2)\n            continue\n\n        # Expression\n        if start_brace == \"{{\":\n            end = reader.find(\"}}\")\n            if end == -1:\n                reader.raise_parse_error(\"Missing end expression }}\")\n            contents = reader.consume(end).strip()\n            reader.consume(2)\n            if not contents:\n                reader.raise_parse_error(\"Empty expression\")\n            body.chunks.append(_Expression(contents, line))\n            continue\n\n        # Block\n        assert start_brace == \"{%\", start_brace\n        end = reader.find(\"%}\")\n        if end == -1:\n            reader.raise_parse_error(\"Missing end block %}\")\n        contents = reader.consume(end).strip()\n        reader.consume(2)\n        if not contents:\n            reader.raise_parse_error(\"Empty block tag ({% %})\")\n\n        operator, space, suffix = contents.partition(\" \")\n        suffix = suffix.strip()\n\n        # Intermediate (\"else\", \"elif\", etc) blocks\n        intermediate_blocks = {\n            \"else\": set([\"if\", \"for\", \"while\", \"try\"]),\n            \"elif\": set([\"if\"]),\n            \"except\": set([\"try\"]),\n            \"finally\": set([\"try\"]),\n        }\n        allowed_parents = intermediate_blocks.get(operator)\n        if allowed_parents is not None:\n            if not in_block:\n                reader.raise_parse_error(\"%s outside %s block\" %\n                                         (operator, allowed_parents))\n            if in_block not in allowed_parents:\n                reader.raise_parse_error(\n                    \"%s block cannot be attached to %s block\" %\n                    (operator, in_block))\n            body.chunks.append(_IntermediateControlBlock(contents, line))\n            continue\n\n        # End tag\n        elif operator == \"end\":\n            if not in_block:\n                reader.raise_parse_error(\"Extra {% end %} block\")\n            return body\n\n        elif operator in (\"extends\", \"include\", \"set\", \"import\", \"from\",\n                          \"comment\", \"autoescape\", \"raw\", \"module\"):\n            if operator == \"comment\":\n                continue\n            if operator == \"extends\":\n                suffix = suffix.strip('\"').strip(\"'\")\n                if not suffix:\n                    reader.raise_parse_error(\"extends missing file path\")\n                block = _ExtendsBlock(suffix)\n            elif operator in (\"import\", \"from\"):\n                if not suffix:\n                    reader.raise_parse_error(\"import missing statement\")\n                block = _Statement(contents, line)\n            elif operator == \"include\":\n                suffix = suffix.strip('\"').strip(\"'\")\n                if not suffix:\n                    reader.raise_parse_error(\"include missing file path\")\n                block = _IncludeBlock(suffix, reader, line)\n            elif operator == \"set\":\n                if not suffix:\n                    reader.raise_parse_error(\"set missing statement\")\n                block = _Statement(suffix, line)\n            elif operator == \"autoescape\":\n                fn = suffix.strip()\n                if fn == \"None\":\n                    fn = None\n                template.autoescape = fn\n                continue\n            elif operator == \"raw\":\n                block = _Expression(suffix, line, raw=True)\n            elif operator == \"module\":\n                block = _Module(suffix, line)\n            body.chunks.append(block)\n            continue\n\n        elif operator in (\"apply\", \"block\", \"try\", \"if\", \"for\", \"while\"):\n            # parse inner body recursively\n            if operator in (\"for\", \"while\"):\n                block_body = _parse(reader, template, operator, operator)\n            elif operator == \"apply\":\n                # apply creates a nested function so syntactically it's not\n                # in the loop.\n                block_body = _parse(reader, template, operator, None)\n            else:\n                block_body = _parse(reader, template, operator, in_loop)\n\n            if operator == \"apply\":\n                if not suffix:\n                    reader.raise_parse_error(\"apply missing method name\")\n                block = _ApplyBlock(suffix, line, block_body)\n            elif operator == \"block\":\n                if not suffix:\n                    reader.raise_parse_error(\"block missing name\")\n                block = _NamedBlock(suffix, block_body, template, line)\n            else:\n                block = _ControlBlock(contents, line, block_body)\n            body.chunks.append(block)\n            continue\n\n        elif operator in (\"break\", \"continue\"):\n            if not in_loop:\n                reader.raise_parse_error(\"%s outside %s block\" %\n                                         (operator, set([\"for\", \"while\"])))\n            body.chunks.append(_Statement(contents, line))\n            continue\n\n        else:\n            reader.raise_parse_error(\"unknown operator: %r\" % operator)\n"}
A user will ask you to solve a task. You should first draft your thinking process (inner monologue). Then, generate the solution.

Your response format must follow the template below:
<think>
Your thoughts or/and draft, like working through an exercise on scratch paper. Be as casual and as long as you want until you are confident to generate a correct solution.
</think>
<solution>
Final solution presented to the user.
</solution>
system
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]

**Title:**
Exception Raised When Using Unsupported 'oneline' Whitespace Mode

**Description:**
When configuring the template loader with the `whitespace` mode set to `'oneline'`, an exception is thrown indicating that the whitespace mode is invalid. This prevents the use of the `'oneline'` mode for removing excessive whitespace in templates.

**Example Code:**
```python
from tornado.template import DictLoader

def test_oneline_whitespace_mode():
    templates = {'example.html': '\n\n<div>Content</div>\n\n'}
    loader = DictLoader(templates, whitespace='oneline')
    loader.load('example.html').generate()
```

**Expected Behavior:**
The template should be processed by collapsing all runs of whitespace into a single space and removing all newlines, resulting in the HTML being rendered without unnecessary blank lines.

**Actual Behavior:**
An exception is raised with the message: `Exception: invalid whitespace mode oneline`

[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### tornado/template.py
#!/usr/bin/env python
#
# Copyright 2009 Facebook
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""A simple template system that compiles templates to Python code.

Basic usage looks like::

    t = template.Template("<html>{{ myvalue }}</html>")
    print t.generate(myvalue="XXX")

`Loader` is a class that loads templates from a root directory and caches
the compiled templates::

    loader = template.Loader("/home/btaylor")
    print loader.load("test.html").generate(myvalue="XXX")

We compile all templates to raw Python. Error-reporting is currently... uh,
interesting. Syntax for the templates::

    ### base.html
    <html>
      <head>
        <title>{% block title %}Default title{% end %}</title>
      </head>
      <body>
        <ul>
          {% for student in students %}
            {% block student %}
              <li>{{ escape(student.name) }}</li>
            {% end %}
          {% end %}
        </ul>
      </body>
    </html>

    ### bold.html
    {% extends "base.html" %}

    {% block title %}A bolder title{% end %}

    {% block student %}
      <li><span style="bold">{{ escape(student.name) }}</span></li>
    {% end %}

Unlike most other template systems, we do not put any restrictions on the
expressions you can include in your statements. ``if`` and ``for`` blocks get
translated exactly into Python, so you can do complex expressions like::

   {% for student in [p for p in people if p.student and p.age > 23] %}
     <li>{{ escape(student.name) }}</li>
   {% end %}

Translating directly to Python means you can apply functions to expressions
easily, like the ``escape()`` function in the examples above. You can pass
functions in to your template just like any other variable
(In a `.RequestHandler`, override `.RequestHandler.get_template_namespace`)::

   ### Python code
   def add(x, y):
      return x + y
   template.execute(add=add)

   ### The template
   {{ add(1, 2) }}

We provide the functions `escape() <.xhtml_escape>`, `.url_escape()`,
`.json_encode()`, and `.squeeze()` to all templates by default.

Typical applications do not create `Template` or `Loader` instances by
hand, but instead use the `~.RequestHandler.render` and
`~.RequestHandler.render_string` methods of
`tornado.web.RequestHandler`, which load templates automatically based
on the ``template_path`` `.Application` setting.

Variable names beginning with ``_tt_`` are reserved by the template
system and should not be used by application code.

Syntax Reference
----------------

Template expressions are surrounded by double curly braces: ``{{ ... }}``.
The contents may be any python expression, which will be escaped according
to the current autoescape setting and inserted into the output.  Other
template directives use ``{% %}``.  These tags may be escaped as ``{{!``
and ``{%!`` if you need to include a literal ``{{`` or ``{%`` in the output.

To comment out a section so that it is omitted from the output, surround it
with ``{# ... #}``.

``{% apply *function* %}...{% end %}``
    Applies a function to the output of all template code between ``apply``
    and ``end``::

        {% apply linkify %}{{name}} said: {{message}}{% end %}

    Note that as an implementation detail apply blocks are implemented
    as nested functions and thus may interact strangely with variables
    set via ``{% set %}``, or the use of ``{% break %}`` or ``{% continue %}``
    within loops.

``{% autoescape *function* %}``
    Sets the autoescape mode for the current file.  This does not affect
    other files, even those referenced by ``{% include %}``.  Note that
    autoescaping can also be configured globally, at the `.Application`
    or `Loader`.::

        {% autoescape xhtml_escape %}
        {% autoescape None %}

``{% block *name* %}...{% end %}``
    Indicates a named, replaceable block for use with ``{% extends %}``.
    Blocks in the parent template will be replaced with the contents of
    the same-named block in a child template.::

        <!-- base.html -->
        <title>{% block title %}Default title{% end %}</title>

        <!-- mypage.html -->
        {% extends "base.html" %}
        {% block title %}My page title{% end %}

``{% comment ... %}``
    A comment which will be removed from the template output.  Note that
    there is no ``{% end %}`` tag; the comment goes from the word ``comment``
    to the closing ``%}`` tag.

``{% extends *filename* %}``
    Inherit from another template.  Templates that use ``extends`` should
    contain one or more ``block`` tags to replace content from the parent
    template.  Anything in the child template not contained in a ``block``
    tag will be ignored.  For an example, see the ``{% block %}`` tag.

``{% for *var* in *expr* %}...{% end %}``
    Same as the python ``for`` statement.  ``{% break %}`` and
    ``{% continue %}`` may be used inside the loop.

``{% from *x* import *y* %}``
    Same as the python ``import`` statement.

``{% if *condition* %}...{% elif *condition* %}...{% else %}...{% end %}``
    Conditional statement - outputs the first section whose condition is
    true.  (The ``elif`` and ``else`` sections are optional)

``{% import *module* %}``
    Same as the python ``import`` statement.

``{% include *filename* %}``
    Includes another template file.  The included file can see all the local
    variables as if it were copied directly to the point of the ``include``
    directive (the ``{% autoescape %}`` directive is an exception).
    Alternately, ``{% module Template(filename, **kwargs) %}`` may be used
    to include another template with an isolated namespace.

``{% module *expr* %}``
    Renders a `~tornado.web.UIModule`.  The output of the ``UIModule`` is
    not escaped::

        {% module Template("foo.html", arg=42) %}

    ``UIModules`` are a feature of the `tornado.web.RequestHandler`
    class (and specifically its ``render`` method) and will not work
    when the template system is used on its own in other contexts.

``{% raw *expr* %}``
    Outputs the result of the given expression without autoescaping.

``{% set *x* = *y* %}``
    Sets a local variable.

``{% try %}...{% except %}...{% else %}...{% finally %}...{% end %}``
    Same as the python ``try`` statement.

``{% while *condition* %}... {% end %}``
    Same as the python ``while`` statement.  ``{% break %}`` and
    ``{% continue %}`` may be used inside the loop.
"""

from __future__ import absolute_import, division, print_function, with_statement

import datetime
import linecache
import os.path
import posixpath
import re
import threading

from tornado import escape
from tornado.log import app_log
from tornado.util import ObjectDict, exec_in, unicode_type

try:
    from cStringIO import StringIO  # py2
except ImportError:
    from io import StringIO  # py3

_DEFAULT_AUTOESCAPE = "xhtml_escape"
_UNSET = object()


def filter_whitespace(mode, text):
    """Transform whitespace in ``text`` according to ``mode``.

    Available modes are:

    * ``all``: Return all whitespace unmodified.
    * ``single``: Collapse consecutive whitespace with a single whitespace
      character, preserving newlines.

    .. versionadded:: 4.3
    """
    if mode == 'all':
        return text
    elif mode == 'single':
        text = re.sub(r"([\t ]+)", " ", text)
        text = re.sub(r"(\s*\n\s*)", "\n", text)
        return text
    else:
        raise Exception("invalid whitespace mode %s" % mode)


class Template(object):
    """A compiled template.

    We compile into Python from the given template_string. You can generate
    the template from variables with generate().
    """
    # note that the constructor's signature is not extracted with
    # autodoc because _UNSET looks like garbage.  When changing
    # this signature update website/sphinx/template.rst too.
    def __init__(self, template_string, name="<string>", loader=None,
                 compress_whitespace=_UNSET, autoescape=_UNSET,
                 whitespace=None):
        """Construct a Template.

        :arg str template_string: the contents of the template file.
        :arg str name: the filename from which the template was loaded
            (used for error message).
        :arg tornado.template.BaseLoader loader: the `~tornado.template.BaseLoader` responsible for this template,
            used to resolve ``{% include %}`` and ``{% extend %}``
            directives.
        :arg bool compress_whitespace: Deprecated since Tornado 4.3.
            Equivalent to ``whitespace="single"`` if true and
            ``whitespace="all"`` if false.
        :arg str autoescape: The name of a function in the template
            namespace, or ``None`` to disable escaping by default.
        :arg str whitespace: A string specifying treatment of whitespace;
            see `filter_whitespace` for options.

        .. versionchanged:: 4.3
           Added ``whitespace`` parameter; deprecated ``compress_whitespace``.
        """
        self.name = name

        if compress_whitespace is not _UNSET:
            # Convert deprecated compress_whitespace (bool) to whitespace (str).
            if whitespace is not None:
                raise Exception("cannot set both whitespace and compress_whitespace")
            whitespace = "single" if compress_whitespace else "all"
        if whitespace is None:
            if loader and loader.whitespace:
                whitespace = loader.whitespace
            else:
                # Whitespace defaults by filename.
                if name.endswith(".html") or name.endswith(".js"):
                    whitespace = "single"
                else:
                    whitespace = "all"
        # Validate the whitespace setting.
        filter_whitespace(whitespace, '')

        if autoescape is not _UNSET:
            self.autoescape = autoescape
        elif loader:
            self.autoescape = loader.autoescape
        else:
            self.autoescape = _DEFAULT_AUTOESCAPE

        self.namespace = loader.namespace if loader else {}
        reader = _TemplateReader(name, escape.native_str(template_string),
                                 whitespace)
        self.file = _File(self, _parse(reader, self))
        self.code = self._generate_python(loader)
        self.loader = loader
        try:
            # Under python2.5, the fake filename used here must match
            # the module name used in __name__ below.
            # The dont_inherit flag prevents template.py's future imports
            # from being applied to the generated code.
            self.compiled = compile(
                escape.to_unicode(self.code),
                "%s.generated.py" % self.name.replace('.', '_'),
                "exec", dont_inherit=True)
        except Exception:
            formatted_code = _format_code(self.code).rstrip()
            app_log.error("%s code:\n%s", self.name, formatted_code)
            raise

    def generate(self, **kwargs):
        """Generate this template with the given arguments."""
        namespace = {
            "escape": escape.xhtml_escape,
            "xhtml_escape": escape.xhtml_escape,
            "url_escape": escape.url_escape,
            "json_encode": escape.json_encode,
            "squeeze": escape.squeeze,
            "linkify": escape.linkify,
            "datetime": datetime,
            "_tt_utf8": escape.utf8,  # for internal use
            "_tt_string_types": (unicode_type, bytes),
            # __name__ and __loader__ allow the traceback mechanism to find
            # the generated source code.
            "__name__": self.name.replace('.', '_'),
            "__loader__": ObjectDict(get_source=lambda name: self.code),
        }
        namespace.update(self.namespace)
        namespace.update(kwargs)
        exec_in(self.compiled, namespace)
        execute = namespace["_tt_execute"]
        # Clear the traceback module's cache of source data now that
        # we've generated a new template (mainly for this module's
        # unittests, where different tests reuse the same name).
        linecache.clearcache()
        return execute()

    def _generate_python(self, loader):
        buffer = StringIO()
        try:
            # named_blocks maps from names to _NamedBlock objects
            named_blocks = {}
            ancestors = self._get_ancestors(loader)
            ancestors.reverse()
            for ancestor in ancestors:
                ancestor.find_named_blocks(loader, named_blocks)
            writer = _CodeWriter(buffer, named_blocks, loader,
                                 ancestors[0].template)
            ancestors[0].generate(writer)
            return buffer.getvalue()
        finally:
            buffer.close()

    def _get_ancestors(self, loader):
        ancestors = [self.file]
        for chunk in self.file.body.chunks:
            if isinstance(chunk, _ExtendsBlock):
                if not loader:
                    raise ParseError("{% extends %} block found, but no "
                                     "template loader")
                template = loader.load(chunk.name, self.name)
                ancestors.extend(template._get_ancestors(loader))
        return ancestors


class BaseLoader(object):
    """Base class for template loaders.

    You must use a template loader to use template constructs like
    ``{% extends %}`` and ``{% include %}``. The loader caches all
    templates after they are loaded the first time.
    """
    def __init__(self, autoescape=_DEFAULT_AUTOESCAPE, namespace=None,
                 whitespace=None):
        """Construct a template loader.

        :arg str autoescape: The name of a function in the template
            namespace, such as "xhtml_escape", or ``None`` to disable
            autoescaping by default.
        :arg dict namespace: A dictionary to be added to the default template
            namespace, or ``None``.
        :arg str whitespace: A string specifying default behavior for
            whitespace in templates; see `filter_whitespace` for options.
            Default is "single" for files ending in ".html" and ".js" and
            "all" for other files.

        .. versionchanged:: 4.3
           Added ``whitespace`` parameter.
        """
        self.autoescape = autoescape
        self.namespace = namespace or {}
        self.whitespace = whitespace
        self.templates = {}
        # self.lock protects self.templates.  It's a reentrant lock
        # because templates may load other templates via `include` or
        # `extends`.  Note that thanks to the GIL this code would be safe
        # even without the lock, but could lead to wasted work as multiple
        # threads tried to compile the same template simultaneously.
        self.lock = threading.RLock()

    def reset(self):
        """Resets the cache of compiled templates."""
        with self.lock:
            self.templates = {}

    def resolve_path(self, name, parent_path=None):
        """Converts a possibly-relative path to absolute (used internally)."""
        raise NotImplementedError()

    def load(self, name, parent_path=None):
        """Loads a template."""
        name = self.resolve_path(name, parent_path=parent_path)
        with self.lock:
            if name not in self.templates:
                self.templates[name] = self._create_template(name)
            return self.templates[name]

    def _create_template(self, name):
        raise NotImplementedError()


class Loader(BaseLoader):
    """A template loader that loads from a single root directory.
    """
    def __init__(self, root_directory, **kwargs):
        super(Loader, self).__init__(**kwargs)
        self.root = os.path.abspath(root_directory)

    def resolve_path(self, name, parent_path=None):
        if parent_path and not parent_path.startswith("<") and \
            not parent_path.startswith("/") and \
                not name.startswith("/"):
            current_path = os.path.join(self.root, parent_path)
            file_dir = os.path.dirname(os.path.abspath(current_path))
            relative_path = os.path.abspath(os.path.join(file_dir, name))
            if relative_path.startswith(self.root):
                name = relative_path[len(self.root) + 1:]
        return name

    def _create_template(self, name):
        path = os.path.join(self.root, name)
        with open(path, "rb") as f:
            template = Template(f.read(), name=name, loader=self)
            return template


class DictLoader(BaseLoader):
    """A template loader that loads from a dictionary."""
    def __init__(self, dict, **kwargs):
        super(DictLoader, self).__init__(**kwargs)
        self.dict = dict

    def resolve_path(self, name, parent_path=None):
        if parent_path and not parent_path.startswith("<") and \
            not parent_path.startswith("/") and \
                not name.startswith("/"):
            file_dir = posixpath.dirname(parent_path)
            name = posixpath.normpath(posixpath.join(file_dir, name))
        return name

    def _create_template(self, name):
        return Template(self.dict[name], name=name, loader=self)


class _Node(object):
    def each_child(self):
        return ()

    def generate(self, writer):
        raise NotImplementedError()

    def find_named_blocks(self, loader, named_blocks):
        for child in self.each_child():
            child.find_named_blocks(loader, named_blocks)


class _File(_Node):
    def __init__(self, template, body):
        self.template = template
        self.body = body
        self.line = 0

    def generate(self, writer):
        writer.write_line("def _tt_execute():", self.line)
        with writer.indent():
            writer.write_line("_tt_buffer = []", self.line)
            writer.write_line("_tt_append = _tt_buffer.append", self.line)
            self.body.generate(writer)
            writer.write_line("return _tt_utf8('').join(_tt_buffer)", self.line)

    def each_child(self):
        return (self.body,)


class _ChunkList(_Node):
    def __init__(self, chunks):
        self.chunks = chunks

    def generate(self, writer):
        for chunk in self.chunks:
            chunk.generate(writer)

    def each_child(self):
        return self.chunks


class _NamedBlock(_Node):
    def __init__(self, name, body, template, line):
        self.name = name
        self.body = body
        self.template = template
        self.line = line

    def each_child(self):
        return (self.body,)

    def generate(self, writer):
        block = writer.named_blocks[self.name]
        with writer.include(block.template, self.line):
            block.body.generate(writer)

    def find_named_blocks(self, loader, named_blocks):
        named_blocks[self.name] = self
        _Node.find_named_blocks(self, loader, named_blocks)


class _ExtendsBlock(_Node):
    def __init__(self, name):
        self.name = name


class _IncludeBlock(_Node):
    def __init__(self, name, reader, line):
        self.name = name
        self.template_name = reader.name
        self.line = line

    def find_named_blocks(self, loader, named_blocks):
        included = loader.load(self.name, self.template_name)
        included.file.find_named_blocks(loader, named_blocks)

    def generate(self, writer):
        included = writer.loader.load(self.name, self.template_name)
        with writer.include(included, self.line):
            included.file.body.generate(writer)


class _ApplyBlock(_Node):
    def __init__(self, method, line, body=None):
        self.method = method
        self.line = line
        self.body = body

    def each_child(self):
        return (self.body,)

    def generate(self, writer):
        method_name = "_tt_apply%d" % writer.apply_counter
        writer.apply_counter += 1
        writer.write_line("def %s():" % method_name, self.line)
        with writer.indent():
            writer.write_line("_tt_buffer = []", self.line)
            writer.write_line("_tt_append = _tt_buffer.append", self.line)
            self.body.generate(writer)
            writer.write_line("return _tt_utf8('').join(_tt_buffer)", self.line)
        writer.write_line("_tt_append(_tt_utf8(%s(%s())))" % (
            self.method, method_name), self.line)


class _ControlBlock(_Node):
    def __init__(self, statement, line, body=None):
        self.statement = statement
        self.line = line
        self.body = body

    def each_child(self):
        return (self.body,)

    def generate(self, writer):
        writer.write_line("%s:" % self.statement, self.line)
        with writer.indent():
            self.body.generate(writer)
            # Just in case the body was empty
            writer.write_line("pass", self.line)


class _IntermediateControlBlock(_Node):
    def __init__(self, statement, line):
        self.statement = statement
        self.line = line

    def generate(self, writer):
        # In case the previous block was empty
        writer.write_line("pass", self.line)
        writer.write_line("%s:" % self.statement, self.line, writer.indent_size() - 1)


class _Statement(_Node):
    def __init__(self, statement, line):
        self.statement = statement
        self.line = line

    def generate(self, writer):
        writer.write_line(self.statement, self.line)


class _Expression(_Node):
    def __init__(self, expression, line, raw=False):
        self.expression = expression
        self.line = line
        self.raw = raw

    def generate(self, writer):
        writer.write_line("_tt_tmp = %s" % self.expression, self.line)
        writer.write_line("if isinstance(_tt_tmp, _tt_string_types):"
                          " _tt_tmp = _tt_utf8(_tt_tmp)", self.line)
        writer.write_line("else: _tt_tmp = _tt_utf8(str(_tt_tmp))", self.line)
        if not self.raw and writer.current_template.autoescape is not None:
            # In python3 functions like xhtml_escape return unicode,
            # so we have to convert to utf8 again.
            writer.write_line("_tt_tmp = _tt_utf8(%s(_tt_tmp))" %
                              writer.current_template.autoescape, self.line)
        writer.write_line("_tt_append(_tt_tmp)", self.line)


class _Module(_Expression):
    def __init__(self, expression, line):
        super(_Module, self).__init__("_tt_modules." + expression, line,
                                      raw=True)


class _Text(_Node):
    def __init__(self, value, line, whitespace):
        self.value = value
        self.line = line
        self.whitespace = whitespace

    def generate(self, writer):
        value = self.value

        # Compress whitespace if requested, with a crude heuristic to avoid
        # altering preformatted whitespace.
        if "<pre>" not in value:
            value = filter_whitespace(self.whitespace, value)

        if value:
            writer.write_line('_tt_append(%r)' % escape.utf8(value), self.line)


class ParseError(Exception):
    """Raised for template syntax errors.

    ``ParseError`` instances have ``filename`` and ``lineno`` attributes
    indicating the position of the error.

    .. versionchanged:: 4.3
       Added ``filename`` and ``lineno`` attributes.
    """
    def __init__(self, message, filename, lineno):
        self.message = message
        # The names "filename" and "lineno" are chosen for consistency
        # with python SyntaxError.
        self.filename = filename
        self.lineno = lineno

    def __str__(self):
        return '%s at %s:%d' % (self.message, self.filename, self.lineno)


class _CodeWriter(object):
    def __init__(self, file, named_blocks, loader, current_template):
        self.file = file
        self.named_blocks = named_blocks
        self.loader = loader
        self.current_template = current_template
        self.apply_counter = 0
        self.include_stack = []
        self._indent = 0

    def indent_size(self):
        return self._indent

    def indent(self):
        class Indenter(object):
            def __enter__(_):
                self._indent += 1
                return self

            def __exit__(_, *args):
                assert self._indent > 0
                self._indent -= 1

        return Indenter()

    def include(self, template, line):
        self.include_stack.append((self.current_template, line))
        self.current_template = template

        class IncludeTemplate(object):
            def __enter__(_):
                return self

            def __exit__(_, *args):
                self.current_template = self.include_stack.pop()[0]

        return IncludeTemplate()

    def write_line(self, line, line_number, indent=None):
        if indent is None:
            indent = self._indent
        line_comment = '  # %s:%d' % (self.current_template.name, line_number)
        if self.include_stack:
            ancestors = ["%s:%d" % (tmpl.name, lineno)
                         for (tmpl, lineno) in self.include_stack]
            line_comment += ' (via %s)' % ', '.join(reversed(ancestors))
        print("    " * indent + line + line_comment, file=self.file)


class _TemplateReader(object):
    def __init__(self, name, text, whitespace):
        self.name = name
        self.text = text
        self.whitespace = whitespace
        self.line = 1
        self.pos = 0

    def find(self, needle, start=0, end=None):
        assert start >= 0, start
        pos = self.pos
        start += pos
        if end is None:
            index = self.text.find(needle, start)
        else:
            end += pos
            assert end >= start
            index = self.text.find(needle, start, end)
        if index != -1:
            index -= pos
        return index

    def consume(self, count=None):
        if count is None:
            count = len(self.text) - self.pos
        newpos = self.pos + count
        self.line += self.text.count("\n", self.pos, newpos)
        s = self.text[self.pos:newpos]
        self.pos = newpos
        return s

    def remaining(self):
        return len(self.text) - self.pos

    def __len__(self):
        return self.remaining()

    def __getitem__(self, key):
        if type(key) is slice:
            size = len(self)
            start, stop, step = key.indices(size)
            if start is None:
                start = self.pos
            else:
                start += self.pos
            if stop is not None:
                stop += self.pos
            return self.text[slice(start, stop, step)]
        elif key < 0:
            return self.text[key]
        else:
            return self.text[self.pos + key]

    def __str__(self):
        return self.text[self.pos:]

    def raise_parse_error(self, msg):
        raise ParseError(msg, self.name, self.line)


def _format_code(code):
    lines = code.splitlines()
    format = "%%%dd  %%s\n" % len(repr(len(lines) + 1))
    return "".join([format % (i + 1, line) for (i, line) in enumerate(lines)])


def _parse(reader, template, in_block=None, in_loop=None):
    body = _ChunkList([])
    while True:
        # Find next template directive
        curly = 0
        while True:
            curly = reader.find("{", curly)
            if curly == -1 or curly + 1 == reader.remaining():
                # EOF
                if in_block:
                    reader.raise_parse_error(
                        "Missing {%% end %%} block for %s" % in_block)
                body.chunks.append(_Text(reader.consume(), reader.line,
                                         reader.whitespace))
                return body
            # If the first curly brace is not the start of a special token,
            # start searching from the character after it
            if reader[curly + 1] not in ("{", "%", "#"):
                curly += 1
                continue
            # When there are more than 2 curlies in a row, use the
            # innermost ones.  This is useful when generating languages
            # like latex where curlies are also meaningful
            if (curly + 2 < reader.remaining() and
                    reader[curly + 1] == '{' and reader[curly + 2] == '{'):
                curly += 1
                continue
            break

        # Append any text before the special token
        if curly > 0:
            cons = reader.consume(curly)
            body.chunks.append(_Text(cons, reader.line,
                                     reader.whitespace))

        start_brace = reader.consume(2)
        line = reader.line

        # Template directives may be escaped as "{{!" or "{%!".
        # In this case output the braces and consume the "!".
        # This is especially useful in conjunction with jquery templates,
        # which also use double braces.
        if reader.remaining() and reader[0] == "!":
            reader.consume(1)
            body.chunks.append(_Text(start_brace, line,
                                     reader.whitespace))
            continue

        # Comment
        if start_brace == "{#":
            end = reader.find("#}")
            if end == -1:
                reader.raise_parse_error("Missing end comment #}")
            contents = reader.consume(end).strip()
            reader.consume(2)
            continue

        # Expression
        if start_brace == "{{":
            end = reader.find("}}")
            if end == -1:
                reader.raise_parse_error("Missing end expression }}")
            contents = reader.consume(end).strip()
            reader.consume(2)
            if not contents:
                reader.raise_parse_error("Empty expression")
            body.chunks.append(_Expression(contents, line))
            continue

        # Block
        assert start_brace == "{%", start_brace
        end = reader.find("%}")
        if end == -1:
            reader.raise_parse_error("Missing end block %}")
        contents = reader.consume(end).strip()
        reader.consume(2)
        if not contents:
            reader.raise_parse_error("Empty block tag ({% %})")

        operator, space, suffix = contents.partition(" ")
        suffix = suffix.strip()

        # Intermediate ("else", "elif", etc) blocks
        intermediate_blocks = {
            "else": set(["if", "for", "while", "try"]),
            "elif": set(["if"]),
            "except": set(["try"]),
            "finally": set(["try"]),
        }
        allowed_parents = intermediate_blocks.get(operator)
        if allowed_parents is not None:
            if not in_block:
                reader.raise_parse_error("%s outside %s block" %
                                         (operator, allowed_parents))
            if in_block not in allowed_parents:
                reader.raise_parse_error(
                    "%s block cannot be attached to %s block" %
                    (operator, in_block))
            body.chunks.append(_IntermediateControlBlock(contents, line))
            continue

        # End tag
        elif operator == "end":
            if not in_block:
                reader.raise_parse_error("Extra {% end %} block")
            return body

        elif operator in ("extends", "include", "set", "import", "from",
                          "comment", "autoescape", "raw", "module"):
            if operator == "comment":
                continue
            if operator == "extends":
                suffix = suffix.strip('"').strip("'")
                if not suffix:
                    reader.raise_parse_error("extends missing file path")
                block = _ExtendsBlock(suffix)
            elif operator in ("import", "from"):
                if not suffix:
                    reader.raise_parse_error("import missing statement")
                block = _Statement(contents, line)
            elif operator == "include":
                suffix = suffix.strip('"').strip("'")
                if not suffix:
                    reader.raise_parse_error("include missing file path")
                block = _IncludeBlock(suffix, reader, line)
            elif operator == "set":
                if not suffix:
                    reader.raise_parse_error("set missing statement")
                block = _Statement(suffix, line)
            elif operator == "autoescape":
                fn = suffix.strip()
                if fn == "None":
                    fn = None
                template.autoescape = fn
                continue
            elif operator == "raw":
                block = _Expression(suffix, line, raw=True)
            elif operator == "module":
                block = _Module(suffix, line)
            body.chunks.append(block)
            continue

        elif operator in ("apply", "block", "try", "if", "for", "while"):
            # parse inner body recursively
            if operator in ("for", "while"):
                block_body = _parse(reader, template, operator, operator)
            elif operator == "apply":
                # apply creates a nested function so syntactically it's not
                # in the loop.
                block_body = _parse(reader, template, operator, None)
            else:
                block_body = _parse(reader, template, operator, in_loop)

            if operator == "apply":
                if not suffix:
                    reader.raise_parse_error("apply missing method name")
                block = _ApplyBlock(suffix, line, block_body)
            elif operator == "block":
                if not suffix:
                    reader.raise_parse_error("block missing name")
                block = _NamedBlock(suffix, block_body, template, line)
            else:
                block = _ControlBlock(contents, line, block_body)
            body.chunks.append(block)
            continue

        elif operator in ("break", "continue"):
            if not in_loop:
                reader.raise_parse_error("%s outside %s block" %
                                         (operator, set(["for", "while"])))
            body.chunks.append(_Statement(contents, line))
            continue

        else:
            reader.raise_parse_error("unknown operator: %r" % operator)

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
user