Python yaml.dump плохой отступ

Я выполняю следующий код python:

import yaml


foo = {
    'name': 'foo',
    'my_list': [{'foo': 'test', 'bar': 'test2'}, {'foo': 'test3', 'bar': 'test4'}],
    'hello': 'world'
}

print(yaml.dump(foo, default_flow_style=False))

но печатает:

hello: world
my_list:
- bar: test2
  foo: test
- bar: test4
  foo: test3
name: foo

вместо:

hello: world
my_list:
  - bar: test2
    foo: test
  - bar: test4
    foo: test3
name: foo

любое представление о том, почему элементы my_list не имеют отступов хорошо?

Спасибо

Ответ 1

Этот билет предполагает, что текущая реализация корректно следует spec:

"-", "?" и символы ":", используемые для обозначения записей коллекции блоков, воспринимаются людьми как часть отступа. Это обрабатывается в каждом конкретном случае соответствующими производствами.

В той же теме есть этот фрагмент кода (измененный в соответствии с вашим примером), чтобы получить поведение, которое вы ищете:

import yaml

class MyDumper(yaml.Dumper):

    def increase_indent(self, flow=False, indentless=False):
        return super(MyDumper, self).increase_indent(flow, False)

foo = {
    'name': 'foo',
    'my_list': [
        {'foo': 'test', 'bar': 'test2'},
        {'foo': 'test3', 'bar': 'test4'}],
    'hello': 'world',
}

print yaml.dump(foo, Dumper=MyDumper, default_flow_style=False)

Ответ 2

Если это помогает, я написал код для решения одной и той же проблемы. Просто передайте исходный вывод из yaml.dump() в _fix_dump().

import re
from cStringIO import StringIO

def _fix_dump(dump, indentSize=2):
    stream = StringIO(dump)
    out = StringIO()
    pat = re.compile('(\s*)([^:]*)(:*)')
    last = None

    prefix = 0
    for s in stream:    
        indent, key, colon = pat.match(s).groups()
        if indent=="" and key[0]!= '-':
            prefix = 0
        if last:
            if len(last[0])==len(indent) and last[2]==':':
                if all([
                        not last[1].startswith('-'), 
                        s.strip().startswith('-')
                        ]):
                    prefix += indentSize
        out.write(" "*prefix+s)
        last = indent, key, colon
    return out.getvalue()