Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I control the formatting of multiline strings?

Tags:

The following code:

from ruamel.yaml import YAML
import sys, textwrap

yaml = YAML()
yaml.default_flow_style = False
yaml.dump({
    'hello.py': textwrap.dedent("""\
        import sys
        sys.stdout.write("hello world")
    """)
}, sys.stdout)

produces:

hello.py: "import sys\nsys.stdout.write(\"hello world\")\n"

is there a way to make it produce:

hello.py: |
    import sys
    sys.stdout.write("hello world")

instead?

Versions:

python: 2.7.16 on Win10 (1903)
ruamel.ordereddict==0.4.14
ruamel.yaml==0.16.0
ruamel.yaml.clib==0.1.0
like image 447
thebjorn Avatar asked Aug 06 '19 19:08

thebjorn


People also ask

How does Python handle multiline strings?

Multiline Strings with Triple Quotes A multiline string in Python begins and ends with either three single quotes or three double quotes. Any quotes, tabs, or newlines in between the “triple quotes” are considered part of the string. Python's indentation rules for blocks do not apply to lines inside a multiline string.

Are multi line strings allowed in JSON?

Now you can store multi-line strings in JSON.

What are the two ways in which multiline strings can be created?

There are three ways to create strings that span multiple lines: By using template literals. By using the + operator – the JavaScript concatenation operator. By using the \ operator – the JavaScript backslash operator and escape character.


1 Answers

If you load, then dump, your expected output, you'll see that ruamel.yaml can actually preserve the block style literal scalar.

import sys
import ruamel.yaml

yaml_str = """\
hello.py: |
    import sys
    sys.stdout.write("hello world")
"""

yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

as this gives again the loaded input:

hello.py: |
  import sys
  sys.stdout.write("hello world")

To find out how it does that you should inspect the type of your multi-line string:

print(type(data['hello.py']))

which prints:

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

and that should point you in the right direction:

from ruamel.yaml import YAML
from ruamel.yaml.scalarstring import LiteralScalarString
import sys, textwrap

def LS(s):
    return LiteralScalarString(textwrap.dedent(s))


yaml = ruamel.yaml.YAML()
yaml.dump({
    'hello.py': LS("""\
        import sys
        sys.stdout.write("hello world")
    """)
}, sys.stdout)

which also outputs what you want:

hello.py: |
  import sys
  sys.stdout.write("hello world")
like image 104
Anthon Avatar answered Sep 28 '22 10:09

Anthon