leforestier/yattag

attributes order

jan-spurny opened this issue · 1 comments

I run into a problem when porting our software from python2 to python3 - there are unittests which just compare html output (str) of yattag to stored html files - and now all these tests started to fail because html attributes in yattag are represented by dict, so in python3 versions prior to 3.7 (I think), final attribute order is randomized, which results in failing tests. For example:

$ cat example.py 
from yattag import Doc

doc, tag, text = Doc().tagtext()
with tag('html'):
    with tag('body'):
        doc.attr(klass = 'foo', a = 'bar', b = 'baz')
print(doc.getvalue())

$ python example.py 
<html><body a="bar" b="baz" class="foo"></body></html>
$ python example.py 
<html><body a="bar" class="foo" b="baz"></body></html>
$ python example.py 
<html><body b="baz" a="bar" class="foo"></body></html>
$ python example.py 
<html><body class="foo" b="baz" a="bar"></body></html>

Would it be possible to add something like order_attrs: bool=False optional parameter to Doc.get_value() or something similar to make order (and therefore resulting text) predictable?

Hi Jan,
yes, only from Python 3.6 is the order of keyword arguments preserved.
Not much we can do about that. But you can change how you test. Have a look at how I wrote the tests here: https://github.com/leforestier/yattag/blob/master/test/tests_simpledoc.py
I used xml.etree.ElementTree to parse the strings returned by getvalue(). You could do the same: parse the resulting strings and check that the attributes of the nodes are the attributes you expect.