Invalid output from round-trip dumper with block_seq_indent and mappings within list items

Issue #164 invalid
Mike Kazantsev
created an issue
#!/usr/bin/env python3

import os, sys, io
import ruamel.yaml

yaml_str = '''
some-list:
  - item-map-A:
      map-A-key1:
      map-A-key2:
    item-map-B:
    item-map-C:
'''

yaml = ruamel.yaml.YAML(pure=True)
yaml.block_seq_indent = 2
with io.StringIO(yaml_str) as src: data = yaml.load(src)
yaml.dump(data, sys.stdout)

output:

some-list:
  - item-map-A:
    map-A-key1:
    map-A-key2:
  item-map-B:
  item-map-C:

expected output:

some-list:
  - item-map-A:
      map-A-key1:
      map-A-key2:
    item-map-B:
    item-map-C:

Workarounds:

  • Do not use block_seq_indent.

Versions:

  • ruamel.yaml version: 0.15.34
  • python sys.version: 3.6.2 (default, Jul 20 2017, 03:52:27) \n[GCC 7.1.1 20170630]

Comments (5)

  1. Ruamel/Anthon van der Neut repo owner

    There are a few problems here.

    Your source has a different indent for the sequences (4 positions with an offset for the dash of 2) and the indent for mappings is only 2 positions. Until recently you could not even have different indents on output for sequences and mappings, but nowadays you can.

    The default indent is 2, and as the documentation has indicated for a very long time, you need to have your indent at least two bigger than the block_seq_indent. With the change to allow control over sequence and mapping indents separately the exact wording has changed a bit but it was always explicitly warning that:

    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.

    In your case sequence is 2 (the default) and offset is 2 (as you set it, default would be 0).

    If you set the indent for sequences to 4 and for mappings to 2 as well your output will be as expected:

    import os, sys
    import ruamel.yaml
    
    yaml_str = """\
    some-list:
      - item-map-A:
          map-A-key1:
          map-A-key2:
        item-map-B:
        item-map-C:
    """
    
    yaml = ruamel.yaml.YAML(pure=True)
    yaml.indent(mapping=2, sequence=4, offset=2)
    data = yaml.load(yaml_str)
    yaml.dump(data, sys.stdout)
    
  2. Mike Kazantsev reporter

    I apparently skipped this section of the docs and didn't realize indents in sequences should be counted not from "- " prefix but the value after it, which would probably also explain other some issues.

  3. Log in to comment