jinja2.tests

Built-in template tests used with the is operator.

  1"""Built-in template tests used with the ``is`` operator."""
  2import operator
  3import typing as t
  4from collections import abc
  5from numbers import Number
  6
  7from .runtime import Undefined
  8from .utils import pass_environment
  9
 10if t.TYPE_CHECKING:
 11    from .environment import Environment
 12
 13
 14def test_odd(value: int) -> bool:
 15    """Return true if the variable is odd."""
 16    return value % 2 == 1
 17
 18
 19def test_even(value: int) -> bool:
 20    """Return true if the variable is even."""
 21    return value % 2 == 0
 22
 23
 24def test_divisibleby(value: int, num: int) -> bool:
 25    """Check if a variable is divisible by a number."""
 26    return value % num == 0
 27
 28
 29def test_defined(value: t.Any) -> bool:
 30    """Return true if the variable is defined:
 31
 32    .. sourcecode:: jinja
 33
 34        {% if variable is defined %}
 35            value of variable: {{ variable }}
 36        {% else %}
 37            variable is not defined
 38        {% endif %}
 39
 40    See the :func:`default` filter for a simple way to set undefined
 41    variables.
 42    """
 43    return not isinstance(value, Undefined)
 44
 45
 46def test_undefined(value: t.Any) -> bool:
 47    """Like :func:`defined` but the other way round."""
 48    return isinstance(value, Undefined)
 49
 50
 51@pass_environment
 52def test_filter(env: "Environment", value: str) -> bool:
 53    """Check if a filter exists by name. Useful if a filter may be
 54    optionally available.
 55
 56    .. code-block:: jinja
 57
 58        {% if 'markdown' is filter %}
 59            {{ value | markdown }}
 60        {% else %}
 61            {{ value }}
 62        {% endif %}
 63
 64    .. versionadded:: 3.0
 65    """
 66    return value in env.filters
 67
 68
 69@pass_environment
 70def test_test(env: "Environment", value: str) -> bool:
 71    """Check if a test exists by name. Useful if a test may be
 72    optionally available.
 73
 74    .. code-block:: jinja
 75
 76        {% if 'loud' is test %}
 77            {% if value is loud %}
 78                {{ value|upper }}
 79            {% else %}
 80                {{ value|lower }}
 81            {% endif %}
 82        {% else %}
 83            {{ value }}
 84        {% endif %}
 85
 86    .. versionadded:: 3.0
 87    """
 88    return value in env.tests
 89
 90
 91def test_none(value: t.Any) -> bool:
 92    """Return true if the variable is none."""
 93    return value is None
 94
 95
 96def test_boolean(value: t.Any) -> bool:
 97    """Return true if the object is a boolean value.
 98
 99    .. versionadded:: 2.11
100    """
101    return value is True or value is False
102
103
104def test_false(value: t.Any) -> bool:
105    """Return true if the object is False.
106
107    .. versionadded:: 2.11
108    """
109    return value is False
110
111
112def test_true(value: t.Any) -> bool:
113    """Return true if the object is True.
114
115    .. versionadded:: 2.11
116    """
117    return value is True
118
119
120# NOTE: The existing 'number' test matches booleans and floats
121def test_integer(value: t.Any) -> bool:
122    """Return true if the object is an integer.
123
124    .. versionadded:: 2.11
125    """
126    return isinstance(value, int) and value is not True and value is not False
127
128
129# NOTE: The existing 'number' test matches booleans and integers
130def test_float(value: t.Any) -> bool:
131    """Return true if the object is a float.
132
133    .. versionadded:: 2.11
134    """
135    return isinstance(value, float)
136
137
138def test_lower(value: str) -> bool:
139    """Return true if the variable is lowercased."""
140    return str(value).islower()
141
142
143def test_upper(value: str) -> bool:
144    """Return true if the variable is uppercased."""
145    return str(value).isupper()
146
147
148def test_string(value: t.Any) -> bool:
149    """Return true if the object is a string."""
150    return isinstance(value, str)
151
152
153def test_mapping(value: t.Any) -> bool:
154    """Return true if the object is a mapping (dict etc.).
155
156    .. versionadded:: 2.6
157    """
158    return isinstance(value, abc.Mapping)
159
160
161def test_number(value: t.Any) -> bool:
162    """Return true if the variable is a number."""
163    return isinstance(value, Number)
164
165
166def test_sequence(value: t.Any) -> bool:
167    """Return true if the variable is a sequence. Sequences are variables
168    that are iterable.
169    """
170    try:
171        len(value)
172        value.__getitem__
173    except Exception:
174        return False
175
176    return True
177
178
179def test_sameas(value: t.Any, other: t.Any) -> bool:
180    """Check if an object points to the same memory address than another
181    object:
182
183    .. sourcecode:: jinja
184
185        {% if foo.attribute is sameas false %}
186            the foo attribute really is the `False` singleton
187        {% endif %}
188    """
189    return value is other
190
191
192def test_iterable(value: t.Any) -> bool:
193    """Check if it's possible to iterate over an object."""
194    try:
195        iter(value)
196    except TypeError:
197        return False
198
199    return True
200
201
202def test_escaped(value: t.Any) -> bool:
203    """Check if the value is escaped."""
204    return hasattr(value, "__html__")
205
206
207def test_in(value: t.Any, seq: t.Container) -> bool:
208    """Check if value is in seq.
209
210    .. versionadded:: 2.10
211    """
212    return value in seq
213
214
215TESTS = {
216    "odd": test_odd,
217    "even": test_even,
218    "divisibleby": test_divisibleby,
219    "defined": test_defined,
220    "undefined": test_undefined,
221    "filter": test_filter,
222    "test": test_test,
223    "none": test_none,
224    "boolean": test_boolean,
225    "false": test_false,
226    "true": test_true,
227    "integer": test_integer,
228    "float": test_float,
229    "lower": test_lower,
230    "upper": test_upper,
231    "string": test_string,
232    "mapping": test_mapping,
233    "number": test_number,
234    "sequence": test_sequence,
235    "iterable": test_iterable,
236    "callable": callable,
237    "sameas": test_sameas,
238    "escaped": test_escaped,
239    "in": test_in,
240    "==": operator.eq,
241    "eq": operator.eq,
242    "equalto": operator.eq,
243    "!=": operator.ne,
244    "ne": operator.ne,
245    ">": operator.gt,
246    "gt": operator.gt,
247    "greaterthan": operator.gt,
248    "ge": operator.ge,
249    ">=": operator.ge,
250    "<": operator.lt,
251    "lt": operator.lt,
252    "lessthan": operator.lt,
253    "<=": operator.le,
254    "le": operator.le,
255}
def test_odd(value: int) -> bool:
15def test_odd(value: int) -> bool:
16    """Return true if the variable is odd."""
17    return value % 2 == 1

