pyangbind
pyangbind copied to clipboard
TypedListType not handled correctly by load_json
Hello,
Running the script below id expect it returns True, but it does not.
import json
import openconfig_bindings
from pyangbind.lib import pybindJSON
from pyangbind.lib.serialise import pybindJSONDecoder
input = {
"network-instance": {
"global": {
"name": "global",
"protocols": {
"protocol": {
"bgp 64496": {
"bgp": {
"neighbors": {
"neighbor": {
"192.0.2.5": {
"neighbor-address": "192.0.2.5",
"config": {
"auth-password": "super-secret-key",
"peer-as": 64497,
"description": "Friendly Peer"
},
"afi-safis": {
"afi-safi": {
"IPV4_UNICAST": {
"ipv4-unicast": {
"prefix-limit": {
"config": {
"shutdown-threshold-pct": 75,
"restart-timer": 30.0,
"max-prefixes": 5000
}
}
},
"apply-policy": {
"config": {
"import-policy": [
"AS64496_IN"
],
"export-policy": [
"AS64406_OUT"
]
}
},
"config": {
"enabled": True
},
"afi-safi-name": "IPV4_UNICAST"
}
}
}
}
}
}
},
"identifier": "bgp",
"name": "64496"
}
}
}
}
}
}
instance_obj = openconfig_bindings.network_instances.network_instances()
output = pybindJSONDecoder.load_json(input, None, None, obj=instance_obj)
output = json.loads(pybindJSON.dumps(output))
print input == output
Reason is serialize's load_json method TypedListType objects during parsing. Here's the relevant piece of code:
elif pybind_attr in ["TypedListType"]:
if not overwrite:
list_obj = getattr(obj, "_get_%s" % safe_name(key))()
for item in d[key]:
if item not in list_obj:
list_obj.append(item)
list_copy = []
for elem in list_obj:
list_copy.append(elem)
for e in list_copy:
if e not in d[key]:
list_obj.remove(e)
set_via_stdmethod = False
list_obj is of YANGBaseClass type while d[key] is regular list. When it checks if e isn't in d[key] (third line from bottom) e is ReferencePathType while items in d[key] are regular strings (at least in my case). So e is never in d[key] and it gets removed.
I fixed my local issue just by casting ReferencePathType to str, but i am not sure if that works in all cases:
diff --git a/pyangbind/lib/serialize.py b/pyangbind/lib/serialize.py
index 1308a4b..8f57ff5 100644
--- a/pyangbind/lib/serialize.py
+++ b/pyangbind/lib/serialize.py
@@ -308,7 +308,7 @@ class pybindJSONDecoder(object):
for elem in list_obj:
list_copy.append(elem)
for e in list_copy:
- if e not in d[key]:
+ if str(e) not in d[key]:
list_obj.remove(e)
set_via_stdmethod = False
else:
Can you take a look?