ruamel.yaml equivalent of sort_keys?
python, ruamel.yaml
Solution
You need some recursive function that handles mappings/dicts, sequence/list:
import sys
import ruamel.yaml
CM = ruamel.yaml.comments.CommentedMap
yaml = ruamel.yaml.YAML()
data = dict(a=1, c=dict(b=2, a=1), b=[2, dict(e=6, d=5), 4])
yaml.dump(data, sys.stdout)
def rec_sort(d):
try:
if isinstance(d, CM):
return d.sort()
except AttributeError:
pass
if isinstance(d, dict):
# could use dict in newer python versions
res = ruamel.yaml.CommentedMap()
for k in sorted(d.keys()):
res[k] = rec_sort(d[k])
return res
if isinstance(d, list):
for idx, elem in enumerate(d):
d[idx] = rec_sort(elem)
return d
print('---')
yaml.dump(rec_sort(data), sys.stdout)
which gives:
a: 1
c:
b: 2
a: 1
b:
- 2
- e: 6
d: 5
- 4
---
a: 1
b:
- 2
- d: 5
e: 6
- 4
c:
a: 1
b: 2
The commented map is the structure ruamel.yaml uses when doing a round-trip (load+dump) and round-tripping is designed to keep the keys in the order that they were during loading.
The above should do a reasonable job preserving comments on mappings/sequences when you load `data` from a commented YAML file
Problem
I'm trying to dump a Python dict to a YAML file using `ruamel.yaml`. I'm familiar with the `json` module's interface, where pretty-printing a dict is as simple as ``` import json with open('outfile.json', 'w') as f: json.dump(mydict, f, indent=4, sort_keys=True) ``` With `ruamel.yaml`, I've gotten as far as ``` import ruamel.yaml with open('outfile.yaml', 'w') as f: ruamel.yaml.round_trip_dump(mydict, f, indent=2) ``` but it doesn't seem to support the `sort_keys` option. `ruamel.yaml` also doesn't seem to have any exhaustive docs, and searching Google for "ruamel.yaml sort" or "ruamel.yaml alphabetize" didn't turn up anything at the level of simplicity I'd expect. Is there a one-or-two-liner for pretty-printing a YAML file with sorted keys? (Note that I need the keys to be alphabetized down through the whole container, recursively; just alphabetizing the top level is not good enough.) Notice that if I use `round_trip_dump`, the keys are not sorted; and if I use `safe_dump`, the output is not "YAML-style" (or more importantly "Kubernetes-style") YAML. I don't want `[]` or `{}` in my output. ``` $ pip freeze | grep yaml ruamel.yaml==0.12.5 $ python >>> import ruamel.yaml >>> mydict = {'a':1, 'b':[2,3,4], 'c':{'a':1,'b':2}} >>> print ruamel.yaml.round_trip_dump(mydict) # right format, wrong sorting a: 1 c: a: 1 b: 2 b: - 2 - 3 - 4 >>> print ruamel.yaml.safe_dump(mydict) # wrong format, right sorting a: 1 b: [2, 3, 4] c: {a: 1, b: 2} ```