codekingpro/portable-devtools
114k
1"""Built-in template tests used with the ``is`` operator."""2 3import operator4import typing as t5from collections import abc6from numbers import Number7 8from .runtime import Undefined9from .utils import pass_environment10 11if t.TYPE_CHECKING:12 from .environment import Environment13 14 15def test_odd(value: int) -> bool:16 """Return true if the variable is odd."""17 return value % 2 == 118 19 20def test_even(value: int) -> bool:21 """Return true if the variable is even."""22 return value % 2 == 023 24 25def test_divisibleby(value: int, num: int) -> bool:26 """Check if a variable is divisible by a number."""27 return value % num == 028 29 30def test_defined(value: t.Any) -> bool:31 """Return true if the variable is defined:32 33 .. sourcecode:: jinja34 35 {% if variable is defined %}36 value of variable: {{ variable }}37 {% else %}38 variable is not defined39 {% endif %}40 41 See the :func:`default` filter for a simple way to set undefined42 variables.43 """44 return not isinstance(value, Undefined)45 46 47def test_undefined(value: t.Any) -> bool:48 """Like :func:`defined` but the other way round."""49 return isinstance(value, Undefined)50 51 52@pass_environment53def test_filter(env: "Environment", value: str) -> bool:54 """Check if a filter exists by name. Useful if a filter may be55 optionally available.56 57 .. code-block:: jinja58 59 {% if 'markdown' is filter %}60 {{ value | markdown }}61 {% else %}62 {{ value }}63 {% endif %}64 65 .. versionadded:: 3.066 """67 return value in env.filters68 69 70@pass_environment71def test_test(env: "Environment", value: str) -> bool:72 """Check if a test exists by name. Useful if a test may be73 optionally available.74 75 .. code-block:: jinja76 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.088 """89 return value in env.tests90 91 92def test_none(value: t.Any) -> bool:93 """Return true if the variable is none."""94 return value is None95 96 97def test_boolean(value: t.Any) -> bool:98 """Return true if the object is a boolean value.99 100 .. versionadded:: 2.11101 """102 return value is True or value is False103 104 105def test_false(value: t.Any) -> bool:106 """Return true if the object is False.107 108 .. versionadded:: 2.11109 """110 return value is False111 112 113def test_true(value: t.Any) -> bool:114 """Return true if the object is True.115 116 .. versionadded:: 2.11117 """118 return value is True119 120 121# NOTE: The existing 'number' test matches booleans and floats122def test_integer(value: t.Any) -> bool:123 """Return true if the object is an integer.124 125 .. versionadded:: 2.11126 """127 return isinstance(value, int) and value is not True and value is not False128 129 130# NOTE: The existing 'number' test matches booleans and integers131def test_float(value: t.Any) -> bool:132 """Return true if the object is a float.133 134 .. versionadded:: 2.11135 """136 return isinstance(value, float)137 138 139def test_lower(value: str) -> bool:140 """Return true if the variable is lowercased."""141 return str(value).islower()142 143 144def test_upper(value: str) -> bool:145 """Return true if the variable is uppercased."""146 return str(value).isupper()147 148 149def test_string(value: t.Any) -> bool:150 """Return true if the object is a string."""151 return isinstance(value, str)152 153 154def test_mapping(value: t.Any) -> bool:155 """Return true if the object is a mapping (dict etc.).156 157 .. versionadded:: 2.6158 """159 return isinstance(value, abc.Mapping)160 161 162def test_number(value: t.Any) -> bool:163 """Return true if the variable is a number."""164 return isinstance(value, Number)165 166 167def test_sequence(value: t.Any) -> bool:168 """Return true if the variable is a sequence. Sequences are variables169 that are iterable.170 """171 try:172 len(value)173 value.__getitem__ # noqa B018174 except Exception:175 return False176 177 return True178 179 180def test_sameas(value: t.Any, other: t.Any) -> bool:181 """Check if an object points to the same memory address than another182 object:183 184 .. sourcecode:: jinja185 186 {% if foo.attribute is sameas false %}187 the foo attribute really is the `False` singleton188 {% endif %}189 """190 return value is other191 192 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 False199 200 return True201 202 203def test_escaped(value: t.Any) -> bool:204 """Check if the value is escaped."""205 return hasattr(value, "__html__")206 207 208def test_in(value: t.Any, seq: t.Container[t.Any]) -> bool:209 """Check if value is in seq.210 211 .. versionadded:: 2.10212 """213 return value in seq214 215 216TESTS = {217 "odd": test_odd,218 "even": test_even,219 "divisibleby": test_divisibleby,220 "defined": test_defined,221 "undefined": test_undefined,222 "filter": test_filter,223 "test": test_test,224 "none": test_none,225 "boolean": test_boolean,226 "false": test_false,227 "true": test_true,228 "integer": test_integer,229 "float": test_float,230 "lower": test_lower,231 "upper": test_upper,232 "string": test_string,233 "mapping": test_mapping,234 "number": test_number,235 "sequence": test_sequence,236 "iterable": test_iterable,237 "callable": callable,238 "sameas": test_sameas,239 "escaped": test_escaped,240 "in": test_in,241 "==": operator.eq,242 "eq": operator.eq,243 "equalto": operator.eq,244 "!=": operator.ne,245 "ne": operator.ne,246 ">": operator.gt,247 "gt": operator.gt,248 "greaterthan": operator.gt,249 "ge": operator.ge,250 ">=": operator.ge,251 "<": operator.lt,252 "lt": operator.lt,253 "lessthan": operator.lt,254 "<=": operator.le,255 "le": operator.le,256}257 