Sophie

Sophie

distrib > Mageia > 6 > armv7hl > media > core-updates > by-pkgid > 65530c6176058f9b54858c3b4f6385e6 > files > 132

python-django-doc-1.8.19-1.mga6.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml" lang="">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>django.template.base &#8212; Django 1.8.19 documentation</title>
    
    <link rel="stylesheet" href="../../../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
    
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../../../',
        VERSION:     '1.8.19',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../../../_static/jquery.js"></script>
    <script type="text/javascript" src="../../../_static/underscore.js"></script>
    <script type="text/javascript" src="../../../_static/doctools.js"></script>
    <link rel="index" title="Index" href="../../../genindex.html" />
    <link rel="search" title="Search" href="../../../search.html" />
    <link rel="top" title="Django 1.8.19 documentation" href="../../../contents.html" />
    <link rel="up" title="django" href="../../django.html" />



 
<script type="text/javascript" src="../../../templatebuiltins.js"></script>
<script type="text/javascript">
(function($) {
    if (!django_template_builtins) {
       // templatebuiltins.js missing, do nothing.
       return;
    }
    $(document).ready(function() {
        // Hyperlink Django template tags and filters
        var base = "../../../ref/templates/builtins.html";
        if (base == "#") {
            // Special case for builtins.html itself
            base = "";
        }
        // Tags are keywords, class '.k'
        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
             var tagname = $(elem).text();
             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
                 var fragment = tagname.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
             }
        });
        // Filters are functions, class '.nf'
        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
             var filtername = $(elem).text();
             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
                 var fragment = filtername.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
             }
        });
    });
})(jQuery);
</script>


  </head>
  <body role="document">

    <div class="document">
  <div id="custom-doc" class="yui-t6">
    <div id="hd">
      <h1><a href="../../../index.html">Django 1.8.19 documentation</a></h1>
      <div id="global-nav">
        <a title="Home page" href="../../../index.html">Home</a>  |
        <a title="Table of contents" href="../../../contents.html">Table of contents</a>  |
        <a title="Global index" href="../../../genindex.html">Index</a>  |
        <a title="Module index" href="../../../py-modindex.html">Modules</a>
      </div>
      <div class="nav">
    <a href="../../index.html" title="Module code" accesskey="U">up</a></div>
    </div>

    <div id="bd">
      <div id="yui-main">
        <div class="yui-b">
          <div class="yui-g" id="_modules-django-template-base">
            
  <h1>Source code for django.template.base</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">This is the Django template system.</span>

<span class="sd">How it works:</span>

<span class="sd">The Lexer.tokenize() function converts a template string (i.e., a string containing</span>
<span class="sd">markup with custom template tags) to tokens, which can be either plain text</span>
<span class="sd">(TOKEN_TEXT), variables (TOKEN_VAR) or block statements (TOKEN_BLOCK).</span>

<span class="sd">The Parser() class takes a list of tokens in its constructor, and its parse()</span>
<span class="sd">method returns a compiled template -- which is, under the hood, a list of</span>
<span class="sd">Node objects.</span>

<span class="sd">Each Node is responsible for creating some sort of output -- e.g. simple text</span>
<span class="sd">(TextNode), variable values in a given context (VariableNode), results of basic</span>
<span class="sd">logic (IfNode), results of looping (ForNode), or anything else. The core Node</span>
<span class="sd">types are TextNode, VariableNode, IfNode and ForNode, but plugin modules can</span>
<span class="sd">define their own custom node types.</span>

<span class="sd">Each Node has a render() method, which takes a Context and returns a string of</span>
<span class="sd">the rendered node. For example, the render() method of a Variable Node returns</span>
<span class="sd">the variable&#39;s value as a string. The render() method of a ForNode returns the</span>
<span class="sd">rendered output of whatever was inside the loop, recursively.</span>

<span class="sd">The Template class is a convenient wrapper that takes care of template</span>
<span class="sd">compilation and rendering.</span>

<span class="sd">Usage:</span>

<span class="sd">The only thing you should ever use directly in this file is the Template class.</span>
<span class="sd">Create a compiled template object with a template_string, then call render()</span>
<span class="sd">with a context. In the compilation stage, the TemplateSyntaxError exception</span>
<span class="sd">will be raised if the template doesn&#39;t have proper syntax.</span>

<span class="sd">Sample code:</span>

<span class="sd">&gt;&gt;&gt; from django import template</span>
<span class="sd">&gt;&gt;&gt; s = u&#39;&lt;html&gt;{% if test %}&lt;h1&gt;{{ varvalue }}&lt;/h1&gt;{% endif %}&lt;/html&gt;&#39;</span>
<span class="sd">&gt;&gt;&gt; t = template.Template(s)</span>

<span class="sd">(t is now a compiled template, and its render() method can be called multiple</span>
<span class="sd">times with multiple contexts)</span>

<span class="sd">&gt;&gt;&gt; c = template.Context({&#39;test&#39;:True, &#39;varvalue&#39;: &#39;Hello&#39;})</span>
<span class="sd">&gt;&gt;&gt; t.render(c)</span>
<span class="sd">u&#39;&lt;html&gt;&lt;h1&gt;Hello&lt;/h1&gt;&lt;/html&gt;&#39;</span>
<span class="sd">&gt;&gt;&gt; c = template.Context({&#39;test&#39;:False, &#39;varvalue&#39;: &#39;Hello&#39;})</span>
<span class="sd">&gt;&gt;&gt; t.render(c)</span>
<span class="sd">u&#39;&lt;html&gt;&lt;/html&gt;&#39;</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">unicode_literals</span>

<span class="kn">import</span> <span class="nn">inspect</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">warnings</span>
<span class="kn">from</span> <span class="nn">functools</span> <span class="k">import</span> <span class="n">partial</span>
<span class="kn">from</span> <span class="nn">importlib</span> <span class="k">import</span> <span class="n">import_module</span>

<span class="kn">from</span> <span class="nn">django.apps</span> <span class="k">import</span> <span class="n">apps</span>
<span class="kn">from</span> <span class="nn">django.template.context</span> <span class="k">import</span> <span class="p">(</span>  <span class="c1"># NOQA: imported for backwards compatibility</span>
    <span class="n">BaseContext</span><span class="p">,</span> <span class="n">Context</span><span class="p">,</span> <span class="n">ContextPopException</span><span class="p">,</span> <span class="n">RequestContext</span><span class="p">,</span>
<span class="p">)</span>
<span class="kn">from</span> <span class="nn">django.utils</span> <span class="k">import</span> <span class="n">lru_cache</span><span class="p">,</span> <span class="n">six</span>
<span class="kn">from</span> <span class="nn">django.utils.deprecation</span> <span class="k">import</span> <span class="n">RemovedInDjango110Warning</span>
<span class="kn">from</span> <span class="nn">django.utils.encoding</span> <span class="k">import</span> <span class="p">(</span>
    <span class="n">force_str</span><span class="p">,</span> <span class="n">force_text</span><span class="p">,</span> <span class="n">python_2_unicode_compatible</span><span class="p">,</span>
<span class="p">)</span>
<span class="kn">from</span> <span class="nn">django.utils.formats</span> <span class="k">import</span> <span class="n">localize</span>
<span class="kn">from</span> <span class="nn">django.utils.html</span> <span class="k">import</span> <span class="n">conditional_escape</span>
<span class="kn">from</span> <span class="nn">django.utils.inspect</span> <span class="k">import</span> <span class="n">getargspec</span>
<span class="kn">from</span> <span class="nn">django.utils.itercompat</span> <span class="k">import</span> <span class="n">is_iterable</span>
<span class="kn">from</span> <span class="nn">django.utils.module_loading</span> <span class="k">import</span> <span class="n">module_has_submodule</span>
<span class="kn">from</span> <span class="nn">django.utils.safestring</span> <span class="k">import</span> <span class="p">(</span>
    <span class="n">EscapeData</span><span class="p">,</span> <span class="n">SafeData</span><span class="p">,</span> <span class="n">mark_for_escaping</span><span class="p">,</span> <span class="n">mark_safe</span><span class="p">,</span>
<span class="p">)</span>
<span class="kn">from</span> <span class="nn">django.utils.text</span> <span class="k">import</span> <span class="p">(</span>
    <span class="n">get_text_list</span><span class="p">,</span> <span class="n">smart_split</span><span class="p">,</span> <span class="n">unescape_string_literal</span><span class="p">,</span>
<span class="p">)</span>
<span class="kn">from</span> <span class="nn">django.utils.timezone</span> <span class="k">import</span> <span class="n">template_localtime</span>
<span class="kn">from</span> <span class="nn">django.utils.translation</span> <span class="k">import</span> <span class="n">pgettext_lazy</span><span class="p">,</span> <span class="n">ugettext_lazy</span>

<span class="n">TOKEN_TEXT</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">TOKEN_VAR</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">TOKEN_BLOCK</span> <span class="o">=</span> <span class="mi">2</span>
<span class="n">TOKEN_COMMENT</span> <span class="o">=</span> <span class="mi">3</span>
<span class="n">TOKEN_MAPPING</span> <span class="o">=</span> <span class="p">{</span>
    <span class="n">TOKEN_TEXT</span><span class="p">:</span> <span class="s1">&#39;Text&#39;</span><span class="p">,</span>
    <span class="n">TOKEN_VAR</span><span class="p">:</span> <span class="s1">&#39;Var&#39;</span><span class="p">,</span>
    <span class="n">TOKEN_BLOCK</span><span class="p">:</span> <span class="s1">&#39;Block&#39;</span><span class="p">,</span>
    <span class="n">TOKEN_COMMENT</span><span class="p">:</span> <span class="s1">&#39;Comment&#39;</span><span class="p">,</span>
<span class="p">}</span>

<span class="c1"># template syntax constants</span>
<span class="n">FILTER_SEPARATOR</span> <span class="o">=</span> <span class="s1">&#39;|&#39;</span>
<span class="n">FILTER_ARGUMENT_SEPARATOR</span> <span class="o">=</span> <span class="s1">&#39;:&#39;</span>
<span class="n">VARIABLE_ATTRIBUTE_SEPARATOR</span> <span class="o">=</span> <span class="s1">&#39;.&#39;</span>
<span class="n">BLOCK_TAG_START</span> <span class="o">=</span> <span class="s1">&#39;{%&#39;</span>
<span class="n">BLOCK_TAG_END</span> <span class="o">=</span> <span class="s1">&#39;%}&#39;</span>
<span class="n">VARIABLE_TAG_START</span> <span class="o">=</span> <span class="s1">&#39;{{&#39;</span>
<span class="n">VARIABLE_TAG_END</span> <span class="o">=</span> <span class="s1">&#39;}}&#39;</span>
<span class="n">COMMENT_TAG_START</span> <span class="o">=</span> <span class="s1">&#39;{#&#39;</span>
<span class="n">COMMENT_TAG_END</span> <span class="o">=</span> <span class="s1">&#39;#}&#39;</span>
<span class="n">TRANSLATOR_COMMENT_MARK</span> <span class="o">=</span> <span class="s1">&#39;Translators&#39;</span>
<span class="n">SINGLE_BRACE_START</span> <span class="o">=</span> <span class="s1">&#39;{&#39;</span>
<span class="n">SINGLE_BRACE_END</span> <span class="o">=</span> <span class="s1">&#39;}&#39;</span>

<span class="n">ALLOWED_VARIABLE_CHARS</span> <span class="o">=</span> <span class="p">(</span><span class="s1">&#39;abcdefghijklmnopqrstuvwxyz&#39;</span>
                         <span class="s1">&#39;ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.&#39;</span><span class="p">)</span>

<span class="c1"># what to report as the origin for templates that come from non-loader sources</span>
<span class="c1"># (e.g. strings)</span>
<span class="n">UNKNOWN_SOURCE</span> <span class="o">=</span> <span class="s1">&#39;&lt;unknown source&gt;&#39;</span>

<span class="c1"># match a variable or block tag and capture the entire tag, including start/end</span>
<span class="c1"># delimiters</span>
<span class="n">tag_re</span> <span class="o">=</span> <span class="p">(</span><span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s1">&#39;(</span><span class="si">%s</span><span class="s1">.*?</span><span class="si">%s</span><span class="s1">|</span><span class="si">%s</span><span class="s1">.*?</span><span class="si">%s</span><span class="s1">|</span><span class="si">%s</span><span class="s1">.*?</span><span class="si">%s</span><span class="s1">)&#39;</span> <span class="o">%</span>
          <span class="p">(</span><span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">BLOCK_TAG_START</span><span class="p">),</span> <span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">BLOCK_TAG_END</span><span class="p">),</span>
           <span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">VARIABLE_TAG_START</span><span class="p">),</span> <span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">VARIABLE_TAG_END</span><span class="p">),</span>
           <span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">COMMENT_TAG_START</span><span class="p">),</span> <span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">COMMENT_TAG_END</span><span class="p">))))</span>

<span class="c1"># global dictionary of libraries that have been loaded using get_library</span>
<span class="n">libraries</span> <span class="o">=</span> <span class="p">{}</span>
<span class="c1"># global list of libraries to load by default for a new parser</span>
<span class="n">builtins</span> <span class="o">=</span> <span class="p">[]</span>


<div class="viewcode-block" id="TemplateSyntaxError"><a class="viewcode-back" href="../../../topics/templates.html#django.template.TemplateSyntaxError">[docs]</a><span class="k">class</span> <span class="nc">TemplateSyntaxError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
    <span class="k">pass</span></div>


<div class="viewcode-block" id="TemplateDoesNotExist"><a class="viewcode-back" href="../../../topics/templates.html#django.template.TemplateDoesNotExist">[docs]</a><span class="k">class</span> <span class="nc">TemplateDoesNotExist</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
    <span class="k">pass</span></div>


<span class="k">class</span> <span class="nc">TemplateEncodingError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
    <span class="k">pass</span>


<span class="nd">@python_2_unicode_compatible</span>
<span class="k">class</span> <span class="nc">VariableDoesNotExist</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="p">()):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">params</span> <span class="o">=</span> <span class="n">params</span>

    <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span> <span class="o">%</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">force_text</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">errors</span><span class="o">=</span><span class="s1">&#39;replace&#39;</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">params</span><span class="p">)</span>


