| 29 | # Credit: https://gist.github.com/pypt/94d747fe5180851196eb |
| 30 | class UniqueKeyLoader(SafeLoader): |
| 31 | def construct_mapping(self, node, deep=False): |
| 32 | if not isinstance(node, nodes.MappingNode): |
| 33 | raise constructor.ConstructorError( |
| 34 | None, |
| 35 | None, |
| 36 | "expected a mapping node, but found %s" % node.id, |
| 37 | node.start_mark, |
| 38 | ) |
| 39 | mapping = {} |
| 40 | for key_node, value_node in node.value: |
| 41 | key = self.construct_object(key_node, deep=deep) |
| 42 | try: |
| 43 | hash(key) |
| 44 | except TypeError as exc: |
| 45 | raise constructor.ConstructorError( |
| 46 | "while constructing a mapping", |
| 47 | node.start_mark, |
| 48 | "found unacceptable key (%s)" % exc, |
| 49 | key_node.start_mark, |
| 50 | ) |
| 51 | # check for duplicate keys |
| 52 | if key in mapping: |
| 53 | raise constructor.ConstructorError( |
| 54 | 'found duplicate key "%s"' % key_node.value |
| 55 | ) |
| 56 | value = self.construct_object(value_node, deep=deep) |
| 57 | mapping[key] = value |
| 58 | return mapping |
| 59 | |
| 60 | |
| 61 | # Add UniqueKeyLoader to the yaml SafeLoader so it is invoked by safe_load. |