How get the sequences properly indented with ruamel.yaml?
Asked Answered
A

1

17

With the following data

from ruamel import yaml
data = {1: {1:[{1:1,2:2},{1:1,2:2}], 2:2}, 2: 42}

I get an incorrect indentation for the sequence

>>> print yaml.round_trip_dump(data)
1:
  1:
  - 1: 1
    2: 2
  - 1: 1
    2: 2
  2: 2
2: 42

Which cannot be folded on Notepad++. However with the proper indent it works:

Bad:

Bad Indent

Good:

Good Indent

I have tried to use block_seq_indent=2:

>>> print yaml.round_trip_dump(data, block_seq_indent=2)
1:
  1:
    - 1: 1
    2: 2
    - 1: 1
    2: 2
  2: 2
2: 42

How can I solve this issue?

Ashly answered 6/6, 2017 at 11:21 Comment(0)
N
26

The ruamel.yaml documentation, although generally lacking, says the following about offset of the dash within the indent:

If the offset equals sequence, there is not enough room for the dash and the space that has to follow it. In that case the element itself would normally be pushed to the next line (and older versions of ruamel.yaml did so). But this is prevented from happening. However the indent level is what is used for calculating the cumulative indent for deeper levels and specifying sequence=3 resp. offset=2, might give correct, but counter intuitive results.

It is best to always have sequence >= offset + 2 but this is not enforced. Depending on your structure, not following this advice might lead to invalid output.

By default indent (both for mappings and for sequences) equals 2, if you do:

import sys
from ruamel import yaml

data = {1: {1:[{1:1,2:2},{1:1,2:2}], 2:2}, 2: 42}

yml = yaml.YAML()
yml.indent(mapping=2, sequence=4, offset=2)
yml.dump(data, sys.stdout)

you get:

1:
  1:
    - 1: 1
      2: 2
    - 1: 1
      2: 2
  2: 2
2: 42

With the old API, that you use in your question, you cannot do the different indent for mappings and sequences in a trivial way (you need to subclass the Emitter, and on post __init__ of the base class, set the values). And with older versions of ruamel.yaml this was not possible at all.

This only works with the default (round-trip, i.e. typ='rt') dumper, but does work with both the normal Python dict resp. list (e.g. from YAML(typ='safe').load(....)) and the more convulated subclasses thereof used when doing YAML().load(....)

(the above requires ruamel.yaml>=0.15.30)

Needlepoint answered 6/6, 2017 at 11:43 Comment(3)
Unfortunately with a indent of 4 I cannot use notepad++ to fold my YAML. That said the YAML specification recommend an indent of 2Ashly
With the updated .indent() you should be able to get this to work.Needlepoint
Thank you for specifying "with the default dumper". Spent quite some time wondering why changing the configuration of my safe YAML class wasn't working.Hippodrome

© 2022 - 2024 — McMap. All rights reserved.