This commit is contained in:
Augusto Pontes 2025-11-17 13:45:10 +01:00 committed by GitHub
commit 3098b052a6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 38 additions and 3 deletions

View file

@ -65,6 +65,7 @@ from django.utils.safestring import SafeData, SafeString, mark_safe
from django.utils.text import get_text_list, smart_split, unescape_string_literal
from django.utils.timezone import template_localtime
from django.utils.translation import gettext_lazy, pgettext_lazy
from django.utils.version import PY314
from .exceptions import TemplateSyntaxError
@ -92,6 +93,9 @@ tag_re = re.compile(r"({%.*?%}|{{.*?}}|{#.*?#})")
logger = logging.getLogger("django.template")
if PY314:
import annotationlib
class TokenType(Enum):
TEXT = 0
@ -825,9 +829,19 @@ class FilterExpression:
# Check to see if a decorator is providing the real function.
func = inspect.unwrap(func)
args, _, _, defaults, _, _, _ = inspect.getfullargspec(func)
alen = len(args)
dlen = len(defaults or [])
if PY314:
sig = inspect.signature(
func, annotation_format=annotationlib.Format.FORWARDREF
)
else:
sig = inspect.signature(func)
alen = len(sig.parameters)
non_default_params = [
p for p in sig.parameters.values() if p.default is p.empty
]
dlen = alen - len(non_default_params)
# Not enough OR Too many
if plen < (alen - dlen) or plen > alen:
raise TemplateSyntaxError(

View file

@ -3,6 +3,9 @@ Testing some internals of the template processing.
These are *not* examples to be copied in user code.
"""
import unittest
from typing import TYPE_CHECKING
from django.template import Library, TemplateSyntaxError
from django.template.base import (
FilterExpression,
@ -15,6 +18,10 @@ from django.template.base import (
)
from django.template.defaultfilters import register as filter_library
from django.test import SimpleTestCase
from django.utils.version import PY314
if TYPE_CHECKING:
from django.utils.safestring import SafeText
class ParserTests(SimpleTestCase):
@ -240,3 +247,17 @@ class ParserTests(SimpleTestCase):
FilterExpression(num, p).resolve({})
with self.assertRaises(TemplateSyntaxError):
FilterExpression(f"0|default:{num}", p).resolve({})
@unittest.skipUnless(PY314, "Deferred annotations are Python 3.14+ only")
def test_register_filter_deferred_annotations(self):
register = Library()
@register.filter("example")
def example_filter(value: str, arg: str = "default") -> SafeText:
return f"{value}_{arg}"
result = FilterExpression.args_check(
"example", example_filter, ["extra_example"]
)
self.assertTrue(result)