<span class="k">class</span> <span class="nc">InvalidTemplateLibrary</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
    <span class="k">pass</span>


<span class="k">class</span> <span class="nc">Origin</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>

    <span class="k">def</span> <span class="nf">reload</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span><span class="s1">&#39;subclasses of Origin must provide a reload() method&#39;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>


<div class="viewcode-block" id="StringOrigin"><a class="viewcode-back" href="../../../ref/templates/api.html#django.template.StringOrigin">[docs]</a><span class="k">class</span> <span class="nc">StringOrigin</span><span class="p">(</span><span class="n">Origin</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">source</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">StringOrigin</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">UNKNOWN_SOURCE</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">source</span> <span class="o">=</span> <span class="n">source</span>

    <span class="k">def</span> <span class="nf">reload</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">source</span></div>


<div class="viewcode-block" id="Template"><a class="viewcode-back" href="../../../ref/templates/api.html#django.template.Template">[docs]</a><span class="k">class</span> <span class="nc">Template</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">template_string</span><span class="p">,</span> <span class="n">origin</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">engine</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">template_string</span> <span class="o">=</span> <span class="n">force_text</span><span class="p">(</span><span class="n">template_string</span><span class="p">)</span>
        <span class="k">except</span> <span class="ne">UnicodeDecodeError</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">TemplateEncodingError</span><span class="p">(</span><span class="s2">&quot;Templates can only be constructed &quot;</span>
                                        <span class="s2">&quot;from unicode or UTF-8 strings.&quot;</span><span class="p">)</span>
        <span class="c1"># If Template is instantiated directly rather than from an Engine and</span>
        <span class="c1"># exactly one Django template engine is configured, use that engine.</span>
        <span class="c1"># This is required to preserve backwards-compatibility for direct use</span>
        <span class="c1"># e.g. Template(&#39;...&#39;).render(Context({...}))</span>
        <span class="k">if</span> <span class="n">engine</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="kn">from</span> <span class="nn">.engine</span> <span class="k">import</span> <span class="n">Engine</span>
            <span class="n">engine</span> <span class="o">=</span> <span class="n">Engine</span><span class="o">.</span><span class="n">get_default</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">engine</span><span class="o">.</span><span class="n">debug</span> <span class="ow">and</span> <span class="n">origin</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">origin</span> <span class="o">=</span> <span class="n">StringOrigin</span><span class="p">(</span><span class="n">template_string</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">nodelist</span> <span class="o">=</span> <span class="n">engine</span><span class="o">.</span><span class="n">compile_string</span><span class="p">(</span><span class="n">template_string</span><span class="p">,</span> <span class="n">origin</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">origin</span> <span class="o">=</span> <span class="n">origin</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">engine</span> <span class="o">=</span> <span class="n">engine</span>

    <span class="k">def</span> <span class="nf">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">nodelist</span><span class="p">:</span>
            <span class="k">for</span> <span class="n">subnode</span> <span class="ow">in</span> <span class="n">node</span><span class="p">:</span>
                <span class="k">yield</span> <span class="n">subnode</span>

    <span class="k">def</span> <span class="nf">_render</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">nodelist</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>

<div class="viewcode-block" id="Template.render"><a class="viewcode-back" href="../../../ref/templates/api.html#django.template.Template.render">[docs]</a>    <span class="k">def</span> <span class="nf">render</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
        <span class="s2">&quot;Display stage -- can be called many times&quot;</span>
        <span class="n">context</span><span class="o">.</span><span class="n">render_context</span><span class="o">.</span><span class="n">push</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">context</span><span class="o">.</span><span class="n">template</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                <span class="k">with</span> <span class="n">context</span><span class="o">.</span><span class="n">bind_template</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
                    <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_render</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_render</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
        <span class="k">finally</span><span class="p">:</span>
            <span class="n">context</span><span class="o">.</span><span class="n">render_context</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span></div></div>


<span class="k">class</span> <span class="nc">Token</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token_type</span><span class="p">,</span> <span class="n">contents</span><span class="p">):</span>
        <span class="c1"># token_type must be TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK or</span>
        <span class="c1"># TOKEN_COMMENT.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">token_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">contents</span> <span class="o">=</span> <span class="n">token_type</span><span class="p">,</span> <span class="n">contents</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lineno</span> <span class="o">=</span> <span class="kc">None</span>

    <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">token_name</span> <span class="o">=</span> <span class="n">TOKEN_MAPPING</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">token_type</span><span class="p">]</span>
        <span class="k">return</span> <span class="p">(</span><span class="s1">&#39;&lt;</span><span class="si">%s</span><span class="s1"> token: &quot;</span><span class="si">%s</span><span class="s1">...&quot;&gt;&#39;</span> <span class="o">%</span>
                <span class="p">(</span><span class="n">token_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">contents</span><span class="p">[:</span><span class="mi">20</span><span class="p">]</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)))</span>

    <span class="k">def</span> <span class="nf">split_contents</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">split</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="n">bits</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">smart_split</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">contents</span><span class="p">))</span>
        <span class="k">for</span> <span class="n">bit</span> <span class="ow">in</span> <span class="n">bits</span><span class="p">:</span>
            <span class="c1"># Handle translation-marked template pieces</span>
            <span class="k">if</span> <span class="n">bit</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;_(&quot;&#39;</span><span class="p">)</span> <span class="ow">or</span> <span class="n">bit</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;_(&#39;&quot;</span><span class="p">):</span>
                <span class="n">sentinal</span> <span class="o">=</span> <span class="n">bit</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">+</span> <span class="s1">&#39;)&#39;</span>
                <span class="n">trans_bit</span> <span class="o">=</span> <span class="p">[</span><span class="n">bit</span><span class="p">]</span>
                <span class="k">while</span> <span class="ow">not</span> <span class="n">bit</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">sentinal</span><span class="p">):</span>
                    <span class="n">bit</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">bits</span><span class="p">)</span>
                    <span class="n">trans_bit</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">bit</span><span class="p">)</span>
                <span class="n">bit</span> <span class="o">=</span> <span class="s1">&#39; &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">trans_bit</span><span class="p">)</span>
            <span class="n">split</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">bit</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">split</span>


<span class="k">class</span> <span class="nc">Lexer</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">template_string</span><span class="p">,</span> <span class="n">origin</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">template_string</span> <span class="o">=</span> <span class="n">template_string</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">origin</span> <span class="o">=</span> <span class="n">origin</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lineno</span> <span class="o">=</span> <span class="mi">1</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">verbatim</span> <span class="o">=</span> <span class="kc">False</span>

    <span class="k">def</span> <span class="nf">tokenize</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a list of tokens from a given template_string.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">in_tag</span> <span class="o">=</span> <span class="kc">False</span>
        <span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">bit</span> <span class="ow">in</span> <span class="n">tag_re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">template_string</span><span class="p">):</span>
            <span class="k">if</span> <span class="n">bit</span><span class="p">:</span>
                <span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">create_token</span><span class="p">(</span><span class="n">bit</span><span class="p">,</span> <span class="n">in_tag</span><span class="p">))</span>
            <span class="n">in_tag</span> <span class="o">=</span> <span class="ow">not</span> <span class="n">in_tag</span>
        <span class="k">return</span> <span class="n">result</span>

    <span class="k">def</span> <span class="nf">create_token</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token_string</span><span class="p">,</span> <span class="n">in_tag</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Convert the given token string into a new Token object and return it.</span>
<span class="sd">        If in_tag is True, we are processing something that matched a tag,</span>
<span class="sd">        otherwise it should be treated as a literal string.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">in_tag</span> <span class="ow">and</span> <span class="n">token_string</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">BLOCK_TAG_START</span><span class="p">):</span>
            <span class="c1"># The [2:-2] ranges below strip off *_TAG_START and *_TAG_END.</span>
            <span class="c1"># We could do len(BLOCK_TAG_START) to be more &quot;correct&quot;, but we&#39;ve</span>
            <span class="c1"># hard-coded the 2s here for performance. And it&#39;s not like</span>
            <span class="c1"># the TAG_START values are going to change anytime, anyway.</span>
            <span class="n">block_content</span> <span class="o">=</span> <span class="n">token_string</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbatim</span> <span class="ow">and</span> <span class="n">block_content</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbatim</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">verbatim</span> <span class="o">=</span> <span class="kc">False</span>
        <span class="k">if</span> <span class="n">in_tag</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbatim</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">token_string</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">VARIABLE_TAG_START</span><span class="p">):</span>
                <span class="n">token</span> <span class="o">=</span> <span class="n">Token</span><span class="p">(</span><span class="n">TOKEN_VAR</span><span class="p">,</span> <span class="n">token_string</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
            <span class="k">elif</span> <span class="n">token_string</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">BLOCK_TAG_START</span><span class="p">):</span>
                <span class="k">if</span> <span class="n">block_content</span><span class="p">[:</span><span class="mi">9</span><span class="p">]</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;verbatim&#39;</span><span class="p">,</span> <span class="s1">&#39;verbatim &#39;</span><span class="p">):</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">verbatim</span> <span class="o">=</span> <span class="s1">&#39;end</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">block_content</span>
                <span class="n">token</span> <span class="o">=</span> <span class="n">Token</span><span class="p">(</span><span class="n">TOKEN_BLOCK</span><span class="p">,</span> <span class="n">block_content</span><span class="p">)</span>
            <span class="k">elif</span> <span class="n">token_string</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">COMMENT_TAG_START</span><span class="p">):</span>
                <span class="n">content</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
                <span class="k">if</span> <span class="n">token_string</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">TRANSLATOR_COMMENT_MARK</span><span class="p">):</span>
                    <span class="n">content</span> <span class="o">=</span> <span class="n">token_string</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
                <span class="n">token</span> <span class="o">=</span> <span class="n">Token</span><span class="p">(</span><span class="n">TOKEN_COMMENT</span><span class="p">,</span> <span class="n">content</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">token</span> <span class="o">=</span> <span class="n">Token</span><span class="p">(</span><span class="n">TOKEN_TEXT</span><span class="p">,</span> <span class="n">token_string</span><span class="p">)</span>
        <span class="n">token</span><span class="o">.</span><span class="n">lineno</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lineno</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lineno</span> <span class="o">+=</span> <span class="n">token_string</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">token</span>


<span class="k">class</span> <span class="nc">Parser</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tokens</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">tokens</span> <span class="o">=</span> <span class="n">tokens</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">tags</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">filters</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="k">for</span> <span class="n">lib</span> <span class="ow">in</span> <span class="n">builtins</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">add_library</span><span class="p">(</span><span class="n">lib</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parse_until</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">parse_until</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">parse_until</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="n">nodelist</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">create_nodelist</span><span class="p">()</span>
        <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">tokens</span><span class="p">:</span>
            <span class="n">token</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">next_token</span><span class="p">()</span>
            <span class="c1"># Use the raw values here for TOKEN_* for a tiny performance boost.</span>
            <span class="k">if</span> <span class="n">token</span><span class="o">.</span><span class="n">token_type</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>  <span class="c1"># TOKEN_TEXT</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">extend_nodelist</span><span class="p">(</span><span class="n">nodelist</span><span class="p">,</span> <span class="n">TextNode</span><span class="p">(</span><span class="n">token</span><span class="o">.</span><span class="n">contents</span><span class="p">),</span> <span class="n">token</span><span class="p">)</span>
            <span class="k">elif</span> <span class="n">token</span><span class="o">.</span><span class="n">token_type</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>  <span class="c1"># TOKEN_VAR</span>
                <span class="k">if</span> <span class="ow">not</span> <span class="n">token</span><span class="o">.</span><span class="n">contents</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">empty_variable</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="n">filter_expression</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">compile_filter</span><span class="p">(</span><span class="n">token</span><span class="o">.</span><span class="n">contents</span><span class="p">)</span>
                <span class="k">except</span> <span class="n">TemplateSyntaxError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
                    <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">compile_filter_error</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
                        <span class="k">raise</span>
                <span class="n">var_node</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">create_variable_node</span><span class="p">(</span><span class="n">filter_expression</span><span class="p">)</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">extend_nodelist</span><span class="p">(</span><span class="n">nodelist</span><span class="p">,</span> <span class="n">var_node</span><span class="p">,</span> <span class="n">token</span><span class="p">)</span>
            <span class="k">elif</span> <span class="n">token</span><span class="o">.</span><span class="n">token_type</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>  <span class="c1"># TOKEN_BLOCK</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="n">command</span> <span class="o">=</span> <span class="n">token</span><span class="o">.</span><span class="n">contents</span><span class="o">.</span><span class="n">split</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span>
                <span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">empty_block_tag</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">command</span> <span class="ow">in</span> <span class="n">parse_until</span><span class="p">:</span>
                    <span class="c1"># put token back on token list so calling</span>
                    <span class="c1"># code knows why it terminated</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">prepend_token</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
                    <span class="k">return</span> <span class="n">nodelist</span>
                <span class="c1"># execute callback function for this tag and append</span>
                <span class="c1"># resulting node</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">enter_command</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="n">token</span><span class="p">)</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="n">compile_func</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tags</span><span class="p">[</span><span class="n">command</span><span class="p">]</span>
                <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">invalid_block_tag</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">command</span><span class="p">,</span> <span class="n">parse_until</span><span class="p">)</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="n">compiled_result</span> <span class="o">=</span> <span class="n">compile_func</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token</span><span class="p">)</span>
                <span class="k">except</span> <span class="n">TemplateSyntaxError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
                    <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">compile_function_error</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
                        <span class="k">raise</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">extend_nodelist</span><span class="p">(</span><span class="n">nodelist</span><span class="p">,</span> <span class="n">compiled_result</span><span class="p">,</span> <span class="n">token</span><span class="p">)</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">exit_command</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">parse_until</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">unclosed_block_tag</span><span class="p">(</span><span class="n">parse_until</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">nodelist</span>

    <span class="k">def</span> <span class="nf">skip_past</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">endtag</span><span class="p">):</span>
        <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">tokens</span><span class="p">:</span>
            <span class="n">token</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">next_token</span><span class="p">()</span>
            <span class="k">if</span> <span class="n">token</span><span class="o">.</span><span class="n">token_type</span> <span class="o">==</span> <span class="n">TOKEN_BLOCK</span> <span class="ow">and</span> <span class="n">token</span><span class="o">.</span><span class="n">contents</span> <span class="o">==</span> <span class="n">endtag</span><span class="p">:</span>
                <span class="k">return</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">unclosed_block_tag</span><span class="p">([</span><span class="n">endtag</span><span class="p">])</span>

    <span class="k">def</span> <span class="nf">create_variable_node</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filter_expression</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">VariableNode</span><span class="p">(</span><span class="n">filter_expression</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">create_nodelist</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">NodeList</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">extend_nodelist</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nodelist</span><span class="p">,</span> <span class="n">node</span><span class="p">,</span> <span class="n">token</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">node</span><span class="o">.</span><span class="n">must_be_first</span> <span class="ow">and</span> <span class="n">nodelist</span><span class="p">:</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">nodelist</span><span class="o">.</span><span class="n">contains_nontext</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">AttributeError</span>
            <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
                <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%r</span><span class="s2"> must be the first tag &quot;</span>
                                          <span class="s2">&quot;in the template.&quot;</span> <span class="o">%</span> <span class="n">node</span><span class="p">)</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">nodelist</span><span class="p">,</span> <span class="n">NodeList</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">TextNode</span><span class="p">):</span>
            <span class="n">nodelist</span><span class="o">.</span><span class="n">contains_nontext</span> <span class="o">=</span> <span class="kc">True</span>
        <span class="n">nodelist</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">enter_command</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">command</span><span class="p">,</span> <span class="n">token</span><span class="p">):</span>
        <span class="k">pass</span>

    <span class="k">def</span> <span class="nf">exit_command</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">pass</span>

    <span class="k">def</span> <span class="nf">error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">empty_variable</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token</span><span class="p">):</span>
        <span class="k">raise</span> <span class="bp">self</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="s2">&quot;Empty variable tag&quot;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">empty_block_tag</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token</span><span class="p">):</span>
        <span class="k">raise</span> <span class="bp">self</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="s2">&quot;Empty block tag&quot;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">invalid_block_tag</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span> <span class="n">command</span><span class="p">,</span> <span class="n">parse_until</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">parse_until</span><span class="p">:</span>
            <span class="k">raise</span> <span class="bp">self</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="s2">&quot;Invalid block tag: &#39;</span><span class="si">%s</span><span class="s2">&#39;, expected </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span>
                <span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="n">get_text_list</span><span class="p">([</span><span class="s2">&quot;&#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span> <span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">parse_until</span><span class="p">])))</span>
        <span class="k">raise</span> <span class="bp">self</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="s2">&quot;Invalid block tag: &#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span> <span class="n">command</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">unclosed_block_tag</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parse_until</span><span class="p">):</span>
        <span class="k">raise</span> <span class="bp">self</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="s2">&quot;Unclosed tags: </span><span class="si">%s</span><span class="s2"> &quot;</span> <span class="o">%</span> <span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">parse_until</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">compile_filter_error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
        <span class="k">pass</span>

    <span class="k">def</span> <span class="nf">compile_function_error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
        <span class="k">pass</span>

    <span class="k">def</span> <span class="nf">next_token</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">tokens</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">prepend_token</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">tokens</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">token</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">delete_first_token</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">tokens</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>

    <span class="k">def</span> <span class="nf">add_library</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lib</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">tags</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">lib</span><span class="o">.</span><span class="n">tags</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">filters</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">lib</span><span class="o">.</span><span class="n">filters</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">compile_filter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Convenient wrapper for FilterExpression</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">FilterExpression</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">find_filter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filter_name</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">filter_name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">filters</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">filters</span><span class="p">[</span><span class="n">filter_name</span><span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="s2">&quot;Invalid filter: &#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span> <span class="n">filter_name</span><span class="p">)</span>


<span class="k">class</span> <span class="nc">TokenParser</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Subclass this and implement the top() method to parse a template line.</span>
<span class="sd">    When instantiating the parser, pass in the line from the Django template</span>
<span class="sd">    parser.</span>

<span class="sd">    The parser&#39;s &quot;tagname&quot; instance-variable stores the name of the tag that</span>
<span class="sd">    the filter was called with.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">subject</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">subject</span> <span class="o">=</span> <span class="n">subject</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">pointer</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">backout</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">tagname</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tag</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">top</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Overload this method to do the actual parsing and return the result.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span><span class="s1">&#39;subclasses of Tokenparser must provide a top() method&#39;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">more</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns True if there is more stuff in the tag.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">pointer</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">subject</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">back</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Undoes the last microparser. Use this for lookahead and backtracking.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">backout</span><span class="p">):</span>
            <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="s2">&quot;back called without some previous &quot;</span>
                                      <span class="s2">&quot;parsing&quot;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">pointer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">backout</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">tag</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        A microparser that just returns the next tag from the line.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">subject</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">subject</span>
        <span class="n">i</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pointer</span>
        <span class="k">if</span> <span class="n">i</span> <span class="o">&gt;=</span> <span class="nb">len</span><span class="p">(</span><span class="n">subject</span><span class="p">):</span>
            <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="s2">&quot;expected another tag, found &quot;</span>
                                      <span class="s2">&quot;end of string: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">subject</span><span class="p">)</span>
        <span class="n">p</span> <span class="o">=</span> <span class="n">i</span>
        <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="n">subject</span><span class="p">)</span> <span class="ow">and</span> <span class="n">subject</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\t</span><span class="s1">&#39;</span><span class="p">):</span>
            <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
        <span class="n">s</span> <span class="o">=</span> <span class="n">subject</span><span class="p">[</span><span class="n">p</span><span class="p">:</span><span class="n">i</span><span class="p">]</span>
        <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="n">subject</span><span class="p">)</span> <span class="ow">and</span> <span class="n">subject</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\t</span><span class="s1">&#39;</span><span class="p">):</span>
            <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">backout</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pointer</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">pointer</span> <span class="o">=</span> <span class="n">i</span>
        <span class="k">return</span> <span class="n">s</span>

    <span class="k">def</span> <span class="nf">value</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        A microparser that parses for a value: some string constant or</span>
<span class="sd">        variable name.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">subject</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">subject</span>
        <span class="n">i</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pointer</span>

        <span class="k">def</span> <span class="nf">next_space_index</span><span class="p">(</span><span class="n">subject</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
            <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">            Increment pointer until a real space (i.e. a space not within</span>
<span class="sd">            quotes) is encountered</span>
<span class="sd">            &quot;&quot;&quot;</span>
            <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="n">subject</span><span class="p">)</span> <span class="ow">and</span> <span class="n">subject</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\t</span><span class="s1">&#39;</span><span class="p">):</span>
                <span class="k">if</span> <span class="n">subject</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;&quot;&#39;</span><span class="p">,</span> <span class="s2">&quot;&#39;&quot;</span><span class="p">):</span>
                    <span class="n">c</span> <span class="o">=</span> <span class="n">subject</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
                    <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
                    <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="n">subject</span><span class="p">)</span> <span class="ow">and</span> <span class="n">subject</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">!=</span> <span class="n">c</span><span class="p">:</span>
                        <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
                    <span class="k">if</span> <span class="n">i</span> <span class="o">&gt;=</span> <span class="nb">len</span><span class="p">(</span><span class="n">subject</span><span class="p">):</span>
                        <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="s2">&quot;Searching for value. &quot;</span>
                            <span class="s2">&quot;Unexpected end of string in column </span><span class="si">%d</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span>
                            <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">subject</span><span class="p">))</span>
                <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="k">return</span> <span class="n">i</span>

        <span class="k">if</span> <span class="n">i</span> <span class="o">&gt;=</span> <span class="nb">len</span><span class="p">(</span><span class="n">subject</span><span class="p">):</span>
            <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="s2">&quot;Searching for value. Expected another &quot;</span>
                                      <span class="s2">&quot;value but found end of string: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span>
                                      <span class="n">subject</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">subject</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;&quot;&#39;</span><span class="p">,</span> <span class="s2">&quot;&#39;&quot;</span><span class="p">):</span>
            <span class="n">p</span> <span class="o">=</span> <span class="n">i</span>
            <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="n">subject</span><span class="p">)</span> <span class="ow">and</span> <span class="n">subject</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">!=</span> <span class="n">subject</span><span class="p">[</span><span class="n">p</span><span class="p">]:</span>
                <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="k">if</span> <span class="n">i</span> <span class="o">&gt;=</span> <span class="nb">len</span><span class="p">(</span><span class="n">subject</span><span class="p">):</span>
                <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="s2">&quot;Searching for value. Unexpected &quot;</span>
                                          <span class="s2">&quot;end of string in column </span><span class="si">%d</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span>
                                          <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">subject</span><span class="p">))</span>
            <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>

            <span class="c1"># Continue parsing until next &quot;real&quot; space,</span>
            <span class="c1"># so that filters are also included</span>
            <span class="n">i</span> <span class="o">=</span> <span class="n">next_space_index</span><span class="p">(</span><span class="n">subject</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>

            <span class="n">res</span> <span class="o">=</span> <span class="n">subject</span><span class="p">[</span><span class="n">p</span><span class="p">:</span><span class="n">i</span><span class="p">]</span>
            <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="n">subject</span><span class="p">)</span> <span class="ow">and</span> <span class="n">subject</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\t</span><span class="s1">&#39;</span><span class="p">):</span>
                <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">backout</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pointer</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">pointer</span> <span class="o">=</span> <span class="n">i</span>
            <span class="k">return</span> <span class="n">res</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">p</span> <span class="o">=</span> <span class="n">i</span>
            <span class="n">i</span> <span class="o">=</span> <span class="n">next_space_index</span><span class="p">(</span><span class="n">subject</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
            <span class="n">s</span> <span class="o">=</span> <span class="n">subject</span><span class="p">[</span><span class="n">p</span><span class="p">:</span><span class="n">i</span><span class="p">]</span>
            <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="n">subject</span><span class="p">)</span> <span class="ow">and</span> <span class="n">subject</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\t</span><span class="s1">&#39;</span><span class="p">):</span>
                <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">backout</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pointer</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">pointer</span> <span class="o">=</span> <span class="n">i</span>
            <span class="k">return</span> <span class="n">s</span>

