You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
4.1 KiB

4 years ago
  1. # -*- coding: utf-8 -*-
  2. """
  3. jinja2.tests
  4. ~~~~~~~~~~~~
  5. Jinja test functions. Used with the "is" operator.
  6. :copyright: (c) 2017 by the Jinja Team.
  7. :license: BSD, see LICENSE for more details.
  8. """
  9. import operator
  10. import re
  11. from collections import Mapping
  12. from jinja2.runtime import Undefined
  13. from jinja2._compat import text_type, string_types, integer_types
  14. import decimal
  15. number_re = re.compile(r'^-?\d+(\.\d+)?$')
  16. regex_type = type(number_re)
  17. test_callable = callable
  18. def test_odd(value):
  19. """Return true if the variable is odd."""
  20. return value % 2 == 1
  21. def test_even(value):
  22. """Return true if the variable is even."""
  23. return value % 2 == 0
  24. def test_divisibleby(value, num):
  25. """Check if a variable is divisible by a number."""
  26. return value % num == 0
  27. def test_defined(value):
  28. """Return true if the variable is defined:
  29. .. sourcecode:: jinja
  30. {% if variable is defined %}
  31. value of variable: {{ variable }}
  32. {% else %}
  33. variable is not defined
  34. {% endif %}
  35. See the :func:`default` filter for a simple way to set undefined
  36. variables.
  37. """
  38. return not isinstance(value, Undefined)
  39. def test_undefined(value):
  40. """Like :func:`defined` but the other way round."""
  41. return isinstance(value, Undefined)
  42. def test_none(value):
  43. """Return true if the variable is none."""
  44. return value is None
  45. def test_lower(value):
  46. """Return true if the variable is lowercased."""
  47. return text_type(value).islower()
  48. def test_upper(value):
  49. """Return true if the variable is uppercased."""
  50. return text_type(value).isupper()
  51. def test_string(value):
  52. """Return true if the object is a string."""
  53. return isinstance(value, string_types)
  54. def test_mapping(value):
  55. """Return true if the object is a mapping (dict etc.).
  56. .. versionadded:: 2.6
  57. """
  58. return isinstance(value, Mapping)
  59. def test_number(value):
  60. """Return true if the variable is a number."""
  61. return isinstance(value, integer_types + (float, complex, decimal.Decimal))
  62. def test_sequence(value):
  63. """Return true if the variable is a sequence. Sequences are variables
  64. that are iterable.
  65. """
  66. try:
  67. len(value)
  68. value.__getitem__
  69. except:
  70. return False
  71. return True
  72. def test_sameas(value, other):
  73. """Check if an object points to the same memory address than another
  74. object:
  75. .. sourcecode:: jinja
  76. {% if foo.attribute is sameas false %}
  77. the foo attribute really is the `False` singleton
  78. {% endif %}
  79. """
  80. return value is other
  81. def test_iterable(value):
  82. """Check if it's possible to iterate over an object."""
  83. try:
  84. iter(value)
  85. except TypeError:
  86. return False
  87. return True
  88. def test_escaped(value):
  89. """Check if the value is escaped."""
  90. return hasattr(value, '__html__')
  91. def test_in(value, seq):
  92. """Check if value is in seq.
  93. .. versionadded:: 2.10
  94. """
  95. return value in seq
  96. TESTS = {
  97. 'odd': test_odd,
  98. 'even': test_even,
  99. 'divisibleby': test_divisibleby,
  100. 'defined': test_defined,
  101. 'undefined': test_undefined,
  102. 'none': test_none,
  103. 'lower': test_lower,
  104. 'upper': test_upper,
  105. 'string': test_string,
  106. 'mapping': test_mapping,
  107. 'number': test_number,
  108. 'sequence': test_sequence,
  109. 'iterable': test_iterable,
  110. 'callable': test_callable,
  111. 'sameas': test_sameas,
  112. 'escaped': test_escaped,
  113. 'in': test_in,
  114. '==': operator.eq,
  115. 'eq': operator.eq,
  116. 'equalto': operator.eq,
  117. '!=': operator.ne,
  118. 'ne': operator.ne,
  119. '>': operator.gt,
  120. 'gt': operator.gt,
  121. 'greaterthan': operator.gt,
  122. 'ge': operator.ge,
  123. '>=': operator.ge,
  124. '<': operator.lt,
  125. 'lt': operator.lt,
  126. 'lessthan': operator.lt,
  127. '<=': operator.le,
  128. 'le': operator.le,
  129. }