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