<span class="c1"># This only matches constant *strings* (things in quotes or marked for</span>
<span class="c1"># translation). Numbers are treated as variables for implementation reasons</span>
<span class="c1"># (so that they retain their type when passed to filters).</span>
<span class="n">constant_string</span> <span class="o">=</span> <span class="s2">r&quot;&quot;&quot;</span>
<span class="s2">(?:</span><span class="si">%(i18n_open)s%(strdq)s%(i18n_close)s</span><span class="s2">|</span>
<span class="si">%(i18n_open)s%(strsq)s%(i18n_close)s</span><span class="s2">|</span>
<span class="si">%(strdq)s</span><span class="s2">|</span>
<span class="si">%(strsq)s</span><span class="s2">)</span>
<span class="s2">&quot;&quot;&quot;</span> <span class="o">%</span> <span class="p">{</span>
    <span class="s1">&#39;strdq&#39;</span><span class="p">:</span> <span class="s1">r&#39;&quot;[^&quot;</span><span class="se">\\</span><span class="s1">]*(?:</span><span class="se">\\</span><span class="s1">.[^&quot;</span><span class="se">\\</span><span class="s1">]*)*&quot;&#39;</span><span class="p">,</span>  <span class="c1"># double-quoted string</span>
    <span class="s1">&#39;strsq&#39;</span><span class="p">:</span> <span class="s2">r&quot;&#39;[^&#39;</span><span class="se">\\</span><span class="s2">]*(?:</span><span class="se">\\</span><span class="s2">.[^&#39;</span><span class="se">\\</span><span class="s2">]*)*&#39;&quot;</span><span class="p">,</span>  <span class="c1"># single-quoted string</span>
    <span class="s1">&#39;i18n_open&#39;</span><span class="p">:</span> <span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="s2">&quot;_(&quot;</span><span class="p">),</span>
    <span class="s1">&#39;i18n_close&#39;</span><span class="p">:</span> <span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="s2">&quot;)&quot;</span><span class="p">),</span>
<span class="p">}</span>
<span class="n">constant_string</span> <span class="o">=</span> <span class="n">constant_string</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>