Return true if the variable is odd.

def test_even(value: int) -> bool:
20def test_even(value: int) -> bool:
21    """Return true if the variable is even."""
22    return value % 2 == 0

Return true if the variable is even.

def test_divisibleby(value: int, num: int) -> bool:
25def test_divisibleby(value: int, num: int) -> bool:
26    """Check if a variable is divisible by a number."""
27    return value % num == 0

Check if a variable is divisible by a number.

def test_defined(value: Any) -> bool:
30def test_defined(value: t.Any) -> bool:
31    """Return true if the variable is defined:
32
33    .. sourcecode:: jinja
34
35        {% if variable is defined %}
36            value of variable: {{ variable }}
37        {% else %}
38            variable is not defined
39        {% endif %}
40
41    See the :func:`default` filter for a simple way to set undefined
42    variables.
43    """
44    return not isinstance(value, Undefined)

Return true if the variable is defined:

.. sourcecode:: jinja

{% if variable is defined %}
    value of variable: {{ variable }}
{% else %}
    variable is not defined
{% endif %}

See the default() filter for a simple way to set undefined variables.

def test_undefined(value: Any) -> bool:
47def test_undefined(value: t.Any) -> bool:
48    """Like :func:`defined` but the other way round."""
49    return isinstance(value, Undefined)

Like defined() but the other way round.

@pass_environment
def test_filter(env: jinja2.environment.Environment, value: str) -> bool:
52@pass_environment
53def test_filter(env: "Environment", value: str) -> bool:
54    """Check if a filter exists by name. Useful if a filter may be
55    optionally available.
56
57    .. code-block:: jinja
58
59        {% if 'markdown' is filter %}
60            {{ value | markdown }}
61        {% else %}
62            {{ value }}
63        {% endif %}
64
65    .. versionadded:: 3.0
66    """
67    return value in env.filters

Check if a filter exists by name. Useful if a filter may be optionally available.

{% if 'markdown' is filter %}
    {{ value | markdown }}
{% else %}
    {{ value }}
{% endif %}

New in version 3.0.

@pass_environment
def test_test(env: jinja2.environment.Environment, value: str) -> bool:
70@pass_environment
71def test_test(env: "Environment", value: str) -> bool:
72    """Check if a test exists by name. Useful if a test may be
73    optionally available.
74
75    .. code-block:: jinja
76
77        {% if 'loud' is test %}
78            {% if value is loud %}
79                {{ value|upper }}
80            {% else %}
81                {{ value|lower }}
82            {% endif %}
83        {% else %}
84            {{ value }}
85        {% endif %}
86
87    .. versionadded:: 3.0
88    """
89    return value in env.tests

Check if a test exists by name. Useful if a test may be optionally available.

{% if 'loud' is test %}
    {% if value is loud %}
        {{ value|upper }}
    {% else %}
        {{ value|lower }}
    {% endif %}
{% else %}
    {{ value }}
{% endif %}

New in version 3.0.

def test_none(value: Any) -> bool:
92def test_none(value: t.Any) -> bool:
93    """Return true if the variable is none."""
94    return value is None

Return true if the variable is none.

def test_boolean(value: Any) -> bool:
 97def test_boolean(value: t.Any) -> bool:
 98    """Return true if the object is a boolean value.
 99
100    .. versionadded:: 2.11
101    """
102    return value is True or value is False

Return true if the object is a boolean value.

