Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/jinja2/tests.py: 70%

66 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2023-09-25 06:15 +0000

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[t.Any]) -> 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}