Source code for piglot.utils.yaml_parser

"""Module for parsing the YAML configuration file."""
from typing import Dict, Any
import os
import os.path
import yaml
from yaml.parser import ParserError
from yaml.scanner import ScannerError


[docs] class UniqueKeyLoader(yaml.SafeLoader): """YAML loader that checks for duplicate keys in mappings. Adapted from https://gist.github.com/pypt/94d747fe5180851196eb. """
[docs] def construct_mapping(self, node, deep=False): mapping = set() for key_node, _ in node.value: key = self.construct_object(key_node, deep=deep) if key in mapping: raise ValueError(f"Duplicate {key!r} key found in YAML.") mapping.add(key) return super().construct_mapping(node, deep)
[docs] def parse_config_file(config_file: str) -> Dict[str, Any]: """Parses the YAML configuration file. Parameters ---------- config_file : str Path to the configuration file. Returns ------- Dict[str, Any] Dictionary with the YAML data. Raises ------ RuntimeError When the YAML parsing fails. """ try: with open(config_file, 'r', encoding='utf8') as file: config = yaml.load(file, Loader=UniqueKeyLoader) # nosec B506 except (ParserError, ScannerError) as exc: raise RuntimeError("Failed to parse the config file: YAML syntax seems invalid.") from exc # Check required terms if 'iters' not in config: raise RuntimeError("Missing number of iterations from the config file") if 'objective' not in config: raise RuntimeError("Missing objective from the config file") if 'optimiser' not in config: raise RuntimeError("Missing optimiser from the config file") if 'parameters' not in config: raise RuntimeError("Missing parameters from the config file") # Add missing optional items if 'output' not in config: config['output'] = os.path.splitext(config_file)[0] if 'quiet' not in config: config["quiet"] = False elif config['quiet']: config["quiet"] = True return config