pythonyamlruamel.yaml

is CommentedMap.keys() in ruamel.yaml keeping the insertion order?


I am trying to check some internal yaml files, and "fix" them. For that I need to preserve the comments, so I decided to use ruamel.yaml library.

The thing is that one of the checks is that some "keys", if present, are in a certain order. So for example:

settings:
  # foo
  key2:
    prop: value
  # bar
  key1:
    prop: value
  ...

I need to "fix" it, like this:

settings:
  # bar
  key1:
    prop: value
  # foo
  key2:
    prop: value
  ...

but in order to check first the correct "order", I am wondering if I do the following:

yaml = YAML()
yaml.preserve_quotes = True
file: CommentedMap = yaml.load(path)
settings: Any = file.get("settings", default=[])
if not isinstance(linters, CommentedMap):
    return
keys: list[str] = list(settings.keys())
# are keys keeping the insertion order?
...

keys will keep the insertion order.

Thanks.


Solution

  • The CommentedMap that you load from your YAML document is a subclass of ordereddict and that is (nowadays) a subclass of collections.OrdereDict with an added .insert() method.

    The .keys() method is somewhat intransparent, as it returns a CommentedMapKeysView() which is a subclass of a type that holds a reference to the original CommentedMap. Iterating over it will yield the keys in the order of their insertion in the CommentedMap.

    So yes the keys are keeping the insertion order.

    Although it might be true for your input that keys is of type list[str] but in YAML any scalar or collection can be a key for a mapping. ruamel.yaml will load and round-trip e.g. :

    [2011, 10, 2]: anniversary