'Jinja2 using numeric expressions in Template Expressions

I need to do something apparently very simple:

typedef enum {
    {% for e in mylist %}
    {{ e }} = 0x{{ '%04X' % (1 << loop.index0) }},
    {%- endfor %}
    ALL = 0x0FFF
} Sound_Region_t;

but this bombs with "jinja2.exceptions.TemplateSyntaxError: unexpected '<'"

Intention is to get something like:

typedef enum {
    foo = 0x0001,
    bar = 0x0002,
    fie = 0x0004,
    fom = 0x0008,
    ...,
    ALL = 0x0FFF
} Sound_Region_t;

I.e.: value is a "walking bit" so I can "bitwise or" together them. Same behavior if I try to use other variations including "{% with bit = 1 << loop.index %}" or similar.

What am I missing?



Solution 1:[1]

Jinja2 does not allow bitwise operators inside the templates, so we need to create a small global function that executes such operators and returns a number:

def leftshift(amount):
    return 1 << amount

# Get or create a Jinja2 environment
from jinja2 import Environment
env = Environment(...)

# Add leftshift function to the global context
env.globals['leftshift'] = leftshift

And in the templates now we can call leftshift function with the loop index:

typedef enum {
    {% for e in mylist %}
    {{ e }} = 0x{{ '{:04X}'.format(leftshift(loop.index0))}},
    {%- endfor %}
    ALL = 0x0FFF
} Sound_Region_t;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1