# ===================================================================
#
# Unless otherwise specified, all software contained herein is licensed
-# under the Apache License, Version 2.0 (the “License”);
+# under the Apache License, Version 2.0 (the "License");
# you may not use this software except in compliance with the License.
# You may obtain a copy of the License at
#
#
#
# Unless otherwise specified, all documentation contained herein is licensed
-# under the Creative Commons License, Attribution 4.0 Intl. (the “License”);
+# under the Creative Commons License, Attribution 4.0 Intl. (the "License");
# you may not use this documentation except in compliance with the License.
# You may obtain a copy of the License at
#
#
# ============LICENSE_END============================================
#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
#
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", node.start_mark,
- "found duplicate key (%s)" % key, key_node.start_mark)
- mapping[key] = value
-
- return loader.construct_mapping(node, deep)
+ None,
+ None,
+ "expected a mapping node, but found %s" % node.id,
+ node.start_mark,
+ )
+ 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