[VVP] Flag duplicate parameters in .env files
[vvp/validation-scripts.git] / ice_validator / tests / utils / yaml_custom_utils.py
index 6b99dea..597352a 100644 (file)
 #
 
 from yaml.constructor import ConstructorError
+from yaml.nodes import MappingNode
 
+try:
+    from yaml import CLoader as SafeLoader
+except ImportError:
+    from yaml import SafeLoader
 
-def raise_duplicates_keys(loader, node, deep=False):
-    """Raise error when duplicate keys found in yaml file."""
 
-    mapping = {}
-    for key_node, value_node in node.value:
-        key = loader.construct_object(key_node, deep=deep)
-        value = loader.construct_object(value_node, deep=deep)
-        if key in mapping:
+class UniqueKeyLoader(SafeLoader):
+    def construct_mapping(self, node, deep=False):
+        if not isinstance(node, MappingNode):
             raise ConstructorError(
-                "while constructing a mapping",
+                None,
+                None,
+                "expected a mapping node, but found %s" % node.id,
                 node.start_mark,
-                "found duplicate key (%s)" % key,
-                key_node.start_mark,
             )
-        mapping[key] = value
-
-    return loader.construct_mapping(node, deep)
+        mapping = {}
+        for key_node, value_node in node.value:
+            key = self.construct_object(key_node, deep=deep)
+            try:
+                hash(key)
+            except TypeError as exc:
+                raise ConstructorError(
+                    "while constructing a mapping",
+                    node.start_mark,
+                    "found unacceptable key (%s)" % exc,
+                    key_node.start_mark,
+                )
+            # check for duplicate keys
+            if key in mapping:
+                raise ConstructorError(
+                    "while constructing a mapping",
+                    node.start_mark,
+                    "found duplicate key",
+                    key_node.start_mark,
+                )
+            value = self.construct_object(value_node, deep=deep)
+            mapping[key] = value
+        return mapping