import operator
import typing as t
from collections import abc
from numbers import Number
from .runtime import Undefined
from .utils import pass_environment
if t.TYPE_CHECKING:
from .environment import Environment
def test_odd(value: int) -> bool:
return value % 2 == 1
def test_even(value: int) -> bool:
return value % 2 == 0
def test_divisibleby(value: int, num: int) -> bool:
return value % num == 0
def test_defined(value: t.Any) -> bool:
return not isinstance(value, Undefined)
def test_undefined(value: t.Any) -> bool:
return isinstance(value, Undefined)
@pass_environment
def test_filter(env: "Environment", value: str) -> bool:
return value in env.filters
@pass_environment
def test_test(env: "Environment", value: str) -> bool:
return value in env.tests
def test_none(value: t.Any) -> bool:
return value is None
def test_boolean(value: t.Any) -> bool:
return value is True or value is False
def test_false(value: t.Any) -> bool:
return value is False
def test_true(value: t.Any) -> bool:
return value is True
def test_integer(value: t.Any) -> bool:
return isinstance(value, int) and value is not True and value is not False
def test_float(value: t.Any) -> bool:
return isinstance(value, float)
def test_lower(value: str) -> bool:
return str(value).islower()
def test_upper(value: str) -> bool:
return str(value).isupper()
def test_string(value: t.Any) -> bool:
return isinstance(value, str)
def test_mapping(value: t.Any) -> bool:
return isinstance(value, abc.Mapping)
def test_number(value: t.Any) -> bool:
return isinstance(value, Number)
def test_sequence(value: t.Any) -> bool:
try:
len(value)
value.__getitem__
except Exception:
return False
return True
def test_sameas(value: t.Any, other: t.Any) -> bool:
return value is other
def test_iterable(value: t.Any) -> bool:
try:
iter(value)
except TypeError:
return False
return True
def test_escaped(value: t.Any) -> bool:
return hasattr(value, "__html__")
def test_in(value: t.Any, seq: t.Container) -> bool:
return value in seq
TESTS = {
"odd": test_odd,
"even": test_even,
"divisibleby": test_divisibleby,
"defined": test_defined,
"undefined": test_undefined,
"filter": test_filter,
"test": test_test,
"none": test_none,
"boolean": test_boolean,
"false": test_false,
"true": test_true,
"integer": test_integer,
"float": test_float,
"lower": test_lower,
"upper": test_upper,
"string": test_string,
"mapping": test_mapping,
"number": test_number,
"sequence": test_sequence,
"iterable": test_iterable,
"callable": callable,
"sameas": test_sameas,
"escaped": test_escaped,
"in": test_in,
"==": operator.eq,
"eq": operator.eq,
"equalto": operator.eq,
"!=": operator.ne,
"ne": operator.ne,
">": operator.gt,
"gt": operator.gt,
"greaterthan": operator.gt,
"ge": operator.ge,
">=": operator.ge,
"<": operator.lt,
"lt": operator.lt,
"lessthan": operator.lt,
"<=": operator.le,
"le": operator.le,
}