In Pyyaml, how to represent empty strings and lists in block style?

十年热恋 提交于 2019-12-11 01:38:10

问题


I have added representers for folded strings, literal strings as mentioned in Any yaml libraries in Python that support dumping of long strings as block literals or folded blocks?. I have also added representer to print a list in block style in the dumped yaml content.

But the issue is that when the string is empty, i.e., "" or the list is empty, they appear in non-block style in the dumped YAML content.

How do force the pyyaml dumper to output "" empty strings with ">" or "|" style and empty list with flow_style=False in a block style in the generated YAML content?


回答1:


After a bit of research, I am able to dump empty strings as block literals (style in '|>') in a YAML file using Pyyaml. My work is partially based on Any yaml libraries in Python that support dumping of long strings as block literals or folded blocks?.

import yaml
from yaml.emitter import Emitter, ScalarAnalysis

class MyEmitter(Emitter):  
    def analyze_scalar(self, scalar):   
        # Empty scalar is a special case.
        # By default, pyyaml sets allow_block=False
        # I override this to set allow_block=True
        if not scalar:         
            return ScalarAnalysis(scalar=scalar, empty=True, multiline=False,
                allow_flow_plain=False, allow_block_plain=True,
                allow_single_quoted=True, allow_double_quoted=True,
                allow_block=True)   
        return super(MyEmitter, self).analyze_scalar(scalar)

# And I subclass MyDumper from MyEmitter and yaml.Dumper        
class MyDumper(yaml.Dumper, MyEmitter):
    pass
class folded_unicode(unicode): pass
class literal_unicode(unicode): pass

def folded_unicode_representer(dumper, data):
    return dumper.represent_scalar(u'tag:yaml.org,2002:str', data, style='>')
def literal_unicode_representer(dumper, data):
    return dumper.represent_scalar(u'tag:yaml.org,2002:str', data, style='|')

yaml.add_representer(folded_unicode, folded_unicode_representer)
yaml.add_representer(literal_unicode, literal_unicode_representer)

# I test it now
d = {'foo': {'folded': folded_unicode(''), 'literal': literal_unicode('')}}
print yaml.dump(d, Dumper=MyDumper)

Output:

foo:
  folded: >
  literal: |

However, I am not able to find a way to dump an empty list in block style. For this, I tried to mess with yaml/emitter.py and realized that I needed a non-empty list to dump it in block style.

Anyways, this effort did not go in vain, rather it was quite exciting :) I hope that some one may find this useful or may have something to share.



来源:https://stackoverflow.com/questions/10882401/in-pyyaml-how-to-represent-empty-strings-and-lists-in-block-style

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!