Hi everyone!

I have this macro in jinja2 template to generate xml configs:

{%- macro print_opts(options, indent='  ', count=0) %}
{% for key in options.keys() | sort %}
  {% set value = options[key] %}
  {% if value is string %}
    {{- indent*count }}{{ key }} {{ '"' + value.split('\t') | join('" "') + 
'"' }}
  {% elif value in [true, false] %}
    {{- indent*count }}{{ key }} {{ value | lower }}
  {% elif value is number %}
    {{- indent*count }}{{ key }} {{ value }}
  {% elif value is mapping %}
    {{- indent*count }}<{{ key }}>
    {{ print_opts(value, indent, count+1) -}}
    {{- indent*count }}</{{ key.split()[0] }}>
  {% elif value is sequence %}
    {% for i in value | sort -%}
      {{ print_opts({key: i}, indent, count) -}}
    {%- endfor %}
  {% else %}
    {{- indent*count }}{{ key }} "{{ value }}"
  {% endif %}
{% endfor %}
{% endmacro %}

This macro works good with Python2 but I need to add support for Python3 
also.
The problem is that Python3 has some differences in comparison of 
dictionaries and fails when I have a list of dicts here:

  {% elif value is sequence %}
    {% for i in value | sort -%}
      {{ print_opts({key: i}, indent, count) -}}
    {%- endfor %}

unorderable types: dict() < dict()"}

I've tried to create a custom sort filter using original jinja  sort filter
from jinja2._compat import string_types
from operator import itemgetter

def environmentfilter(f):
       f.environmentfilter = True
    return f

@environmentfilter
def do_sort(environment, value, reverse=False, case_sensitive=False,
           attribute=None):

    if not case_sensitive:
        def sort_func(item):
            if isinstance(item, string_types):
                item = item.lower()
            return item
    else:
        sort_func = None

    if attribute is not None:
        getter = make_attrgetter(environment, attribute)
        def sort_func(item, processor=sort_func or (lambda x: x)):
            return processor(getter(item))

    print(type(value))
    if isinstance(value, list) and isinstance(value[0], dict):
        return sorted(value, key=lambda x:sorted(x.keys()), reverse=reverse)
    else:
        return sorted(value, key=sort_func, reverse=reverse)

class FilterModule(object):
    '''
    custom jinja2 sort filter
    '''

    def filters(self):
        return {
            'sort2': do_sort
        }


but something wrong here, seems it works for python2 but not for python3 - 
sorting doesn't work here - output file has random order after each ansible 
running and changed each time.

Maybe someone will advise some other solutions to make this macro work on 
both versions

Thanks!

-- 
You received this message because you are subscribed to the Google Groups 
"Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to ansible-project+unsubscr...@googlegroups.com.
To post to this group, send email to ansible-project@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/ansible-project/8417e20d-3f56-44af-ab31-5b048b7a8c58%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to