Search code examples
pythonyamlpyyaml

python yaml load formatted string


I'm trying to load yaml that contains python formatted strings, e.g. test: {formatted_string}. This would allow me to format the string using dictionary["test"].format(formatted_string="hello yaml"), but when I load the yaml, it's automatically converted to {'test': {'formatted_string': None}} instead of {'test': '{formatted_string}'}.

There are dozens of .yaml files that are already formatted in this way.

I don't see this in the pyyaml docs or anywhere on SO.

Code in full for clarity:

import yaml


data = """
test: {formatted_string}
"""
d1 = yaml.load(data)
print(d1)
# {'test': {'formatted_string': None}}

d2 = {"test": "{formatted_string}"}
print(d2)
# {'test': '{formatted_string}'}

d2["test"] = d2["test"].format(formatted_string="hello yaml")
print(d2)
# {'test': 'hello yaml'}

Thanks!


Solution

  • The { character in YAML (as in JSON) introduces a dictionary. That is this:

    a_dictionary:
      key1: value1
      key2: value2
    

    Is completely equivalent to:

    a_dictionary: {key1: value1, key2: value2}
    

    So when you write...

    test: {formatted_string}
    

    ...the YAML parser things you are introducing a dictionary, and that it has a single key (formatted_string) and no value. If you want to use a { as part of a YAML value you need to quote it:

    test: "{formatted_string}"
    

    Compare:

    >>> yaml.safe_load('test: {formatted_string}')
    {'test': {'formatted_string': None}}
    >>> yaml.safe_load('test: "{formatted_string}"')
    {'test': '{formatted_string}'}
    

    In general, if you always quote your YAML strings your life will be easier :).