Hollister
Hollister

Reputation: 3918

Using from __future__ import in Mako template

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?

Upvotes: 5

Views: 570

Answers (2)

Philip
Philip

Reputation: 470

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.

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1121644

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.

Upvotes: 4

Related Questions