Home > OS >  How to preserve format with yaml dump in python3
How to preserve format with yaml dump in python3

Time:04-08

I want to change only the attribute anotherName from the following yaml file with python.

test.yaml:

---
kind: test
scope: not far
spec:
  test1:
    options:
      - name: test.com
        anotherName: example.com
        empty: []
    groupOne: []
    emptyList:
      firstList: []
      secondList: []

Code (based on this answer)

import yaml
with open("test.yaml", 'r') as stream:
    try:
        loaded=yaml.safe_load(stream)
    except yaml.YAMLError as exc:
        print(exc)
    temp= loaded['spec']['test1']['options']
    for elem in temp:
        elem['anotherName']='somethingChanged'
with open("modified.yaml", 'w') as stream:
    try:
        yaml.dump(loaded, stream)
        print(loaded)
    except yaml.YAMLError as exc:
        print(exc)

The value has been changed, but the code change the order and the structure of the modified.yaml :

#First it misses the thre dashes
kind: test
scope: not far
spec:
  test1:
    emptyList:
      firstList: []
      secondList: []
    groupOne: []
    options:
    - anotherName: somethingChanged #then the order is changed
      empty: []
      name: test.com

CodePudding user response:

you can probably not force a specific output from pyyaml, but if you have such a specific requirement what you want to substitute, then why make the extra hassel of parsing the yml fromat at all. How about reading the file into a string and then making your replacement:

import re
# Here you would need to read the file content. I define it here
content="""
---
kind: test
scope: not far
spec:
  test1:
    options:
      - name: test.com
        anotherName: example.com
        empty: []
    groupOne: []
    emptyList:
      firstList: []
      secondList: []
"""
print(re.sub(r'anotherName: [^\n]*', 'anotherName: somethingChanged', content))

Output:

---
kind: test
scope: not far
spec:
  test1:
    options:
      - name: test.com
        anotherName: somethingChanged
        empty: []
    groupOne: []
    emptyList:
      firstList: []
      secondList: []

CodePudding user response:

If your version of PyYAML is higher than 5.1 you can use sort_keys argument to preserve the order. The only line that needs change is this one:

yaml.dump(loaded, stream, sort_keys=False)
  • Related