Deprecate `..` in template variable lookups?

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?

2 Likes

Agreed. It doesn’t seem at all useful to do the empty string lookup there. :thinking:

The feature here is skipping undeclared variables, which is commonly done. I can’t think that folks would be deliberately leveraging this example of it though. So +1.

2 Likes

I am not sure we’ll see more responses here, so I went ahead and made a ticket: #35738 (Deprecate double-dot variable lookups) – Django .

1 Like