1"""Built-in template tests used with the ``is`` operator.""" 2import operator 3import re 4from collections import abc 5from numbers import Number 6 7from .runtime import Undefined 8 9number_re = re.compile(r"^-?\d+(\.\d+)?$") 10regex_type = type(number_re) 11test_callable = callable 12 13 14def test_odd(value): 15 """Return true if the variable is odd.""" 16 return value % 2 == 1 17 18 19def test_even(value): 20 """Return true if the variable is even.""" 21 return value % 2 == 0 22 23 24def test_divisibleby(value, num): 25 """Check if a variable is divisible by a number.""" 26 return value % num == 0 27 28 29def test_defined(value): 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): 47 """Like :func:`defined` but the other way round.""" 48 return isinstance(value, Undefined) 49 50 51def test_none(value): 52 """Return true if the variable is none.""" 53 return value is None 54 55 56def test_boolean(value): 57 """Return true if the object is a boolean value. 58 59 .. versionadded:: 2.11 60 """ 61 return value is True or value is False 62 63 64def test_false(value): 65 """Return true if the object is False. 66 67 .. versionadded:: 2.11 68 """ 69 return value is False 70 71 72def test_true(value): 73 """Return true if the object is True. 74 75 .. versionadded:: 2.11 76 """ 77 return value is True 78 79 80# NOTE: The existing 'number' test matches booleans and floats 81def test_integer(value): 82 """Return true if the object is an integer. 83 84 .. versionadded:: 2.11 85 """ 86 return isinstance(value, int) and value is not True and value is not False 87 88 89# NOTE: The existing 'number' test matches booleans and integers 90def test_float(value): 91 """Return true if the object is a float. 92 93 .. versionadded:: 2.11 94 """ 95 return isinstance(value, float) 96 97 98def test_lower(value): 99 """Return true if the variable is lowercased.""" 100 return str(value).islower() 101 102 103def test_upper(value): 104 """Return true if the variable is uppercased.""" 105 return str(value).isupper() 106 107 108def test_string(value): 109 """Return true if the object is a string.""" 110 return isinstance(value, str) 111 112 113def test_mapping(value): 114 """Return true if the object is a mapping (dict etc.). 115 116 .. versionadded:: 2.6 117 """ 118 return isinstance(value, abc.Mapping) 119 120 121def test_number(value): 122 """Return true if the variable is a number.""" 123 return isinstance(value, Number) 124 125 126def test_sequence(value): 127 """Return true if the variable is a sequence. Sequences are variables 128 that are iterable. 129 """ 130 try: 131 len(value) 132 value.__getitem__ 133 except Exception: 134 return False 135 return True 136 137 138def test_sameas(value, other): 139 """Check if an object points to the same memory address than another 140 object: 141 142 .. sourcecode:: jinja 143 144 {% if foo.attribute is sameas false %} 145 the foo attribute really is the `False` singleton 146 {% endif %} 147 """ 148 return value is other 149 150 151def test_iterable(value): 152 """Check if it's possible to iterate over an object.""" 153 try: 154 iter(value) 155 except TypeError: 156 return False 157 return True 158 159 160def test_escaped(value): 161 """Check if the value is escaped.""" 162 return hasattr(value, "__html__") 163 164 165def test_in(value, seq): 166 """Check if value is in seq. 167 168 .. versionadded:: 2.10 169 """ 170 return value in seq 171 172 173TESTS = { 174 "odd": test_odd, 175 "even": test_even, 176 "divisibleby": test_divisibleby, 177 "defined": test_defined, 178 "undefined": test_undefined, 179 "none": test_none, 180 "boolean": test_boolean, 181 "false": test_false, 182 "true": test_true, 183 "integer": test_integer, 184 "float": test_float, 185 "lower": test_lower, 186 "upper": test_upper, 187 "string": test_string, 188 "mapping": test_mapping, 189 "number": test_number, 190 "sequence": test_sequence, 191 "iterable": test_iterable, 192 "callable": test_callable, 193 "sameas": test_sameas, 194 "escaped": test_escaped, 195 "in": test_in, 196 "==": operator.eq, 197 "eq": operator.eq, 198 "equalto": operator.eq, 199 "!=": operator.ne, 200 "ne": operator.ne, 201 ">": operator.gt, 202 "gt": operator.gt, 203 "greaterthan": operator.gt, 204 "ge": operator.ge, 205 ">=": operator.ge, 206 "<": operator.lt, 207 "lt": operator.lt, 208 "lessthan": operator.lt, 209 "<=": operator.le, 210 "le": operator.le, 211} 212