I made a mistake in a template last week, typing something like {{ book..title }}
instead of {{ book.title }}
. This went through the normal silent failure path for variable lookups, yielding the empty string:
In [1]: from django.template import Template, Context
In [2]: Template("{{ book..title }}").render(Context({"book": {"title": "I Choose You"}}))
Out[2]: ''
It took me a while to spot that extra dot and remove it.
Currently, Django’s Template Engine parses ..
as a lookup for the empty string, and then another lookup. So this works:
In [3]: Template("{{ book..title }}").render(Context({"book": {"": {"title": "I Choose You"}}}))
Out[3]: 'I Choose You'
That doesn’t seem particularly useful though.
Meanwhile, Jinja disallows ..
with a TemplateSyntaxError
:
In [4]: import jinja2
In [5]: jinja2.Template('{{ x..y }}').render({"x": {"y": 1}})
---------------------------------------------------------------------------
TemplateSyntaxError Traceback (most recent call last)
Cell In[5], line 1
----> 1 jinja2.Template('{{ x..y }}').render({"x": {"y": 1}})
...
File <unknown>:1, in template()
TemplateSyntaxError: expected name or number
I propose that we deprecate and remove support for ..
. I think we can do this in Variable.__init__
so the warning is raised at parse time:
diff --git django/template/base.py django/template/base.py
index 0f1eca58db..1b7bccef6f 100644
--- django/template/base.py
+++ django/template/base.py
@@ -842,6 +842,8 @@ def __init__(self, var):
"not begin with underscores: '%s'" % var
)
self.lookups = tuple(var.split(VARIABLE_ATTRIBUTE_SEPARATOR))
+ if "" in self.lookups:
+ warnings.warn("Uhhhhh no double dots plzzzz")
def resolve(self, context):
"""Resolve this variable against a given context."""
What do y’all think?