| # Safely load fast C Yaml loader/dumper if they are available | |
| try: | |
| from yaml import CSafeLoader as Loader | |
| except ImportError: | |
| from yaml import SafeLoader as Loader # type: ignore[assignment, misc] | |
| try: | |
| from yaml import CSafeDumper as Dumper | |
| except ImportError: | |
| from yaml import SafeDumper as Dumper # type: ignore[assignment, misc] | |
| YamlDumper = Dumper | |
| # A custom loader for YAML that errors on duplicate keys. | |
| # This doesn't happen by default: see https://github.com/yaml/pyyaml/issues/165 | |
| class YamlLoader(Loader): | |
| def construct_mapping(self, node, deep=False): # type: ignore[no-untyped-def] | |
| mapping = [] | |
| for key_node, value_node in node.value: | |
| key = self.construct_object(key_node, deep=deep) # type: ignore[no-untyped-call] | |
| assert key not in mapping, ( | |
| f"Found a duplicate key in the yaml. key={key}, line={node.start_mark.line}" | |
| ) | |
| mapping.append(key) | |
| mapping = super().construct_mapping(node, deep=deep) # type: ignore[no-untyped-call] | |
| return mapping | |