Reputation: 79
I'm editing YAML file but it isn't giving the exact output as I want. There is a difference between indentation and square brackets.
import yaml
add_info = {'network':
{'version': 2,
'renderer': 'networkd',
'ethernets':
{'enx1':
{
'addresses': ['193.254.1.8/24'],
'nameservers': {'addresses':
['193.254.1.5, 8.8.8.8']},
'routes': [{
'to': '193.254.1.0/24',
'via': '193.254.1.5'
}]
}
}
}
}
with open('/etc/netplan/01-network-manager-test.yaml', 'w') as f:
data1 = yaml.dump(add_info, f, sort_keys=False)
print(data1)
Current Output I'm getting from above code.
network:
version: 2
renderer: networkd
ethernets:
enx1:
addresses:
- 193.254.1.8/24
nameservers:
addresses:
- 193.254.1.5, 8.8.8.8
routes:
- to: 193.254.1.0/24
via: 193.254.1.5
This is the exact Output I want:
network:
version: 2
renderer: networkd
ethernets:
enx1:
addresses:
- 193.254.1.6/24
nameservers:
addresses: [193.254.1.5, 8.8.8.8]
routes:
- to: 193.254.1.0/24
via: 193.254.1.5
Upvotes: 0
Views: 160
Reputation: 76599
You should not be using PyYAML. It only supports a subset of YAML 1.1 (which was superseded in 2009) and doesn't give you much fine control.
Start with what you want to get and see how well that round-trips in ruamel.yaml
:
import sys
import ruamel.yaml
yaml_str = """\
network:
version: 2
renderer: networkd
ethernets:
enx1:
addresses:
- 193.254.1.6/24
nameservers:
addresses: [193.254.1.5, 8.8.8.8]
routes:
- to: 193.254.1.0/24
via: 193.254.1.5
"""
yaml = ruamel.yaml.YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
yaml.preserve_quotes = True
data = yaml.load(yaml_str)
# print(data)
yaml.dump(data, sys.stdout)
which gives:
network:
version: 2
renderer: networkd
ethernets:
enx1:
addresses:
- 193.254.1.6/24
nameservers:
addresses: [193.254.1.5, 8.8.8.8]
routes:
- to: 193.254.1.0/24
via: 193.254.1.5
You do have control seperately over indentation of mappings and sequences, but
your sequences are not indented consistently: the sequence that is the value
for addresses
has an indent of 2 with an offset for the sequence indicator (-
)
within that of 0, and for the sequence that is the value of routes is indented 6 with an offset of 4;
your mappings are not indented consistently either (using 2 and 4 positions). ruamel.yaml
doesn't give you that fine control.
If you want to start with your datastructure you need to provide the valued for addresses
not as list
of a single string with embedded comma, but as the subclass of a list that ruamel.yaml
uses (you
could find which by inspecting data
after loading) and mark it to be represented as flow style:
import sys
import ruamel.yaml
def FS(*args):
seq = ruamel.yaml.CommentedSeq(args)
seq.fa.set_flow_style()
return seq
add_info = {'network':
{'version': 2,
'renderer': 'networkd',
'ethernets':
{'enx1':
{
'addresses': ['193.254.1.8/24'],
'nameservers': {'addresses':
FS('193.254.1.5', '8.8.8.8')}, # <- changed
'routes': [{
'to': '193.254.1.0/24',
'via': '193.254.1.5'
}]
}
}
}
}
yaml = ruamel.yaml.YAML()
yaml.dump(add_info, sys.stdout)
which also gives:
network:
version: 2
renderer: networkd
ethernets:
enx1:
addresses:
- 193.254.1.8/24
nameservers:
addresses: [193.254.1.5, 8.8.8.8]
routes:
- to: 193.254.1.0/24
via: 193.254.1.5
Upvotes: 1