]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
clean up scientific notation support 922/head
authorDavid Lord <davidism@gmail.com>
Tue, 23 Jul 2019 15:19:51 +0000 (08:19 -0700)
committerDavid Lord <davidism@gmail.com>
Tue, 23 Jul 2019 15:19:51 +0000 (08:19 -0700)
add changelog
clean up docs
parametrize tests

CHANGES.rst
docs/templates.rst
jinja2/lexer.py
tests/test_lexnparse.py

index ae7f9d60143e1c281675d24eeb263957314613ac..0ee5324186c165725fe90c1d9f76a5fe186af5eb 100644 (file)
@@ -21,6 +21,8 @@ unreleased
 - Added a ``default`` parameter for the ``map`` filter. (`#557`_)
 -   Exclude environment globals from
     :func:`meta.find_undeclared_variables`. #931
+-   Float literals can be written with scientific notation, like
+    ``{{ 2.56e-3 }}``. #912, #922
 
 .. _#557: https://github.com/pallets/jinja/issues/557
 .. _#765: https://github.com/pallets/jinja/issues/765
index 9da057738cd8b32ab1dae000f5a6f7df2141a0c8..88df916745a3c40c2c81b228edf10bf18bae155d 100644 (file)
@@ -396,7 +396,7 @@ this template, it first locates the parent.  The extends tag should be the
 first tag in the template.  Everything before it is printed out normally and
 may cause confusion.  For details about this behavior and how to take
 advantage of it, see :ref:`null-master-fallback`. Also a block will always be
-filled in regardless of whether the surrounding condition is evaluated to be true 
+filled in regardless of whether the surrounding condition is evaluated to be true
 or false.
 
 The filename of the template depends on the template loader.  For example, the
@@ -1178,17 +1178,12 @@ for Python objects such as strings and numbers.  The following literals exist:
     template).
 
 42:
-    Integers numbers are created by just writing the number down. 
-    If a dot is present, the number will be considered a float, otherwise an
-    integer.  Keep in mind that, in Python, ``42`` and ``42.0``
-    are different (``int`` and ``float``, respectively).
-
-42.23 / 42e2 / 42E2 / 1e0:
-    Floating point numbers are created by just writing the
-    number down. Floating points can be written using the dot as a decimal mark,
-    or they can be written in scientific notation in which
-    case you can use lower case 'e' or upper case 'E' to indicate the exponent
-    part. 
+    Integers are whole numbers without a decimal part.
+
+42.23 / 42.1e2:
+    Floating point numbers can be written using a '.' as a decimal mark.
+    They can also be written in scientific notation with an upper or
+    lower case 'e' to indicate the exponent part.
 
 ['list', 'of', 'objects']:
     Everything between two brackets is a list.  Lists are useful for storing
index 119dc99dc8b3988662c4174312cfbaa9fbd403bc..d8812c9b9128e0fcc97b4a90b08ba5764fd6e91f 100644 (file)
@@ -15,6 +15,7 @@
     :license: BSD, see LICENSE for more details.
 """
 import re
+from ast import literal_eval
 from collections import deque
 from operator import itemgetter
 
@@ -22,8 +23,6 @@ from jinja2._compat import implements_iterator, intern, iteritems, text_type
 from jinja2.exceptions import TemplateSyntaxError
 from jinja2.utils import LRUCache
 
-from ast import literal_eval # to support scientific notation
-
 # cache for the lexers. Exists in order to be able to have multiple
 # environments with the same lexer
 _lexer_cache = LRUCache(50)
@@ -54,11 +53,7 @@ else:
     del jinja2._identifier
     del _identifier
 
-# Note: Float now supports 0 or 1 dots, and must thus be evaluated in the right 
-# order so that pure integers are caught first. Floats can now be written with 
-# scientific notation.
-float_re = re.compile(r'(?<!\.)\d+\.?\d+(?:e-?\d+)?', re.IGNORECASE)
-
+float_re = re.compile(r'(?<!\.)\d+(?:\.\d+)?(?:e[+\-]?\d+)?', re.IGNORECASE)
 newline_re = re.compile(r'(\r\n|\r|\n)')
 
 # internal the tokens and keep references to them
index f3adeb46f56902f624ca861421d35967cf019710..454a67b06471bce0d24a41ec8510d480a5cc3b37 100644 (file)
@@ -336,9 +336,36 @@ class TestSyntax(object):
         tmpl = env.from_string('{{ 1 in [1, 2, 3] }}|{{ 1 not in [1, 2, 3] }}')
         assert tmpl.render() == 'True|False'
 
-    def test_literals(self, env):
-        tmpl = env.from_string('{{ [] }}|{{ {} }}|{{ () }}')
-        assert tmpl.render().lower() == '[]|{}|()'
+    @pytest.mark.parametrize("value", ("[]", "{}", "()"))
+    def test_collection_literal(self, env, value):
+        t = env.from_string("{{ %s }}" % value)
+        assert t.render() == value
+
+    @pytest.mark.parametrize("value", ("1", "123"))
+    def test_int_literal(self, env, value):
+        t = env.from_string("{{ %s }}" % value)
+        assert t.render() == value
+
+    @pytest.mark.parametrize(
+        "value",
+        (
+            "1.2",
+            "34.56",
+            ("1e0", "1.0"),
+            ("10e1", "100.0"),
+            ("2.5e100", "2.5e+100"),
+            "2.5e+100",
+            ("25.6e-10", "2.56e-09"),
+        ),
+    )
+    def test_float_literal(self, env, value):
+        if isinstance(value, tuple):
+            value, expect = value
+        else:
+            expect = value
+
+        t = env.from_string("{{ %s }}" % value)
+        assert t.render() == expect
 
     def test_bool(self, env):
         tmpl = env.from_string('{{ true and false }}|{{ false '