5

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?

Hollister
  • 3,758
  • 2
  • 20
  • 22

2 Answers2

4

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.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Yes, I saw this from debugging (and that the error was on line 17), but Mike Bayer (techspot.zzzeek.org) is so smart, I thought he had an accommodation for it. Also, `division` isn't the only future import (`with` comes to mind). I was using `float()` before I tried this. – Hollister Sep 22 '12 at 01:59
  • You'd have to put in a feature request to have `from __future__ with` statements moved to the top of the python output for the template. But as such imports could alter the template scaffolding meaning itself too, I'm not certain that would be a good idea and accepted by Mike Bayer or the other Mako maintainers. – Martijn Pieters Sep 22 '12 at 06:07
0

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.

Community
  • 1
  • 1
Philip
  • 470
  • 1
  • 3
  • 11
  • The vast majority of my logic is in the views, but this case is some processing of each data row right before it's displayed, so I thought I would keep the code close to its use. I can always write a helper function and import it, but this would be tidy indeed. – Hollister Sep 22 '12 at 02:02