I have the following code that reads from a yaml file and needs to know if the property "ethernets" exists in it. I use "ethernets1" below to see how the code behaves when the property does not exist.
#!/usr/bin/python
import yaml
import simplejson as json
NETPLAN = "/etc/netplan/01-network-manager-all.yaml"
# get netplan file
with open(NETPLAN, "r") as stream:
try:
netplan_config = yaml.safe_load(stream)
print("netplan_config = " + json.dumps(netplan_config))
stream.close()
except yaml.YAMLError as e:
print(f"error = {str(e)}")
# test 1
if hasattr(netplan_config["network"], "ethernets"):
print("mark1")
else:
print("mark2")
# test 2
if netplan_config["network"]["ethernets"]:
print("mark3")
else:
print("mark4")
# test 3
if netplan_config["network"]["ethernets1"]:
print("mark5")
else:
print("mark6")
# test 4
try:
if netplan_config["network"]["ethernets1"]:
print("mark7")
except KeyError:
print("mark8")
The output is:
mark2
mark3
error thrown: KeyError: 'ethernets1'
The problem is that "mark1" is not printed. I cannot use the test 2 method because it throws an error if it does not exist. I do not understand why hasattr
does not work on netplan_config
.
YAML file for reference:
network:
ethernets:
eth0:
addresses:
- 192.168.4.31/22
dhcp4: false
dhcp6: false
match:
macaddress: 24:4b:fe:e2:1c:4a
nameservers:
addresses:
- 8.8.8.8
- 8.8.4.4
routes:
- to: default
via: 192.168.4.1
set-name: eth0
renderer: NetworkManager
version: 2
Edit: I guess I could use test4 (it works), but I would rather use hasattr
as it is cleaner.
YAML mappings are loaded as Python dicts (unless you tag the mapping and provide an appropriate loader for the tag), so testing on an attribute is not going to work.
What you need to do is test if a key in the dict:
or use just catch the
KeyError
:which I would use if you are going to use
eths
part