Search code examples
pythonmako

why an undefined variable is larger than a number in mako template?


I use a variable called x,the x is not defined, and use x to compare with a number in mako template:

 %if x>5:
    <h1>helloworld</h1>
 %endif

And why this sentence not cause an exception or an error? But when I want to print this out:

%if x>5:
    <h1>${x}</h1>
%endif

it caused an exception. Why?

This is in mako. Why can't I use this sentence in IPython? Because if I use an undefined variable in IPython, it will tell me variable is not defined suddenly.


Solution

  • That's because mako uses by default an Undefined object that only fails when rendered, but can be used in boolean expressions because implements the __nonzero__ method:

    class Undefined(object):
        """Represents an undefined value in a template.
    
        All template modules have a constant value 
        ``UNDEFINED`` present which is an instance of this
        object.
    
        """
        def __str__(self):
            raise NameError("Undefined")
        def __nonzero__(self):
            return False
    
    UNDEFINED = Undefined()
    

    To use an undefined value that fails even in boolean expressions, you can use strict_undefined argument as follows:

    >>> from mako.template import Template
    >>> mytemplate = Template("""%if x>5:
    ...     <h1>helloworld</h1>
    ... %endif""", strict_undefined=True)
    >>> mytemplate.render()
    ...
    NameError: 'x' is not defined
    

    Note that strict_undefined is available in both mako.template.Template and mako.lookup.TemplateLookup.

    The description from the documentation is:

    Replaces the automatic usage of UNDEFINED for any undeclared variables not located in the Context with an immediate raise of NameError. The advantage is immediate reporting of missing variables which include the name. New in 0.3.6.