I have
<%! from __future__ import division %>
at the very top of my template file. I get the error:
SyntaxError: from __future__ imports must occur at the beginning of the file
What's the correct way to do this?
I have
<%! from __future__ import division %>
at the very top of my template file. I get the error:
SyntaxError: from __future__ imports must occur at the beginning of the file
What's the correct way to do this?
You cannot use from __future__ import
statements in Mako templates. At all.
This is because a Mako template is compiled to a python file, and in order for this to work it sets up some initial structures at the top of that python file:
# -*- encoding:ascii -*- from mako import runtime, filters, cache UNDEFINED = runtime.UNDEFINED __M_dict_builtin = dict __M_locals_builtin = locals _magic_number = 7 _modified_time = 1348257499.1626351 _template_filename = '/tmp/mako.txt' _template_uri = '/tmp/mako.txt' _source_encoding = 'ascii' _exports = []
Only after this initial setup is any code from the template itself included. Your from __future__ import division
will never be placed first.
You can still use floating point division by casting either operand of the /
division operator to a float:
>>> 1 / 2 0 >>> float(1) / 2 0.5
As long as you follow that workaround you can do fine without the division
future import.
Importing from __future__
would be tidy, but I can't think of how to make it work (maybe someone who's more familiar with Mako's internals can). Martijn explains why it isn't possible. I can suggest a couple of work around though.
If possible, do the division outside of the the template and put the result in the Context. This aligns with my personal preference to keep as much logic out of the template as possible.
If that's not an option there's the hacky solution, convert your operands to floats. If you need to do this division in a bunch of different places you can add a function in a module level block:
<%! def div(a, b): return float(a) / float(b) %>
Definitely less elegant than what you had in mind, but it'll work.