<span class="n">filter_raw_string</span> <span class="o">=</span> <span class="s2">r&quot;&quot;&quot;</span>
<span class="s2">^(?P&lt;constant&gt;</span><span class="si">%(constant)s</span><span class="s2">)|</span>
<span class="s2">^(?P&lt;var&gt;[</span><span class="si">%(var_chars)s</span><span class="s2">]+|</span><span class="si">%(num)s</span><span class="s2">)|</span>
<span class="s2"> (?:\s*</span><span class="si">%(filter_sep)s</span><span class="s2">\s*</span>
<span class="s2">     (?P&lt;filter_name&gt;\w+)</span>
<span class="s2">         (?:</span><span class="si">%(arg_sep)s</span><span class="s2"></span>
<span class="s2">             (?:</span>
<span class="s2">              (?P&lt;constant_arg&gt;</span><span class="si">%(constant)s</span><span class="s2">)|</span>
<span class="s2">              (?P&lt;var_arg&gt;[</span><span class="si">%(var_chars)s</span><span class="s2">]+|</span><span class="si">%(num)s</span><span class="s2">)</span>
<span class="s2">             )</span>
<span class="s2">         )?</span>
<span class="s2"> )&quot;&quot;&quot;</span> <span class="o">%</span> <span class="p">{</span>
    <span class="s1">&#39;constant&#39;</span><span class="p">:</span> <span class="n">constant_string</span><span class="p">,</span>
    <span class="s1">&#39;num&#39;</span><span class="p">:</span> <span class="s1">r&#39;[-+\.]?\d[\d\.e]*&#39;</span><span class="p">,</span>
    <span class="s1">&#39;var_chars&#39;</span><span class="p">:</span> <span class="s2">&quot;\w\.&quot;</span><span class="p">,</span>
    <span class="s1">&#39;filter_sep&#39;</span><span class="p">:</span> <span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">FILTER_SEPARATOR</span><span class="p">),</span>
    <span class="s1">&#39;arg_sep&#39;</span><span class="p">:</span> <span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">FILTER_ARGUMENT_SEPARATOR</span><span class="p">),</span>
<span class="p">}</span>

<span class="n">filter_re</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">filter_raw_string</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">UNICODE</span> <span class="o">|</span> <span class="n">re</span><span class="o">.</span><span class="n">VERBOSE</span><span class="p">)</span>


<span class="k">class</span> <span class="nc">FilterExpression</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Parses a variable token and its optional filters (all as a single string),</span>
<span class="sd">    and return a list of tuples of the filter name and arguments.</span>
<span class="sd">    Sample::</span>

