Opened 7 years ago

Closed 6 years ago

#28721 closed Bug (fixed)

Cannot use the variable name "inf" in templates

Reported by: Fraser Nevett Owned by: Levi Payne
Component: Template system Version: 1.11
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

Trying to render a template variable named inf does not work:

>>> from django.template import Template, Context
>>> Template('{{ inf }}').render(Context({'inf': 'xxx'}))
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/tmp/venv/lib/python2.7/site-packages/django/template/base.py", line 191, in __init__
    self.nodelist = self.compile_nodelist()
  File "/tmp/venv/lib/python2.7/site-packages/django/template/base.py", line 233, in compile_nodelist
    e.template_debug = self.get_exception_info(e, e.token)
AttributeError: 'exceptions.OverflowError' object has no attribute 'token'

It also fails if the variable is undefined in the context:

>>> Template('{{ inf }}').render(Context())
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/tmp/venv/lib/python2.7/site-packages/django/template/base.py", line 191, in __init__
    self.nodelist = self.compile_nodelist()
  File "/tmp/venv/lib/python2.7/site-packages/django/template/base.py", line 233, in compile_nodelist
    e.template_debug = self.get_exception_info(e, e.token)
AttributeError: 'exceptions.OverflowError' object has no attribute 'token'

This is happening because 'inf' is used in Python to represent infinity:

>>> float('inf')
inf

The problem appears to be with this bit of the code:

            # First try to treat this variable as a number.
            #
            # Note that this could cause an OverflowError here that we're not
            # catching. Since this should only happen at compile time, that's
            # probably OK.
            self.literal = float(var)

            # So it's a float... is it an int? If the original value contained a
            # dot or an "e" then it was a float, not an int.
            if '.' not in var and 'e' not in var.lower():
                self.literal = int(self.literal)

It successfully converts the string 'inf' to a float with value of infinity, but then trying to convert this float to an int causes the OverflowError:

>>> int(float('inf'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: cannot convert float infinity to integer

Python also supports floats of '-inf' and 'nan'. Using '-inf' as a template variable name doesn't work because it isn't a valid variable name. Using 'nan' as a template variable name works OK:

>>> Template('{{ nan }}').render(Context({'nan': 'xxx'}))
u'xxx'

I think the fix is to allow variables named inf, rather than to support using inf as a float literal within templates.

Change History (9)

comment:1 by Tim Graham, 7 years ago

Triage Stage: UnreviewedAccepted

comment:2 by Levi Payne, 7 years ago

Owner: changed from nobody to Levi Payne
Status: newassigned

comment:4 by Levi Payne, 7 years ago

Has patch: set

comment:5 by Levi Payne, 7 years ago

Pull Request is ready for review.

comment:6 by Tim Graham, 7 years ago

Patch needs improvement: set

comment:7 by Fraser Nevett, 7 years ago

See also #28730

comment:8 by Tim Graham <timograham@…>, 6 years ago

In 6c31042:

Refs #28721 -- Added test for variations of 'inf'/'infinity' as a template variable names.

Fixed by 9ec7d8e514e09636b0ab4bcac74b5f7a5be335a3.

comment:9 by Tim Graham, 6 years ago

Resolution: fixed
Status: assignedclosed
Note: See TracTickets for help on using tickets.
Back to Top