diff --git a/yangson/instance.py b/yangson/instance.py index 360090e4..277fd188 100644 --- a/yangson/instance.py +++ b/yangson/instance.py @@ -196,12 +196,21 @@ def __getitem__(self, key: InstanceKey) -> "InstanceNode": `name`. InstanceValueError: If the receiver's value is not an object. """ + if isinstance(self.value, ArrayValue) and isinstance(key, tuple): + return self._mapentry(key) + if isinstance(self.value, ArrayValue) and isinstance(key, dict): + return self._mapentry(self._map2tuple(key)) if isinstance(self.value, ObjectValue): return self._member(key) if isinstance(self.value, ArrayValue): return self._entry(key) raise InstanceValueError(self.json_pointer(), "scalar instance") + def __contains__(self, key: InstanceKey) -> bool: + """Checks if key does exist + """ + return self.get(key) is not None + def __iter__(self): """Return receiver's iterator. @@ -223,6 +232,14 @@ def ita(): return iter(self._member_names()) raise InstanceValueError(self.json_pointer(), "scalar instance") + def get(self, key: InstanceKey, d=None): + """Return member or entry with given key, returns default if it does not exist + """ + try: + return self[key] + except (InstanceValueError, NonexistentInstance): + return d + def is_internal(self) -> bool: """Return ``True`` if the receiver is an instance of an internal node. """ @@ -491,6 +508,24 @@ def _entry(self, index: int) -> "ArrayEntry": except (IndexError, TypeError): raise NonexistentInstance(self.json_pointer(), "entry " + str(index)) from None + def _map2tuple(self, key: dict) -> tuple: + """generate tuple for key""" + keylist = [] + for keyit in self.schema_node._key_members: + keylist.append(key[keyit]) + + return tuple(keylist) + + def _mapentry(self, key: tuple) -> "ArrayEntry": + """iterate over all childs""" + for child in self: + """generate tuple for key""" + childkey = tuple(child[singlekey].value for singlekey in self.schema_node._key_members) + if key == childkey: + return child + + raise NonexistentInstance(self.json_pointer(), f"key '{key}'") from None + def _peek_schema_route(self, sroute: SchemaRoute) -> Value: irt = InstanceRoute() sn = self.schema_node diff --git a/yangson/instvalue.py b/yangson/instvalue.py index 515964f9..cdb1bdab 100644 --- a/yangson/instvalue.py +++ b/yangson/instvalue.py @@ -35,7 +35,7 @@ EntryValue = Union[ScalarValue, "ObjectValue"] """Type of the value a list ot leaf-list entry.""" -InstanceKey = Union[InstanceName, int] +InstanceKey = Union[InstanceName, int, tuple, dict] """Index of an array entry or name of an object member.""" MetadataObject = Dict[PrefName, ScalarValue]