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

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

66 statements  

1"""Built-in template tests used with the ``is`` operator.""" 

2 

3import operator 

4import typing as t 

5from collections import abc 

6from numbers import Number 

7 

8from .runtime import Undefined 

9from .utils import pass_environment 

10 

11if t.TYPE_CHECKING: 

12 from .environment import Environment 

13 

14 

15def test_odd(value: int) -> bool: 

16 """Return true if the variable is odd.""" 

17 return value % 2 == 1 

18 

19 

20def test_even(value: int) -> bool: 

21 """Return true if the variable is even.""" 

22 return value % 2 == 0 

23 

24 

25def test_divisibleby(value: int, num: int) -> bool: 

26 """Check if a variable is divisible by a number.""" 

27 return value % num == 0 

28 

29 

30def test_defined(value: t.Any) -> bool: 

31 """Return true if the variable is defined: 

32 

33 .. sourcecode:: jinja 

34 

35 {% if variable is defined %} 

36 value of variable: {{ variable }} 

37 {% else %} 

38 variable is not defined 

39 {% endif %} 

40 

41 See the :func:`default` filter for a simple way to set undefined 

42 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_environment 

53def test_filter(env: "Environment", value: str) -> bool: 

54 """Check if a filter exists by name. Useful if a filter may be 

55 optionally available. 

56 

57 .. code-block:: jinja 

58 

59 {% if 'markdown' is filter %} 

60 {{ value | markdown }} 

61 {% else %} 

62 {{ value }} 

63 {% endif %} 

64 

65 .. versionadded:: 3.0 

66 """ 

67 return value in env.filters 

68 

69 

70@pass_environment 

71def test_test(env: "Environment", value: str) -> bool: 

72 """Check if a test exists by name. Useful if a test may be 

73 optionally available. 

74 

75 .. code-block:: jinja 

76 

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.0 

88 """ 

89 return value in env.tests 

90 

91 

92def test_none(value: t.Any) -> bool: 

93 """Return true if the variable is none.""" 

94 return value is None 

95 

96 

97def test_boolean(value: t.Any) -> bool: 

98 """Return true if the object is a boolean value. 

99 

100 .. versionadded:: 2.11 

101 """ 

102 return value is True or value is False 

103 

104 

105def test_false(value: t.Any) -> bool: 

106 """Return true if the object is False. 

107 

108 .. versionadded:: 2.11 

109 """ 

110 return value is False 

111 

112 

113def test_true(value: t.Any) -> bool: 

114 """Return true if the object is True. 

115 

116 .. versionadded:: 2.11 

117 """ 

118 return value is True 

119 

120 

121# NOTE: The existing 'number' test matches booleans and floats 

122def test_integer(value: t.Any) -> bool: 

123 """Return true if the object is an integer. 

124 

125 .. versionadded:: 2.11 

126 """ 

127 return isinstance(value, int) and value is not True and value is not False 

128 

129 

130# NOTE: The existing 'number' test matches booleans and integers 

131def test_float(value: t.Any) -> bool: 

132 """Return true if the object is a float. 

133 

134 .. versionadded:: 2.11 

135 """ 

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.6 

158 """ 

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 variables 

169 that are iterable. 

170 """ 

171 try: 

172 len(value) 

173 value.__getitem__ # noqa B018 

174 except Exception: 

175 return False 

176 

177 return True 

178 

179 

180def test_sameas(value: t.Any, other: t.Any) -> bool: 

181 """Check if an object points to the same memory address than another 

182 object: 

183 

184 .. sourcecode:: jinja 

185 

186 {% if foo.attribute is sameas false %} 

187 the foo attribute really is the `False` singleton 

188 {% endif %} 

189 """ 

190 return value is other 

191 

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 False 

199 

200 return True 

201 

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.10 

212 """ 

213 return value in seq 

214 

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}