- def _add_element(val, path, structure):
- """Add an element to the given path.
-
- :param val: Element value.
- :param path: List of tuples where the first item is the element
- on the path and the second one is its type.
- :param structure: The structure where the element is added.
- :type val: dict, list, str, int, float, bool
- :type path: list
- :type structure: dict
- :raises TypeError if there is a wrong type in the path.
- """
- if len(path) == 1:
- if isinstance(structure, dict):
- if path[0][1] is dict:
- if path[0][0] not in structure:
- structure[path[0][0]] = dict()
- structure[path[0][0]].update(val)
- elif path[0][1] is list:
- if path[0][0] not in structure:
- structure[path[0][0]] = list()
- if isinstance(val, list):
- structure[path[0][0]].extend(val)
- else:
- structure[path[0][0]].append(val)
- else:
- structure[path[0][0]] = val
- elif isinstance(structure, list):
- if path[0][0] == -1 or path[0][0] >= len(structure):
- if isinstance(val, list):
- structure.extend(val)
- else:
- structure.append(val)
- else:
- structure[path[0][0]] = val
- return
-
- if isinstance(structure, dict):
- if path[0][1] is dict:
- if path[0][0] not in structure:
- structure[path[0][0]] = dict()
- elif path[0][1] is list:
- if path[0][0] not in structure:
- structure[path[0][0]] = list()
- elif isinstance(structure, list):
- if path[0][0] == -1 or path[0][0] >= len(structure):
- if path[0][1] is list:
- structure.append(list())
- elif path[0][1] is dict:
- structure.append(dict())
- else:
- structure.append(0)
- path[0][0] = len(structure) - 1
- else:
- raise TypeError(
- u"Only the last item in the path can be different type "
- u"then list or dictionary."
- )
- _add_element(val, path[1:], structure[path[0][0]])
-
- if not isinstance(value, (dict, list, str, int, float, bool)):
- raise TypeError(
- u"The value must be one of these types: dict, list, str, int, "
- u"float, bool.\n"
- f"Value: {value}\n"
- f"Path: {path_to_value}"
- )
- _add_element(deepcopy(value), path_to_value, self._data)
-
- def get_element(self, path):
- """Get the element specified by the path.
-
- :param path: List of keys and indices to the requested element or
- sub-tree.
- :type path: list
- :returns: Element specified by the path.
- :rtype: any