New in version 2.11.

def test_false(value: Any) -> bool:
105def test_false(value: t.Any) -> bool:
106    """Return true if the object is False.
107
108    .. versionadded:: 2.11
109    """
110    return value is False

Return true if the object is False.

New in version 2.11.

def test_true(value: Any) -> bool:
113def test_true(value: t.Any) -> bool:
114    """Return true if the object is True.
115
116    .. versionadded:: 2.11
117    """
118    return value is True

Return true if the object is True.

New in version 2.11.

def test_integer(value: Any) -> bool:
122def test_integer(value: t.Any) -> bool:
123    """Return true if the object is an integer.
124
125    .. versionadded:: 2.11
126    """
127    return isinstance(value, int) and value is not True and value is not False

Return true if the object is an integer.

New in version 2.11.

def test_float(value: Any) -> bool:
131def test_float(value: t.Any) -> bool:
132    """Return true if the object is a float.
133
134    .. versionadded:: 2.11
135    """
136    return isinstance(value, float)

Return true if the object is a float.

New in version 2.11.

def test_lower(value: str) -> bool:
139def test_lower(value: str) -> bool:
140    """Return true if the variable is lowercased."""
141    return str(value).islower()

Return true if the variable is lowercased.

def test_upper(value: str) -> bool:
144def test_upper(value: str) -> bool:
145    """Return true if the variable is uppercased."""
146    return str(value).isupper()

Return true if the variable is uppercased.

def test_string(value: Any) -> bool:
149def test_string(value: t.Any) -> bool:
150    """Return true if the object is a string."""
151    return isinstance(value, str)

Return true if the object is a string.

def test_mapping(value: Any) -> bool:
154def test_mapping(value: t.Any) -> bool:
155    """Return true if the object is a mapping (dict etc.).
156
157    .. versionadded:: 2.6
158    """
159    return isinstance(value, abc.Mapping)

Return true if the object is a mapping (dict etc.).

New in version 2.6.

def test_number(value: Any) -> bool:
162def test_number(value: t.Any) -> bool:
163    """Return true if the variable is a number."""
164    return isinstance(value, Number)

Return true if the variable is a number.

def test_sequence(value: Any) -> bool:
167def test_sequence(value: t.Any) -> bool:
168    """Return true if the variable is a sequence. Sequences are variables
169    that are iterable.
170    """
171    try:
172        len(value)
173        value.__getitem__
174    except Exception:
175        return False
176
177    return True

Return true if the variable is a sequence. Sequences are variables that are iterable.

def test_sameas(value: Any, other: Any) -> bool:
180def test_sameas(value: t.Any, other: t.Any) -> bool:
181    """Check if an object points to the same memory address than another
182    object:
183
184    .. sourcecode:: jinja
185
186        {% if foo.attribute is sameas false %}
187            the foo attribute really is the `False` singleton
188        {% endif %}
189    """
190    return value is other

Check if an object points to the same memory address than another object:

.. sourcecode:: jinja

{% if foo.attribute is sameas false %}
    the foo attribute really is the `False` singleton
{% endif %}
def test_iterable(value: Any) -> bool:
193def test_iterable(value: t.Any) -> bool:
194    """Check if it's possible to iterate over an object."""
195    try:
196        iter(value)
197    except TypeError:
198        return False
199
200    return True

Check if it's possible to iterate over an object.

def test_escaped(value: Any) -> bool:
203def test_escaped(value: t.Any) -> bool:
204    """Check if the value is escaped."""
205    return hasattr(value, "__html__")

Check if the value is escaped.

def test_in(value: Any, seq: Container) -> bool:
208def test_in(value: t.Any, seq: t.Container) -> bool:
209    """Check if value is in seq.
210
211    .. versionadded:: 2.10
212    """
213    return value in seq

Check if value is in seq.

New in version 2.10.

TESTS = {'odd': <function test_odd>, 'even': <function test_even>, 'divisibleby': <function test_divisibleby>, 'defined': <function test_defined>, 'undefined': <function test_undefined>, 'filter': <function test_filter>, 'test': <function test_test>, 'none': <function test_none>, 'boolean': <function test_boolean>, 'false': <function test_false>, 'true': <function test_true>, 'integer': <function test_integer>, 'float': <function test_float>, 'lower': <function test_lower>, 'upper': <function test_upper>, 'string': <function test_string>, 'mapping': <function test_mapping>, 'number': <function test_number>, 'sequence': <function test_sequence>, 'iterable': <function test_iterable>, 'callable': <built-in function callable>, 'sameas': <function test_sameas>, 'escaped': <function test_escaped>, 'in': <function test_in>, '==': <built-in function eq>, 'eq': <built-in function eq>, 'equalto': <built-in function eq>, '!=': <built-in function ne>, 'ne': <built-in function ne>, '>': <built-in function gt>, 'gt': <built-in function gt>, 'greaterthan': <built-in function gt>, 'ge': <built-in function ge>, '>=': <built-in function ge>, '<': <built-in function lt>, 'lt': <built-in function lt>, 'lessthan': <built-in function lt>, '<=': <built-in function le>, 'le': <built-in function le>}