1
0
mirror of https://github.com/django/django.git synced 2025-10-26 15:16:09 +00:00

Fixed #35816 -- Handled parsing of scientific notation in DTL. (#19213)

* Refs #35816 -- Improved test coverage of FilterExpression.

* Fixed #35816 -- Made FilterExpression parse scientific numbers.

---------

Co-authored-by: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com>
This commit is contained in:
haileyajohnson
2025-03-11 00:02:27 -07:00
committed by GitHub
parent 8df5ce80d2
commit 5183f7c287
2 changed files with 71 additions and 4 deletions

View File

@@ -11,6 +11,7 @@ from django.template.base import (
Token,
TokenType,
Variable,
VariableDoesNotExist,
)
from django.template.defaultfilters import register as filter_library
from django.test import SimpleTestCase
@@ -72,6 +73,27 @@ class ParserTests(SimpleTestCase):
with self.assertRaisesMessage(TemplateSyntaxError, msg):
FilterExpression("article._hidden|upper", p)
def test_cannot_parse_characters(self):
p = Parser("", builtins=[filter_library])
for filter_expression, characters in [
('<>|default:"Default"|upper', '|<>||default:"Default"|upper'),
("test|<>|upper", "test||<>||upper"),
]:
with self.subTest(filter_expression=filter_expression):
with self.assertRaisesMessage(
TemplateSyntaxError,
f"Could not parse some characters: {characters}",
):
FilterExpression(filter_expression, p)
def test_cannot_find_variable(self):
p = Parser("", builtins=[filter_library])
with self.assertRaisesMessage(
TemplateSyntaxError,
'Could not find variable at start of |default:"Default"',
):
FilterExpression('|default:"Default"', p)
def test_variable_parsing(self):
c = {"article": {"section": "News"}}
self.assertEqual(Variable("article.section").resolve(c), "News")
@@ -148,3 +170,49 @@ class ParserTests(SimpleTestCase):
'1|two_one_opt_arg:"1"',
):
FilterExpression(expr, parser)
def test_filter_numeric_argument_parsing(self):
p = Parser("", builtins=[filter_library])
cases = {
"5": 5,
"-5": -5,
"5.2": 5.2,
".4": 0.4,
"5.2e3": 5200.0, # 5.2 × 10³ = 5200.0.
"5.2E3": 5200.0, # Case-insensitive.
"5.2e-3": 0.0052, # Negative exponent.
"-1.5E4": -15000.0,
"+3.0e2": 300.0,
".5e2": 50.0, # 0.5 × 10² = 50.0
}
for num, expected in cases.items():
with self.subTest(num=num):
self.assertEqual(FilterExpression(num, p).resolve({}), expected)
self.assertEqual(
FilterExpression(f"0|default:{num}", p).resolve({}), expected
)
invalid_numbers = [
"abc123",
"123abc",
"foo",
"error",
"1e",
"e400",
"1e.2",
"1e2.",
"1e2.0",
"1e2a",
"1e2e3",
"1e-",
"1e-a",
]
for num in invalid_numbers:
with self.subTest(num=num):
self.assertIsNone(
FilterExpression(num, p).resolve({}, ignore_failures=True)
)
with self.assertRaises(VariableDoesNotExist):
FilterExpression(f"0|default:{num}", p).resolve({})