pyangbind icon indicating copy to clipboard operation
pyangbind copied to clipboard

TypedListType not handled correctly by load_json

Open lamehost opened this issue 8 years ago • 0 comments

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?

lamehost avatar Sep 23 '17 14:09 lamehost