Search code examples
pythonyamlpython-3.5quotesdouble-quotes

Python Dump YAML Using Double Quotes Around Strings


In Python 3.5, I have the following dictionary to be dumped into a .yaml file.

D={'name': 'mydata', value: {'x': 1, 'y': 2, 'z':3}}

When I run the following code:

import ruamel
import ruamel.yaml as yaml
D={'name': 'mydata', 'value': {'x': 1, 'y': 2, 'z':3}}
yaml.round_trip_dump(D, open('my_yaml.yaml', 'w'),
                     default_flow_style=False, indent=4)

The resulting my_yaml.yaml looks like the following:

name: mydata                                                                    
value:                                                                     
    z: 3                                                                     
    x: 1                                                                   
    y: 2

My question is, is there a handy way to write double quotes around mydata, i.e., instead of name: mydata, it is written as name: "mydata"


Solution

  • There is a relatively easy way to do this:

    import sys
    import ruamel.yaml
    
    S = ruamel.yaml.scalarstring.DoubleQuotedScalarString
    D = {'name': S('mydata'), 'value': {'x': 1, 'y': 2, 'z':3}}
    
    yaml = ruamel.yaml.YAML()
    yaml.indent(mapping=4)
    yaml.dump(D, sys.stdout)
    

    that last three lines, using an instance of YAML, is the newer way of doing:

    ruamel.yaml.round_trip_dump(D, sys.stdout, indent=4)
    

    Using the new API, you can give a different indent value for your sequences.

    Either way, the above gives you:

    name: "mydata"
    value:
        x: 1
        y: 2
        z: 3
    

    There is no need to explicitly do default_flow_style=False when using ruamel.yamls round-trip-mode.


    The DoubleQuotedScalarString, a subclass of str, is what is used to store "mydata" if you load your preferred output, while preserving quotes:

    yaml.preserve_quotes = True
    data = yaml.load("""\
    name: "mydata"
    value:
        x: 1
        y: 2
        z: 3
    """)
    print(type(data['name']))
    

    gives:

    <class 'ruamel.yaml.scalarstring.DoubleQuotedScalarString'>
    

    If your output round-trips correctly, it is always a good idea to inspect the data structure ruamel.yaml loads, whether it is for double quotes, block style literal scalars, hexadecimal ints or comment preservation.
    The library does a lot behind the scenes for which there is no documentation, and the library's author is probably too lazy to provide more of it.