Skip to content

Commit

Permalink
Implemented enhancement CiscoDevNet#925 in Python
Browse files Browse the repository at this point in the history
  • Loading branch information
ygorelik committed Jun 20, 2019
1 parent 9df3f21 commit 9bf8ef5
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 8 deletions.
4 changes: 4 additions & 0 deletions sdk/python/core/ydk/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# ------------------------------------------------------------------

from .py_types import Entity, EntityCollection, Config, Filter, YList, YLeafList
from .py_types import entity_to_dict, entity_diff

from ydk.ext.types import Bits
from ydk.ext.types import ChildrenMap
from ydk.ext.types import ModelCachingOption
Expand Down Expand Up @@ -48,4 +50,6 @@
"YLeaf",
"YLeafList",
"YType",
"entity_to_dict",
"entity_diff",
]
73 changes: 65 additions & 8 deletions sdk/python/core/ydk/types/py_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@
- YList
- YLeafList
- Entity
- EntityCollection
"""
from collections import OrderedDict
from functools import reduce

import importlib
import logging

import sys

if sys.version_info > (3,):
long = int
unicode = str
Expand All @@ -43,11 +44,13 @@
from ydk.ext.types import Decimal64 # Do not remove. Used in eval()
from ydk.ext.types import Entity as _Entity
from ydk.ext.types import LeafDataList

from ydk.filters import YFilter as _YFilter
from ydk.errors import YModelError as _YModelError
from ydk.errors import YInvalidArgumentError
from ydk.errors.error_handler import handle_type_error as _handle_type_error


class YLeafList(_YLeafList):
""" Wrapper class for YLeafList, add __repr__ and get list slice
functionalities.
Expand Down Expand Up @@ -326,11 +329,11 @@ def path(self):
return self.get_segment_path()

def get_absolute_path(self):
path = self._absolute_path()
if len(path) == 0 and self.is_top_level_class:
path = self.get_segment_path()
if '[' in path:
path = path.split('[')[0]
path = self.get_segment_path()
if not self.is_top_level_class:
path = self.parent.get_absolute_path() + '/' + path
# elif '[' in path:
# path = path.split('[')[0]
return path

def _get_child_by_seg_name(self, segs):
Expand All @@ -345,8 +348,8 @@ def _perform_setattr(self, clazz, leaf_names, name, value):
if name != 'yfilter' and name != 'parent' and name != 'ignore_validation' \
and hasattr(self, '_is_frozen') and self._is_frozen \
and name not in self.__dict__:
raise _YModelError("Attempt to assign unknown attribute '{0}' to '{1}'.".format(name,
self.__class__.__name__))
raise _YModelError("Attempt to assign unknown attribute '{0}' to '{1}'.".
format(name, self.__class__.__name__))
if name in self.__dict__ and isinstance(self.__dict__[name], YList):
raise _YModelError("Attempt to assign value of '{}' to YList ldata. "
"Please use list append or extend method."
Expand Down Expand Up @@ -399,6 +402,60 @@ def _assign_yleaflist(self, name, value, v):

def __str__(self):
return "{}.{}".format(self.__class__.__module__, self.__class__.__name__)


def entity_to_dict(entity):
edict = {}
abs_path = entity.get_absolute_path()
if (hasattr(entity, 'is_presence_container') and entity.is_presence_container) or \
abs_path.endswith(']'):
edict[abs_path] = ''
leaf_name_data = entity.get_name_leaf_data()
for l in leaf_name_data:
leaf_name = l[0]
leaf_value = l[1].value
if leaf_name not in entity.ylist_key_names:
edict["%s/%s" % (abs_path, leaf_name)] = leaf_value
for name, child in entity.get_children().items():
child_dict = entity_to_dict(child)
for n, v in child_dict.items():
edict[n] = v
return edict


def entity_diff(ent1, ent2):
if ent1 is None or ent2 is None or type(ent1) != type(ent2):
logger = logging.getLogger("ydk.types.Entity")
logger.error("entity_diff: Incompatible arguments provided.")
raise YInvalidArgumentError("entity_diff: Incompatible arguments provided.")

diffs = {}
ent1_dict = entity_to_dict(ent1)
ent2_dict = entity_to_dict(ent2)
ent1_keys = sorted(ent1_dict.keys())
ent2_keys = sorted(ent2_dict.keys())
ent1_skip_keys = []
for key in ent1_keys:
if key in ent1_skip_keys:
continue
if key in ent2_keys:
if ent1_dict[key] != ent2_dict[key]:
diffs[key] = (ent1_dict[key], ent2_dict[key])
ent2_keys.remove(key)
else:
diffs[key] = (ent1_dict[key], None)
for dup_key in ent1_keys:
if dup_key.startswith(key):
ent1_skip_keys.append(dup_key)
ent2_skip_keys = []
for key in ent2_keys:
if key in ent2_skip_keys:
continue
diffs[key] = (None, ent2_dict[key])
for dup_key in ent2_keys:
if dup_key.startswith(key):
ent2_skip_keys.append(dup_key)
return diffs


def _name_matches_yang_name(name, yang_name):
Expand Down

0 comments on commit 9bf8ef5

Please sign in to comment.