<span class="sd">        &gt;&gt;&gt; token = &#39;variable|default:&quot;Default value&quot;|date:&quot;Y-m-d&quot;&#39;</span>
<span class="sd">        &gt;&gt;&gt; p = Parser(&#39;&#39;)</span>
<span class="sd">        &gt;&gt;&gt; fe = FilterExpression(token, p)</span>
<span class="sd">        &gt;&gt;&gt; len(fe.filters)</span>
<span class="sd">        2</span>
<span class="sd">        &gt;&gt;&gt; fe.var</span>
<span class="sd">        &lt;Variable: &#39;variable&#39;&gt;</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span> <span class="n">parser</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">token</span> <span class="o">=</span> <span class="n">token</span>
        <span class="n">matches</span> <span class="o">=</span> <span class="n">filter_re</span><span class="o">.</span><span class="n">finditer</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
        <span class="n">var_obj</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="n">filters</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="n">upto</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">matches</span><span class="p">:</span>
            <span class="n">start</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
            <span class="k">if</span> <span class="n">upto</span> <span class="o">!=</span> <span class="n">start</span><span class="p">:</span>
                <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="s2">&quot;Could not parse some characters: &quot;</span>
                                          <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">|</span><span class="si">%s</span><span class="s2">|</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span>
                                          <span class="p">(</span><span class="n">token</span><span class="p">[:</span><span class="n">upto</span><span class="p">],</span> <span class="n">token</span><span class="p">[</span><span class="n">upto</span><span class="p">:</span><span class="n">start</span><span class="p">],</span>
                                           <span class="n">token</span><span class="p">[</span><span class="n">start</span><span class="p">:]))</span>
            <span class="k">if</span> <span class="n">var_obj</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">var</span><span class="p">,</span> <span class="n">constant</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s2">&quot;var&quot;</span><span class="p">,</span> <span class="s2">&quot;constant&quot;</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">constant</span><span class="p">:</span>
                    <span class="k">try</span><span class="p">:</span>
                        <span class="n">var_obj</span> <span class="o">=</span> <span class="n">Variable</span><span class="p">(</span><span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">resolve</span><span class="p">({})</span>
                    <span class="k">except</span> <span class="n">VariableDoesNotExist</span><span class="p">:</span>
                        <span class="n">var_obj</span> <span class="o">=</span> <span class="kc">None</span>
                <span class="k">elif</span> <span class="n">var</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="s2">&quot;Could not find variable at &quot;</span>
                                              <span class="s2">&quot;start of </span><span class="si">%s</span><span class="s2">.&quot;</span> <span class="o">%</span> <span class="n">token</span><span class="p">)</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">var_obj</span> <span class="o">=</span> <span class="n">Variable</span><span class="p">(</span><span class="n">var</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">filter_name</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s2">&quot;filter_name&quot;</span><span class="p">)</span>
                <span class="n">args</span> <span class="o">=</span> <span class="p">[]</span>
                <span class="n">constant_arg</span><span class="p">,</span> <span class="n">var_arg</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s2">&quot;constant_arg&quot;</span><span class="p">,</span> <span class="s2">&quot;var_arg&quot;</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">constant_arg</span><span class="p">:</span>
                    <span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="kc">False</span><span class="p">,</span> <span class="n">Variable</span><span class="p">(</span><span class="n">constant_arg</span><span class="p">)</span><span class="o">.</span><span class="n">resolve</span><span class="p">({})))</span>
                <span class="k">elif</span> <span class="n">var_arg</span><span class="p">:</span>
                    <span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="kc">True</span><span class="p">,</span> <span class="n">Variable</span><span class="p">(</span><span class="n">var_arg</span><span class="p">)))</span>
                <span class="n">filter_func</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">find_filter</span><span class="p">(</span><span class="n">filter_name</span><span class="p">)</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">args_check</span><span class="p">(</span><span class="n">filter_name</span><span class="p">,</span> <span class="n">filter_func</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span>
                <span class="n">filters</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">filter_func</span><span class="p">,</span> <span class="n">args</span><span class="p">))</span>
            <span class="n">upto</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">end</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">upto</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">token</span><span class="p">):</span>
            <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="s2">&quot;Could not parse the remainder: &#39;</span><span class="si">%s</span><span class="s2">&#39; &quot;</span>
                                      <span class="s2">&quot;from &#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">token</span><span class="p">[</span><span class="n">upto</span><span class="p">:],</span> <span class="n">token</span><span class="p">))</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">filters</span> <span class="o">=</span> <span class="n">filters</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">var</span> <span class="o">=</span> <span class="n">var_obj</span>

    <span class="k">def</span> <span class="nf">resolve</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">,</span> <span class="n">ignore_failures</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">var</span><span class="p">,</span> <span class="n">Variable</span><span class="p">):</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">var</span><span class="o">.</span><span class="n">resolve</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
            <span class="k">except</span> <span class="n">VariableDoesNotExist</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">ignore_failures</span><span class="p">:</span>
                    <span class="n">obj</span> <span class="o">=</span> <span class="kc">None</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">string_if_invalid</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">template</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">string_if_invalid</span>
                    <span class="k">if</span> <span class="n">string_if_invalid</span><span class="p">:</span>
                        <span class="k">if</span> <span class="s1">&#39;</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="ow">in</span> <span class="n">string_if_invalid</span><span class="p">:</span>
                            <span class="k">return</span> <span class="n">string_if_invalid</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">var</span>
                        <span class="k">else</span><span class="p">:</span>
                            <span class="k">return</span> <span class="n">string_if_invalid</span>
                    <span class="k">else</span><span class="p">:</span>
                        <span class="n">obj</span> <span class="o">=</span> <span class="n">string_if_invalid</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">var</span>
        <span class="k">for</span> <span class="n">func</span><span class="p">,</span> <span class="n">args</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">filters</span><span class="p">:</span>
            <span class="n">arg_vals</span> <span class="o">=</span> <span class="p">[]</span>
            <span class="k">for</span> <span class="n">lookup</span><span class="p">,</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">args</span><span class="p">:</span>
                <span class="k">if</span> <span class="ow">not</span> <span class="n">lookup</span><span class="p">:</span>
                    <span class="n">arg_vals</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">mark_safe</span><span class="p">(</span><span class="n">arg</span><span class="p">))</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">arg_vals</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">arg</span><span class="o">.</span><span class="n">resolve</span><span class="p">(</span><span class="n">context</span><span class="p">))</span>
            <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s1">&#39;expects_localtime&#39;</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
                <span class="n">obj</span> <span class="o">=</span> <span class="n">template_localtime</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">context</span><span class="o">.</span><span class="n">use_tz</span><span class="p">)</span>
            <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s1">&#39;needs_autoescape&#39;</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
                <span class="n">new_obj</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">autoescape</span><span class="o">=</span><span class="n">context</span><span class="o">.</span><span class="n">autoescape</span><span class="p">,</span> <span class="o">*</span><span class="n">arg_vals</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">new_obj</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="o">*</span><span class="n">arg_vals</span><span class="p">)</span>
            <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s1">&#39;is_safe&#39;</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">SafeData</span><span class="p">):</span>
                <span class="n">obj</span> <span class="o">=</span> <span class="n">mark_safe</span><span class="p">(</span><span class="n">new_obj</span><span class="p">)</span>
            <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">EscapeData</span><span class="p">):</span>
                <span class="n">obj</span> <span class="o">=</span> <span class="n">mark_for_escaping</span><span class="p">(</span><span class="n">new_obj</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">obj</span> <span class="o">=</span> <span class="n">new_obj</span>
        <span class="k">return</span> <span class="n">obj</span>

    <span class="k">def</span> <span class="nf">args_check</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="n">provided</span><span class="p">):</span>
        <span class="n">provided</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">provided</span><span class="p">)</span>
        <span class="c1"># First argument, filter input, is implied.</span>
        <span class="n">plen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">provided</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
        <span class="c1"># Check to see if a decorator is providing the real function.</span>
        <span class="n">func</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s1">&#39;_decorated_function&#39;</span><span class="p">,</span> <span class="n">func</span><span class="p">)</span>

        <span class="n">args</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">defaults</span> <span class="o">=</span> <span class="n">getargspec</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>
        <span class="n">alen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
        <span class="n">dlen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">defaults</span> <span class="ow">or</span> <span class="p">[])</span>
        <span class="c1"># Not enough OR Too many</span>
        <span class="k">if</span> <span class="n">plen</span> <span class="o">&lt;</span> <span class="p">(</span><span class="n">alen</span> <span class="o">-</span> <span class="n">dlen</span><span class="p">)</span> <span class="ow">or</span> <span class="n">plen</span> <span class="o">&gt;</span> <span class="n">alen</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> requires </span><span class="si">%d</span><span class="s2"> arguments, </span><span class="si">%d</span><span class="s2"> provided&quot;</span> <span class="o">%</span>
                                      <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">alen</span> <span class="o">-</span> <span class="n">dlen</span><span class="p">,</span> <span class="n">plen</span><span class="p">))</span>

        <span class="k">return</span> <span class="kc">True</span>
    <span class="n">args_check</span> <span class="o">=</span> <span class="nb">staticmethod</span><span class="p">(</span><span class="n">args_check</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">token</span>


<span class="k">def</span> <span class="nf">resolve_variable</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Returns the resolved variable, which may contain attribute syntax, within</span>
<span class="sd">    the given context.</span>

<span class="sd">    Deprecated; use the Variable class instead.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s2">&quot;resolve_variable() is deprecated. Use django.template.&quot;</span>
                  <span class="s2">&quot;Variable(path).resolve(context) instead&quot;</span><span class="p">,</span>
                  <span class="n">RemovedInDjango110Warning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">Variable</span><span class="p">(</span><span class="n">path</span><span class="p">)</span><span class="o">.</span><span class="n">resolve</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>


<span class="k">class</span> <span class="nc">Variable</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A template variable, resolvable against a given context. The variable may</span>
<span class="sd">    be a hard-coded string (if it begins and ends with single or double quote</span>
<span class="sd">    marks)::</span>

<span class="sd">        &gt;&gt;&gt; c = {&#39;article&#39;: {&#39;section&#39;:u&#39;News&#39;}}</span>
<span class="sd">        &gt;&gt;&gt; Variable(&#39;article.section&#39;).resolve(c)</span>
<span class="sd">        u&#39;News&#39;</span>
<span class="sd">        &gt;&gt;&gt; Variable(&#39;article&#39;).resolve(c)</span>
<span class="sd">        {&#39;section&#39;: u&#39;News&#39;}</span>
<span class="sd">        &gt;&gt;&gt; class AClass: pass</span>
<span class="sd">        &gt;&gt;&gt; c = AClass()</span>
<span class="sd">        &gt;&gt;&gt; c.article = AClass()</span>
<span class="sd">        &gt;&gt;&gt; c.article.section = u&#39;News&#39;</span>

<span class="sd">    (The example assumes VARIABLE_ATTRIBUTE_SEPARATOR is &#39;.&#39;)</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">var</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">var</span> <span class="o">=</span> <span class="n">var</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">literal</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lookups</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">translate</span> <span class="o">=</span> <span class="kc">False</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">message_context</span> <span class="o">=</span> <span class="kc">None</span>

        <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">var</span><span class="p">,</span> <span class="n">six</span><span class="o">.</span><span class="n">string_types</span><span class="p">):</span>
            <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
                <span class="s2">&quot;Variable must be a string or number, got </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">type</span><span class="p">(</span><span class="n">var</span><span class="p">))</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="c1"># First try to treat this variable as a number.</span>
            <span class="c1">#</span>
            <span class="c1"># Note that this could cause an OverflowError here that we&#39;re not</span>
            <span class="c1"># catching. Since this should only happen at compile time, that&#39;s</span>
            <span class="c1"># probably OK.</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">literal</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">var</span><span class="p">)</span>

            <span class="c1"># So it&#39;s a float... is it an int? If the original value contained a</span>
            <span class="c1"># dot or an &quot;e&quot; then it was a float, not an int.</span>
            <span class="k">if</span> <span class="s1">&#39;.&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">var</span> <span class="ow">and</span> <span class="s1">&#39;e&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">var</span><span class="o">.</span><span class="n">lower</span><span class="p">():</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">literal</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">literal</span><span class="p">)</span>

            <span class="c1"># &quot;2.&quot; is invalid</span>
            <span class="k">if</span> <span class="n">var</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">):</span>
                <span class="k">raise</span> <span class="ne">ValueError</span>

        <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
            <span class="c1"># A ValueError means that the variable isn&#39;t a number.</span>
            <span class="k">if</span> <span class="n">var</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;_(&#39;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">var</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">&#39;)&#39;</span><span class="p">):</span>
                <span class="c1"># The result of the lookup should be translated at rendering</span>
                <span class="c1"># time.</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">translate</span> <span class="o">=</span> <span class="kc">True</span>
                <span class="n">var</span> <span class="o">=</span> <span class="n">var</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
            <span class="c1"># If it&#39;s wrapped with quotes (single or double), then</span>
            <span class="c1"># we&#39;re also dealing with a literal.</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">literal</span> <span class="o">=</span> <span class="n">mark_safe</span><span class="p">(</span><span class="n">unescape_string_literal</span><span class="p">(</span><span class="n">var</span><span class="p">))</span>
            <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
                <span class="c1"># Otherwise we&#39;ll set self.lookups so that resolve() knows we&#39;re</span>
                <span class="c1"># dealing with a bonafide variable</span>
                <span class="k">if</span> <span class="n">var</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">VARIABLE_ATTRIBUTE_SEPARATOR</span> <span class="o">+</span> <span class="s1">&#39;_&#39;</span><span class="p">)</span> <span class="o">&gt;</span> <span class="o">-</span><span class="mi">1</span> <span class="ow">or</span> <span class="n">var</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;_&#39;</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="s2">&quot;Variables and attributes may &quot;</span>
                                              <span class="s2">&quot;not begin with underscores: &#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span>
                                              <span class="n">var</span><span class="p">)</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">lookups</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">var</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">VARIABLE_ATTRIBUTE_SEPARATOR</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">resolve</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Resolve this variable against a given context.&quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">lookups</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="c1"># We&#39;re dealing with a variable that needs to be resolved</span>
            <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_resolve_lookup</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c1"># We&#39;re dealing with a literal, so it&#39;s already been &quot;resolved&quot;</span>
            <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">literal</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">translate</span><span class="p">:</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">message_context</span><span class="p">:</span>
                <span class="k">return</span> <span class="n">pgettext_lazy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message_context</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">return</span> <span class="n">ugettext_lazy</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">value</span>

    <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s2">&quot;&lt;</span><span class="si">%s</span><span class="s2">: </span><span class="si">%r</span><span class="s2">&gt;&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">var</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">var</span>

    <span class="k">def</span> <span class="nf">_resolve_lookup</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Performs resolution of a real variable (i.e. not a literal) against the</span>
<span class="sd">        given context.</span>

<span class="sd">        As indicated by the method&#39;s name, this method is an implementation</span>
<span class="sd">        detail and shouldn&#39;t be called by external code. Use Variable.resolve()</span>
<span class="sd">        instead.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">current</span> <span class="o">=</span> <span class="n">context</span>
        <span class="k">try</span><span class="p">:</span>  <span class="c1"># catch-all for silent variable failures</span>
            <span class="k">for</span> <span class="n">bit</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">lookups</span><span class="p">:</span>
                <span class="k">try</span><span class="p">:</span>  <span class="c1"># dictionary lookup</span>
                    <span class="n">current</span> <span class="o">=</span> <span class="n">current</span><span class="p">[</span><span class="n">bit</span><span class="p">]</span>
                    <span class="c1"># ValueError/IndexError are for numpy.array lookup on</span>
                    <span class="c1"># numpy &lt; 1.9 and 1.9+ respectively</span>
                <span class="k">except</span> <span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="ne">AttributeError</span><span class="p">,</span> <span class="ne">KeyError</span><span class="p">,</span> <span class="ne">ValueError</span><span class="p">,</span> <span class="ne">IndexError</span><span class="p">):</span>
                    <span class="k">try</span><span class="p">:</span>  <span class="c1"># attribute lookup</span>
                        <span class="c1"># Don&#39;t return class attributes if the class is the context:</span>
                        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">current</span><span class="p">,</span> <span class="n">BaseContext</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">getattr</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">current</span><span class="p">),</span> <span class="n">bit</span><span class="p">):</span>
                            <span class="k">raise</span> <span class="ne">AttributeError</span>
                        <span class="n">current</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">current</span><span class="p">,</span> <span class="n">bit</span><span class="p">)</span>
                    <span class="k">except</span> <span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="ne">AttributeError</span><span class="p">)</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
                        <span class="c1"># Reraise an AttributeError raised by a @property</span>
                        <span class="k">if</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="ne">AttributeError</span><span class="p">)</span> <span class="ow">and</span>
                                <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">current</span><span class="p">,</span> <span class="n">BaseContext</span><span class="p">)</span> <span class="ow">and</span> <span class="n">bit</span> <span class="ow">in</span> <span class="nb">dir</span><span class="p">(</span><span class="n">current</span><span class="p">)):</span>
                            <span class="k">raise</span>
                        <span class="k">try</span><span class="p">:</span>  <span class="c1"># list-index lookup</span>
                            <span class="n">current</span> <span class="o">=</span> <span class="n">current</span><span class="p">[</span><span class="nb">int</span><span class="p">(</span><span class="n">bit</span><span class="p">)]</span>
                        <span class="k">except</span> <span class="p">(</span><span class="ne">IndexError</span><span class="p">,</span>  <span class="c1"># list index out of range</span>
                                <span class="ne">ValueError</span><span class="p">,</span>  <span class="c1"># invalid literal for int()</span>
                                <span class="ne">KeyError</span><span class="p">,</span>    <span class="c1"># current is a dict without `int(bit)` key</span>
                                <span class="ne">TypeError</span><span class="p">):</span>  <span class="c1"># unsubscriptable object</span>
                            <span class="k">raise</span> <span class="n">VariableDoesNotExist</span><span class="p">(</span><span class="s2">&quot;Failed lookup for key &quot;</span>
                                                       <span class="s2">&quot;[</span><span class="si">%s</span><span class="s2">] in </span><span class="si">%r</span><span class="s2">&quot;</span><span class="p">,</span>
                                                       <span class="p">(</span><span class="n">bit</span><span class="p">,</span> <span class="n">current</span><span class="p">))</span>  <span class="c1"># missing attribute</span>
                <span class="k">if</span> <span class="n">callable</span><span class="p">(</span><span class="n">current</span><span class="p">):</span>
                    <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">current</span><span class="p">,</span> <span class="s1">&#39;do_not_call_in_templates&#39;</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
                        <span class="k">pass</span>
                    <span class="k">elif</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">current</span><span class="p">,</span> <span class="s1">&#39;alters_data&#39;</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
                        <span class="n">current</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">template</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">string_if_invalid</span>
                    <span class="k">else</span><span class="p">:</span>
                        <span class="k">try</span><span class="p">:</span>  <span class="c1"># method call (assuming no args required)</span>
                            <span class="n">current</span> <span class="o">=</span> <span class="n">current</span><span class="p">()</span>
                        <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
                            <span class="k">try</span><span class="p">:</span>
                                <span class="n">inspect</span><span class="o">.</span><span class="n">getcallargs</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
                            <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>  <span class="c1"># arguments *were* required</span>
                                <span class="n">current</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">template</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">string_if_invalid</span>  <span class="c1"># invalid method call</span>
                            <span class="k">else</span><span class="p">:</span>
                                <span class="k">raise</span>
        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
            <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="s1">&#39;silent_variable_failure&#39;</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
                <span class="n">current</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">template</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">string_if_invalid</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">raise</span>

        <span class="k">return</span> <span class="n">current</span>


<span class="k">class</span> <span class="nc">Node</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="c1"># Set this to True for nodes that must be first in the template (although</span>
    <span class="c1"># they can be preceded by text nodes.</span>
    <span class="n">must_be_first</span> <span class="o">=</span> <span class="kc">False</span>
    <span class="n">child_nodelists</span> <span class="o">=</span> <span class="p">(</span><span class="s1">&#39;nodelist&#39;</span><span class="p">,)</span>

    <span class="k">def</span> <span class="nf">render</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return the node rendered as a string.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">pass</span>

    <span class="k">def</span> <span class="nf">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">yield</span> <span class="bp">self</span>

    <span class="k">def</span> <span class="nf">get_nodes_by_type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nodetype</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a list of all nodes (within this node and its nodelist)</span>
<span class="sd">        of the given type</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">nodes</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nodetype</span><span class="p">):</span>
            <span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">child_nodelists</span><span class="p">:</span>
            <span class="n">nodelist</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attr</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">nodelist</span><span class="p">:</span>
                <span class="n">nodes</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">nodelist</span><span class="o">.</span><span class="n">get_nodes_by_type</span><span class="p">(</span><span class="n">nodetype</span><span class="p">))</span>
        <span class="k">return</span> <span class="n">nodes</span>


<span class="k">class</span> <span class="nc">NodeList</span><span class="p">(</span><span class="nb">list</span><span class="p">):</span>
    <span class="c1"># Set to True the first time a non-TextNode is inserted by</span>
    <span class="c1"># extend_nodelist().</span>
    <span class="n">contains_nontext</span> <span class="o">=</span> <span class="kc">False</span>

    <span class="k">def</span> <span class="nf">render</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
        <span class="n">bits</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span>
            <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">Node</span><span class="p">):</span>
                <span class="n">bit</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">render_node</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">bit</span> <span class="o">=</span> <span class="n">node</span>
            <span class="n">bits</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">force_text</span><span class="p">(</span><span class="n">bit</span><span class="p">))</span>
        <span class="k">return</span> <span class="n">mark_safe</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">bits</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">get_nodes_by_type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nodetype</span><span class="p">):</span>
        <span class="s2">&quot;Return a list of all nodes of the given type&quot;</span>
        <span class="n">nodes</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span>
            <span class="n">nodes</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">get_nodes_by_type</span><span class="p">(</span><span class="n">nodetype</span><span class="p">))</span>
        <span class="k">return</span> <span class="n">nodes</span>

    <span class="k">def</span> <span class="nf">render_node</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">node</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">node</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>


<span class="k">class</span> <span class="nc">TextNode</span><span class="p">(</span><span class="n">Node</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">s</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">s</span> <span class="o">=</span> <span class="n">s</span>

    <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">force_str</span><span class="p">(</span><span class="s2">&quot;&lt;Text Node: &#39;</span><span class="si">%s</span><span class="s2">&#39;&gt;&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">s</span><span class="p">[:</span><span class="mi">25</span><span class="p">],</span> <span class="s1">&#39;ascii&#39;</span><span class="p">,</span>
                <span class="n">errors</span><span class="o">=</span><span class="s1">&#39;replace&#39;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">render</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">s</span>


<span class="k">def</span> <span class="nf">render_value_in_context</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Converts any value to a string to become part of a rendered template. This</span>
<span class="sd">    means escaping, if required, and conversion to a unicode object. If value</span>
<span class="sd">    is a string, it is expected to have already been translated.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">value</span> <span class="o">=</span> <span class="n">template_localtime</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">use_tz</span><span class="o">=</span><span class="n">context</span><span class="o">.</span><span class="n">use_tz</span><span class="p">)</span>
    <span class="n">value</span> <span class="o">=</span> <span class="n">localize</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">use_l10n</span><span class="o">=</span><span class="n">context</span><span class="o">.</span><span class="n">use_l10n</span><span class="p">)</span>
    <span class="n">value</span> <span class="o">=</span> <span class="n">force_text</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
    <span class="k">if</span> <span class="p">((</span><span class="n">context</span><span class="o">.</span><span class="n">autoescape</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">SafeData</span><span class="p">))</span> <span class="ow">or</span>
            <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">EscapeData</span><span class="p">)):</span>
        <span class="k">return</span> <span class="n">conditional_escape</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">value</span>


<span class="k">class</span> <span class="nc">VariableNode</span><span class="p">(</span><span class="n">Node</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filter_expression</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">filter_expression</span> <span class="o">=</span> <span class="n">filter_expression</span>

    <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s2">&quot;&lt;Variable Node: </span><span class="si">%s</span><span class="s2">&gt;&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter_expression</span>

    <span class="k">def</span> <span class="nf">render</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">output</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter_expression</span><span class="o">.</span><span class="n">resolve</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
        <span class="k">except</span> <span class="ne">UnicodeDecodeError</span><span class="p">:</span>
            <span class="c1"># Unicode conversion can fail sometimes for reasons out of our</span>
            <span class="c1"># control (e.g. exception rendering). In that case, we fail</span>
            <span class="c1"># quietly.</span>
            <span class="k">return</span> <span class="s1">&#39;&#39;</span>
        <span class="k">return</span> <span class="n">render_value_in_context</span><span class="p">(</span><span class="n">output</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>

<span class="c1"># Regex for token keyword arguments</span>
<span class="n">kwarg_re</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s2">r&quot;(?:(\w+)=)?(.+)&quot;</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">token_kwargs</span><span class="p">(</span><span class="n">bits</span><span class="p">,</span> <span class="n">parser</span><span class="p">,</span> <span class="n">support_legacy</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A utility method for parsing token keyword arguments.</span>

<span class="sd">    :param bits: A list containing remainder of the token (split by spaces)</span>
<span class="sd">        that is to be checked for arguments. Valid arguments will be removed</span>
<span class="sd">        from this list.</span>

<span class="sd">    :param support_legacy: If set to true ``True``, the legacy format</span>
<span class="sd">        ``1 as foo`` will be accepted. Otherwise, only the standard ``foo=1``</span>
<span class="sd">        format is allowed.</span>

<span class="sd">    :returns: A dictionary of the arguments retrieved from the ``bits`` token</span>
<span class="sd">        list.</span>

<span class="sd">    There is no requirement for all remaining token ``bits`` to be keyword</span>
<span class="sd">    arguments, so the dictionary will be returned as soon as an invalid</span>
<span class="sd">    argument format is reached.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">bits</span><span class="p">:</span>
        <span class="k">return</span> <span class="p">{}</span>
    <span class="n">match</span> <span class="o">=</span> <span class="n">kwarg_re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">bits</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
    <span class="n">kwarg_format</span> <span class="o">=</span> <span class="n">match</span> <span class="ow">and</span> <span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">kwarg_format</span><span class="p">:</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">support_legacy</span><span class="p">:</span>
            <span class="k">return</span> <span class="p">{}</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">bits</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">3</span> <span class="ow">or</span> <span class="n">bits</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">&#39;as&#39;</span><span class="p">:</span>
            <span class="k">return</span> <span class="p">{}</span>

    <span class="n">kwargs</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="k">while</span> <span class="n">bits</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">kwarg_format</span><span class="p">:</span>
            <span class="n">match</span> <span class="o">=</span> <span class="n">kwarg_re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">bits</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="n">match</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">):</span>
                <span class="k">return</span> <span class="n">kwargs</span>
            <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">groups</span><span class="p">()</span>
            <span class="k">del</span> <span class="n">bits</span><span class="p">[:</span><span class="mi">1</span><span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">bits</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">3</span> <span class="ow">or</span> <span class="n">bits</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">&#39;as&#39;</span><span class="p">:</span>
                <span class="k">return</span> <span class="n">kwargs</span>
            <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="n">bits</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">bits</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
            <span class="k">del</span> <span class="n">bits</span><span class="p">[:</span><span class="mi">3</span><span class="p">]</span>
        <span class="n">kwargs</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">compile_filter</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">bits</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">kwarg_format</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">bits</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">&#39;and&#39;</span><span class="p">:</span>
                <span class="k">return</span> <span class="n">kwargs</span>
            <span class="k">del</span> <span class="n">bits</span><span class="p">[:</span><span class="mi">1</span><span class="p">]</span>
    <span class="k">return</span> <span class="n">kwargs</span>


<span class="k">def</span> <span class="nf">parse_bits</span><span class="p">(</span><span class="n">parser</span><span class="p">,</span> <span class="n">bits</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span><span class="p">,</span> <span class="n">defaults</span><span class="p">,</span>
               <span class="n">takes_context</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Parses bits for template tag helpers (simple_tag, include_tag and</span>
<span class="sd">    assignment_tag), in particular by detecting syntax errors and by</span>
<span class="sd">    extracting positional and keyword arguments.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">takes_context</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">params</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;context&#39;</span><span class="p">:</span>
            <span class="n">params</span> <span class="o">=</span> <span class="n">params</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span>
                <span class="s2">&quot;&#39;</span><span class="si">%s</span><span class="s2">&#39; is decorated with takes_context=True so it must &quot;</span>
                <span class="s2">&quot;have a first argument of &#39;context&#39;&quot;</span> <span class="o">%</span> <span class="n">name</span><span class="p">)</span>
    <span class="n">args</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="n">kwargs</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="n">unhandled_params</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
    <span class="k">for</span> <span class="n">bit</span> <span class="ow">in</span> <span class="n">bits</span><span class="p">:</span>
        <span class="c1"># First we try to extract a potential kwarg from the bit</span>
        <span class="n">kwarg</span> <span class="o">=</span> <span class="n">token_kwargs</span><span class="p">([</span><span class="n">bit</span><span class="p">],</span> <span class="n">parser</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">kwarg</span><span class="p">:</span>
            <span class="c1"># The kwarg was successfully extracted</span>
            <span class="n">param</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">six</span><span class="o">.</span><span class="n">iteritems</span><span class="p">(</span><span class="n">kwarg</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span>
            <span class="k">if</span> <span class="n">param</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">params</span> <span class="ow">and</span> <span class="n">varkw</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                <span class="c1"># An unexpected keyword argument was supplied</span>
                <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span>
                    <span class="s2">&quot;&#39;</span><span class="si">%s</span><span class="s2">&#39; received unexpected keyword argument &#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span>
                    <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">param</span><span class="p">))</span>
            <span class="k">elif</span> <span class="n">param</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
                <span class="c1"># The keyword argument has already been supplied once</span>
                <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span>
                    <span class="s2">&quot;&#39;</span><span class="si">%s</span><span class="s2">&#39; received multiple values for keyword argument &#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span>
                    <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">param</span><span class="p">))</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="c1"># All good, record the keyword argument</span>
                <span class="n">kwargs</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">param</span><span class="p">)]</span> <span class="o">=</span> <span class="n">value</span>
                <span class="k">if</span> <span class="n">param</span> <span class="ow">in</span> <span class="n">unhandled_params</span><span class="p">:</span>
                    <span class="c1"># If using the keyword syntax for a positional arg, then</span>
                    <span class="c1"># consume it.</span>
                    <span class="n">unhandled_params</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">param</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">kwargs</span><span class="p">:</span>
                <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span>
                    <span class="s2">&quot;&#39;</span><span class="si">%s</span><span class="s2">&#39; received some positional argument(s) after some &quot;</span>
                    <span class="s2">&quot;keyword argument(s)&quot;</span> <span class="o">%</span> <span class="n">name</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="c1"># Record the positional argument</span>
                <span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">compile_filter</span><span class="p">(</span><span class="n">bit</span><span class="p">))</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="c1"># Consume from the list of expected positional arguments</span>
                    <span class="n">unhandled_params</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
                <span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">varargs</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                        <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span>
                            <span class="s2">&quot;&#39;</span><span class="si">%s</span><span class="s2">&#39; received too many positional arguments&quot;</span> <span class="o">%</span>
                            <span class="n">name</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">defaults</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
        <span class="c1"># Consider the last n params handled, where n is the</span>
        <span class="c1"># number of defaults.</span>
        <span class="n">unhandled_params</span> <span class="o">=</span> <span class="n">unhandled_params</span><span class="p">[:</span><span class="o">-</span><span class="nb">len</span><span class="p">(</span><span class="n">defaults</span><span class="p">)]</span>
    <span class="k">if</span> <span class="n">unhandled_params</span><span class="p">:</span>
        <span class="c1"># Some positional arguments were not supplied</span>
        <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span>
            <span class="s2">&quot;&#39;</span><span class="si">%s</span><span class="s2">&#39; did not receive value(s) for the argument(s): </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span>
            <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s2">&quot;&#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span> <span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">unhandled_params</span><span class="p">)))</span>
    <span class="k">return</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span>


<span class="k">def</span> <span class="nf">generic_tag_compiler</span><span class="p">(</span><span class="n">parser</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span><span class="p">,</span> <span class="n">defaults</span><span class="p">,</span>
                         <span class="n">name</span><span class="p">,</span> <span class="n">takes_context</span><span class="p">,</span> <span class="n">node_class</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Returns a template.Node subclass.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">bits</span> <span class="o">=</span> <span class="n">token</span><span class="o">.</span><span class="n">split_contents</span><span class="p">()[</span><span class="mi">1</span><span class="p">:]</span>
    <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span> <span class="o">=</span> <span class="n">parse_bits</span><span class="p">(</span><span class="n">parser</span><span class="p">,</span> <span class="n">bits</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span><span class="p">,</span>
                              <span class="n">defaults</span><span class="p">,</span> <span class="n">takes_context</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">node_class</span><span class="p">(</span><span class="n">takes_context</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">)</span>


<span class="k">class</span> <span class="nc">TagHelperNode</span><span class="p">(</span><span class="n">Node</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Base class for tag helper nodes such as SimpleNode, InclusionNode and</span>
<span class="sd">    AssignmentNode. Manages the positional and keyword arguments to be passed</span>
<span class="sd">    to the decorated function.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">takes_context</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">takes_context</span> <span class="o">=</span> <span class="n">takes_context</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="n">args</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">kwargs</span> <span class="o">=</span> <span class="n">kwargs</span>

    <span class="k">def</span> <span class="nf">get_resolved_arguments</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
        <span class="n">resolved_args</span> <span class="o">=</span> <span class="p">[</span><span class="n">var</span><span class="o">.</span><span class="n">resolve</span><span class="p">(</span><span class="n">context</span><span class="p">)</span> <span class="k">for</span> <span class="n">var</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">]</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">takes_context</span><span class="p">:</span>
            <span class="n">resolved_args</span> <span class="o">=</span> <span class="p">[</span><span class="n">context</span><span class="p">]</span> <span class="o">+</span> <span class="n">resolved_args</span>
        <span class="n">resolved_kwargs</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span><span class="o">.</span><span class="n">resolve</span><span class="p">(</span><span class="n">context</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">kwargs</span><span class="o">.</span><span class="n">items</span><span class="p">()}</span>
        <span class="k">return</span> <span class="n">resolved_args</span><span class="p">,</span> <span class="n">resolved_kwargs</span>


<span class="k">class</span> <span class="nc">Library</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">filters</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">tags</span> <span class="o">=</span> <span class="p">{}</span>

    <span class="k">def</span> <span class="nf">tag</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">compile_function</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">name</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">compile_function</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="c1"># @register.tag()</span>
            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">tag_function</span>
        <span class="k">elif</span> <span class="n">name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">compile_function</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">callable</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
                <span class="c1"># @register.tag</span>
                <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">tag_function</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="c1"># @register.tag(&#39;somename&#39;) or @register.tag(name=&#39;somename&#39;)</span>
                <span class="k">def</span> <span class="nf">dec</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
                    <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">tag</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">func</span><span class="p">)</span>
                <span class="k">return</span> <span class="n">dec</span>
        <span class="k">elif</span> <span class="n">name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">compile_function</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="c1"># register.tag(&#39;somename&#39;, somefunc)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">tags</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">compile_function</span>
            <span class="k">return</span> <span class="n">compile_function</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">InvalidTemplateLibrary</span><span class="p">(</span><span class="s2">&quot;Unsupported arguments to &quot;</span>
                <span class="s2">&quot;Library.tag: (</span><span class="si">%r</span><span class="s2">, </span><span class="si">%r</span><span class="s2">)&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">compile_function</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">tag_function</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">func</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">tags</span><span class="p">[</span><span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s2">&quot;_decorated_function&quot;</span><span class="p">,</span> <span class="n">func</span><span class="p">)</span><span class="o">.</span><span class="n">__name__</span><span class="p">]</span> <span class="o">=</span> <span class="n">func</span>
        <span class="k">return</span> <span class="n">func</span>

    <span class="k">def</span> <span class="nf">filter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">filter_func</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">flags</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">name</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">filter_func</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="c1"># @register.filter()</span>
            <span class="k">def</span> <span class="nf">dec</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
                <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter_function</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="o">**</span><span class="n">flags</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">dec</span>

        <span class="k">elif</span> <span class="n">name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">filter_func</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">callable</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
                <span class="c1"># @register.filter</span>
                <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter_function</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="o">**</span><span class="n">flags</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="c1"># @register.filter(&#39;somename&#39;) or @register.filter(name=&#39;somename&#39;)</span>
                <span class="k">def</span> <span class="nf">dec</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
                    <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="o">**</span><span class="n">flags</span><span class="p">)</span>
                <span class="k">return</span> <span class="n">dec</span>

        <span class="k">elif</span> <span class="n">name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">filter_func</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="c1"># register.filter(&#39;somename&#39;, somefunc)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">filters</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">filter_func</span>
            <span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;expects_localtime&#39;</span><span class="p">,</span> <span class="s1">&#39;is_safe&#39;</span><span class="p">,</span> <span class="s1">&#39;needs_autoescape&#39;</span><span class="p">):</span>
                <span class="k">if</span> <span class="n">attr</span> <span class="ow">in</span> <span class="n">flags</span><span class="p">:</span>
                    <span class="n">value</span> <span class="o">=</span> <span class="n">flags</span><span class="p">[</span><span class="n">attr</span><span class="p">]</span>
                    <span class="c1"># set the flag on the filter for FilterExpression.resolve</span>
                    <span class="nb">setattr</span><span class="p">(</span><span class="n">filter_func</span><span class="p">,</span> <span class="n">attr</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
                    <span class="c1"># set the flag on the innermost decorated function</span>
                    <span class="c1"># for decorators that need it e.g. stringfilter</span>
                    <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">filter_func</span><span class="p">,</span> <span class="s2">&quot;_decorated_function&quot;</span><span class="p">):</span>
                        <span class="nb">setattr</span><span class="p">(</span><span class="n">filter_func</span><span class="o">.</span><span class="n">_decorated_function</span><span class="p">,</span> <span class="n">attr</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
            <span class="n">filter_func</span><span class="o">.</span><span class="n">_filter_name</span> <span class="o">=</span> <span class="n">name</span>
            <span class="k">return</span> <span class="n">filter_func</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">InvalidTemplateLibrary</span><span class="p">(</span><span class="s2">&quot;Unsupported arguments to &quot;</span>
                <span class="s2">&quot;Library.filter: (</span><span class="si">%r</span><span class="s2">, </span><span class="si">%r</span><span class="s2">)&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">filter_func</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">filter_function</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="o">**</span><span class="n">flags</span><span class="p">):</span>
        <span class="n">name</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s2">&quot;_decorated_function&quot;</span><span class="p">,</span> <span class="n">func</span><span class="p">)</span><span class="o">.</span><span class="n">__name__</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="o">**</span><span class="n">flags</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">simple_tag</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">func</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">takes_context</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="k">def</span> <span class="nf">dec</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
            <span class="n">params</span><span class="p">,</span> <span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span><span class="p">,</span> <span class="n">defaults</span> <span class="o">=</span> <span class="n">getargspec</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>

            <span class="k">class</span> <span class="nc">SimpleNode</span><span class="p">(</span><span class="n">TagHelperNode</span><span class="p">):</span>

                <span class="k">def</span> <span class="nf">render</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
                    <span class="n">resolved_args</span><span class="p">,</span> <span class="n">resolved_kwargs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resolved_arguments</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
                    <span class="k">return</span> <span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">resolved_args</span><span class="p">,</span> <span class="o">**</span><span class="n">resolved_kwargs</span><span class="p">)</span>

            <span class="n">function_name</span> <span class="o">=</span> <span class="p">(</span><span class="n">name</span> <span class="ow">or</span>
                <span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s1">&#39;_decorated_function&#39;</span><span class="p">,</span> <span class="n">func</span><span class="p">)</span><span class="o">.</span><span class="n">__name__</span><span class="p">)</span>
            <span class="n">compile_func</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="n">generic_tag_compiler</span><span class="p">,</span>
                <span class="n">params</span><span class="o">=</span><span class="n">params</span><span class="p">,</span> <span class="n">varargs</span><span class="o">=</span><span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span><span class="o">=</span><span class="n">varkw</span><span class="p">,</span>
                <span class="n">defaults</span><span class="o">=</span><span class="n">defaults</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">function_name</span><span class="p">,</span>
                <span class="n">takes_context</span><span class="o">=</span><span class="n">takes_context</span><span class="p">,</span> <span class="n">node_class</span><span class="o">=</span><span class="n">SimpleNode</span><span class="p">)</span>
            <span class="n">compile_func</span><span class="o">.</span><span class="n">__doc__</span> <span class="o">=</span> <span class="n">func</span><span class="o">.</span><span class="n">__doc__</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">tag</span><span class="p">(</span><span class="n">function_name</span><span class="p">,</span> <span class="n">compile_func</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">func</span>

        <span class="k">if</span> <span class="n">func</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="c1"># @register.simple_tag(...)</span>
            <span class="k">return</span> <span class="n">dec</span>
        <span class="k">elif</span> <span class="n">callable</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
            <span class="c1"># @register.simple_tag</span>
            <span class="k">return</span> <span class="n">dec</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="s2">&quot;Invalid arguments provided to simple_tag&quot;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">assignment_tag</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">func</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">takes_context</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="k">def</span> <span class="nf">dec</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
            <span class="n">params</span><span class="p">,</span> <span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span><span class="p">,</span> <span class="n">defaults</span> <span class="o">=</span> <span class="n">getargspec</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>

            <span class="k">class</span> <span class="nc">AssignmentNode</span><span class="p">(</span><span class="n">TagHelperNode</span><span class="p">):</span>
                <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">takes_context</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="n">target_var</span><span class="p">):</span>
                    <span class="nb">super</span><span class="p">(</span><span class="n">AssignmentNode</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">takes_context</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">)</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">target_var</span> <span class="o">=</span> <span class="n">target_var</span>

                <span class="k">def</span> <span class="nf">render</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
                    <span class="n">resolved_args</span><span class="p">,</span> <span class="n">resolved_kwargs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resolved_arguments</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
                    <span class="n">context</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">target_var</span><span class="p">]</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">resolved_args</span><span class="p">,</span> <span class="o">**</span><span class="n">resolved_kwargs</span><span class="p">)</span>
                    <span class="k">return</span> <span class="s1">&#39;&#39;</span>

            <span class="n">function_name</span> <span class="o">=</span> <span class="p">(</span><span class="n">name</span> <span class="ow">or</span>
                <span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s1">&#39;_decorated_function&#39;</span><span class="p">,</span> <span class="n">func</span><span class="p">)</span><span class="o">.</span><span class="n">__name__</span><span class="p">)</span>

            <span class="k">def</span> <span class="nf">compile_func</span><span class="p">(</span><span class="n">parser</span><span class="p">,</span> <span class="n">token</span><span class="p">):</span>
                <span class="n">bits</span> <span class="o">=</span> <span class="n">token</span><span class="o">.</span><span class="n">split_contents</span><span class="p">()[</span><span class="mi">1</span><span class="p">:]</span>
                <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">bits</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">2</span> <span class="ow">or</span> <span class="n">bits</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">&#39;as&#39;</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span>
                        <span class="s2">&quot;&#39;</span><span class="si">%s</span><span class="s2">&#39; tag takes at least 2 arguments and the &quot;</span>
                        <span class="s2">&quot;second last argument must be &#39;as&#39;&quot;</span> <span class="o">%</span> <span class="n">function_name</span><span class="p">)</span>
                <span class="n">target_var</span> <span class="o">=</span> <span class="n">bits</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
                <span class="n">bits</span> <span class="o">=</span> <span class="n">bits</span><span class="p">[:</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span>
                <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span> <span class="o">=</span> <span class="n">parse_bits</span><span class="p">(</span><span class="n">parser</span><span class="p">,</span> <span class="n">bits</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span>
                    <span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span><span class="p">,</span> <span class="n">defaults</span><span class="p">,</span> <span class="n">takes_context</span><span class="p">,</span> <span class="n">function_name</span><span class="p">)</span>
                <span class="k">return</span> <span class="n">AssignmentNode</span><span class="p">(</span><span class="n">takes_context</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="n">target_var</span><span class="p">)</span>

            <span class="n">compile_func</span><span class="o">.</span><span class="n">__doc__</span> <span class="o">=</span> <span class="n">func</span><span class="o">.</span><span class="n">__doc__</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">tag</span><span class="p">(</span><span class="n">function_name</span><span class="p">,</span> <span class="n">compile_func</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">func</span>

        <span class="k">if</span> <span class="n">func</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="c1"># @register.assignment_tag(...)</span>
            <span class="k">return</span> <span class="n">dec</span>
        <span class="k">elif</span> <span class="n">callable</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
            <span class="c1"># @register.assignment_tag</span>
            <span class="k">return</span> <span class="n">dec</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">TemplateSyntaxError</span><span class="p">(</span><span class="s2">&quot;Invalid arguments provided to assignment_tag&quot;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">inclusion_tag</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">file_name</span><span class="p">,</span> <span class="n">takes_context</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="k">def</span> <span class="nf">dec</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
            <span class="n">params</span><span class="p">,</span> <span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span><span class="p">,</span> <span class="n">defaults</span> <span class="o">=</span> <span class="n">getargspec</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>

            <span class="k">class</span> <span class="nc">InclusionNode</span><span class="p">(</span><span class="n">TagHelperNode</span><span class="p">):</span>

                <span class="k">def</span> <span class="nf">render</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
                    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">                    Renders the specified template and context. Caches the</span>
<span class="sd">                    template object in render_context to avoid reparsing and</span>
<span class="sd">                    loading when used in a for loop.</span>
<span class="sd">                    &quot;&quot;&quot;</span>
                    <span class="n">resolved_args</span><span class="p">,</span> <span class="n">resolved_kwargs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_resolved_arguments</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
                    <span class="n">_dict</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">resolved_args</span><span class="p">,</span> <span class="o">**</span><span class="n">resolved_kwargs</span><span class="p">)</span>

                    <span class="n">t</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">render_context</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
                    <span class="k">if</span> <span class="n">t</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">file_name</span><span class="p">,</span> <span class="n">Template</span><span class="p">):</span>
                            <span class="n">t</span> <span class="o">=</span> <span class="n">file_name</span>
                        <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">getattr</span><span class="p">(</span><span class="n">file_name</span><span class="p">,</span> <span class="s1">&#39;template&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span> <span class="n">Template</span><span class="p">):</span>
                            <span class="n">t</span> <span class="o">=</span> <span class="n">file_name</span><span class="o">.</span><span class="n">template</span>
                        <span class="k">elif</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">file_name</span><span class="p">,</span> <span class="n">six</span><span class="o">.</span><span class="n">string_types</span><span class="p">)</span> <span class="ow">and</span> <span class="n">is_iterable</span><span class="p">(</span><span class="n">file_name</span><span class="p">):</span>
                            <span class="n">t</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">template</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">select_template</span><span class="p">(</span><span class="n">file_name</span><span class="p">)</span>
                        <span class="k">else</span><span class="p">:</span>
                            <span class="n">t</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">template</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="n">file_name</span><span class="p">)</span>
                        <span class="n">context</span><span class="o">.</span><span class="n">render_context</span><span class="p">[</span><span class="bp">self</span><span class="p">]</span> <span class="o">=</span> <span class="n">t</span>
                    <span class="n">new_context</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">_dict</span><span class="p">)</span>
                    <span class="c1"># Copy across the CSRF token, if present, because</span>
                    <span class="c1"># inclusion tags are often used for forms, and we need</span>
                    <span class="c1"># instructions for using CSRF protection to be as simple</span>
                    <span class="c1"># as possible.</span>
                    <span class="n">csrf_token</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;csrf_token&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
                    <span class="k">if</span> <span class="n">csrf_token</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                        <span class="n">new_context</span><span class="p">[</span><span class="s1">&#39;csrf_token&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">csrf_token</span>
                    <span class="k">return</span> <span class="n">t</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">new_context</span><span class="p">)</span>

            <span class="n">function_name</span> <span class="o">=</span> <span class="p">(</span><span class="n">name</span> <span class="ow">or</span>
                <span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s1">&#39;_decorated_function&#39;</span><span class="p">,</span> <span class="n">func</span><span class="p">)</span><span class="o">.</span><span class="n">__name__</span><span class="p">)</span>
            <span class="n">compile_func</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="n">generic_tag_compiler</span><span class="p">,</span>
                <span class="n">params</span><span class="o">=</span><span class="n">params</span><span class="p">,</span> <span class="n">varargs</span><span class="o">=</span><span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span><span class="o">=</span><span class="n">varkw</span><span class="p">,</span>
                <span class="n">defaults</span><span class="o">=</span><span class="n">defaults</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">function_name</span><span class="p">,</span>
                <span class="n">takes_context</span><span class="o">=</span><span class="n">takes_context</span><span class="p">,</span> <span class="n">node_class</span><span class="o">=</span><span class="n">InclusionNode</span><span class="p">)</span>
            <span class="n">compile_func</span><span class="o">.</span><span class="n">__doc__</span> <span class="o">=</span> <span class="n">func</span><span class="o">.</span><span class="n">__doc__</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">tag</span><span class="p">(</span><span class="n">function_name</span><span class="p">,</span> <span class="n">compile_func</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">func</span>
        <span class="k">return</span> <span class="n">dec</span>


<span class="k">def</span> <span class="nf">is_library_missing</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Check if library that failed to load cannot be found under any</span>
<span class="sd">    templatetags directory or does exist but fails to import.</span>

<span class="sd">    Non-existing condition is checked recursively for each subpackage in cases</span>
<span class="sd">    like &lt;appdir&gt;/templatetags/subpackage/package/module.py.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="c1"># Don&#39;t bother to check if &#39;.&#39; is in name since any name will be prefixed</span>
    <span class="c1"># with some template root.</span>
    <span class="n">path</span><span class="p">,</span> <span class="n">module</span> <span class="o">=</span> <span class="n">name</span><span class="o">.</span><span class="n">rsplit</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">package</span> <span class="o">=</span> <span class="n">import_module</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
        <span class="k">return</span> <span class="ow">not</span> <span class="n">module_has_submodule</span><span class="p">(</span><span class="n">package</span><span class="p">,</span> <span class="n">module</span><span class="p">)</span>
    <span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">is_library_missing</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">import_library</span><span class="p">(</span><span class="n">taglib_module</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Load a template tag library module.</span>

<span class="sd">    Verifies that the library contains a &#39;register&#39; attribute, and</span>
<span class="sd">    returns that attribute as the representation of the library</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">mod</span> <span class="o">=</span> <span class="n">import_module</span><span class="p">(</span><span class="n">taglib_module</span><span class="p">)</span>
    <span class="k">except</span> <span class="ne">ImportError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
        <span class="c1"># If the ImportError is because the taglib submodule does not exist,</span>
        <span class="c1"># that&#39;s not an error that should be raised. If the submodule exists</span>
        <span class="c1"># and raised an ImportError on the attempt to load it, that we want</span>
        <span class="c1"># to raise.</span>
        <span class="k">if</span> <span class="n">is_library_missing</span><span class="p">(</span><span class="n">taglib_module</span><span class="p">):</span>
            <span class="k">return</span> <span class="kc">None</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">InvalidTemplateLibrary</span><span class="p">(</span><span class="s2">&quot;ImportError raised loading </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span>
                                         <span class="p">(</span><span class="n">taglib_module</span><span class="p">,</span> <span class="n">e</span><span class="p">))</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">mod</span><span class="o">.</span><span class="n">register</span>
    <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
        <span class="k">raise</span> <span class="n">InvalidTemplateLibrary</span><span class="p">(</span><span class="s2">&quot;Template library </span><span class="si">%s</span><span class="s2"> does not have &quot;</span>
                                     <span class="s2">&quot;a variable named &#39;register&#39;&quot;</span> <span class="o">%</span>
                                     <span class="n">taglib_module</span><span class="p">)</span>


<span class="nd">@lru_cache</span><span class="o">.</span><span class="n">lru_cache</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">get_templatetags_modules</span><span class="p">():</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Return the list of all available template tag modules.</span>

<span class="sd">    Caches the result for faster access.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">templatetags_modules_candidates</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;django.templatetags&#39;</span><span class="p">]</span>
    <span class="n">templatetags_modules_candidates</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span>
        <span class="s1">&#39;</span><span class="si">%s</span><span class="s1">.templatetags&#39;</span> <span class="o">%</span> <span class="n">app_config</span><span class="o">.</span><span class="n">name</span>
        <span class="k">for</span> <span class="n">app_config</span> <span class="ow">in</span> <span class="n">apps</span><span class="o">.</span><span class="n">get_app_configs</span><span class="p">())</span>

    <span class="n">templatetags_modules</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">for</span> <span class="n">templatetag_module</span> <span class="ow">in</span> <span class="n">templatetags_modules_candidates</span><span class="p">:</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">import_module</span><span class="p">(</span><span class="n">templatetag_module</span><span class="p">)</span>
        <span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
            <span class="k">continue</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">templatetags_modules</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">templatetag_module</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">templatetags_modules</span>


<span class="k">def</span> <span class="nf">get_library</span><span class="p">(</span><span class="n">library_name</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Load the template library module with the given name.</span>

<span class="sd">    If library is not already loaded loop over all templatetags modules</span>
<span class="sd">    to locate it.</span>

<span class="sd">    {% load somelib %} and {% load someotherlib %} loops twice.</span>

<span class="sd">    Subsequent loads eg. {% load somelib %} in the same process will grab</span>
<span class="sd">    the cached module from libraries.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">lib</span> <span class="o">=</span> <span class="n">libraries</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">library_name</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">lib</span><span class="p">:</span>
        <span class="n">templatetags_modules</span> <span class="o">=</span> <span class="n">get_templatetags_modules</span><span class="p">()</span>
        <span class="n">tried_modules</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">module</span> <span class="ow">in</span> <span class="n">templatetags_modules</span><span class="p">:</span>
            <span class="n">taglib_module</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">%s</span><span class="s1">.</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">library_name</span><span class="p">)</span>
            <span class="n">tried_modules</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">taglib_module</span><span class="p">)</span>
            <span class="n">lib</span> <span class="o">=</span> <span class="n">import_library</span><span class="p">(</span><span class="n">taglib_module</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">lib</span><span class="p">:</span>
                <span class="n">libraries</span><span class="p">[</span><span class="n">library_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">lib</span>
                <span class="k">break</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">lib</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">InvalidTemplateLibrary</span><span class="p">(</span><span class="s2">&quot;Template library </span><span class="si">%s</span><span class="s2"> not found, &quot;</span>
                                         <span class="s2">&quot;tried </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span>
                                         <span class="p">(</span><span class="n">library_name</span><span class="p">,</span>
                                          <span class="s1">&#39;,&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">tried_modules</span><span class="p">)))</span>
    <span class="k">return</span> <span class="n">lib</span>


<span class="k">def</span> <span class="nf">add_to_builtins</span><span class="p">(</span><span class="n">module</span><span class="p">):</span>
    <span class="n">builtins</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">import_library</span><span class="p">(</span><span class="n">module</span><span class="p">))</span>


<span class="n">add_to_builtins</span><span class="p">(</span><span class="s1">&#39;django.template.defaulttags&#39;</span><span class="p">)</span>
<span class="n">add_to_builtins</span><span class="p">(</span><span class="s1">&#39;django.template.defaultfilters&#39;</span><span class="p">)</span>
<span class="n">add_to_builtins</span><span class="p">(</span><span class="s1">&#39;django.template.loader_tags&#39;</span><span class="p">)</span>
</pre></div>

          </div>
        </div>
      </div>
      
        
          <div class="yui-b" id="sidebar">
            
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3>Browse</h3>
  <ul>
    
    
  </ul>
  <h3>You are here:</h3>
  <ul>
      <li>
        <a href="../../../index.html">Django 1.8.19 documentation</a>
        
          <ul><li><a href="../../index.html">Module code</a>
        
          <ul><li><a href="../../django.html">django</a>
        
        <ul><li>django.template.base</li></ul>
        </li></ul></li></ul>
      </li>
  </ul>

<div id="searchbox" style="display: none" role="search">
  <h3>Quick search</h3>
    <form class="search" action="../../../search.html" method="get">
      <div><input type="text" name="q" /></div>
      <div><input type="submit" value="Go" /></div>
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
              <h3>Last update:</h3>
              <p class="topless">Mar 10, 2018</p>
          </div>
        
      
    </div>

    <div id="ft">
      <div class="nav">
    <a href="../../index.html" title="Module code" accesskey="U">up</a></div>
    </div>
  </div>

      <div class="clearer"></div>
    </div>
  </body>
</html>