Source code for dedop.conf.auxiliary_file_reader

from .auxiliary_errors import *
from .auxiliary_parameter import *

import json
from typing import Any, Sequence
import warnings

[docs]class AuxiliaryFileReader: """ class for reading auxiliary files """ # the _id field is the short ID of the file - e.g: CHD, CST ... # this is purely used to give context to error & warning messages _id = None _fileversion = 0 def __init__(self, filename: str=None, **kwargs: Any): """ The base class for auxiliary files. Reads the JSON data from a specified filename, or constructs it from the keyword arguments supplied to the constructor. """ # create empty data dictionary self._data = {} # if a filename has been provided, read the data from the file if filename is not None: self._data = self._read_file(filename) # update the data dict with values from keyword arguments self._data.update(kwargs) @classmethod def _read_file(cls, filename: str) -> None: """ reads JSON data from the specified filename and adds it to the data collection of the AuxiliaryFileReader """ data = {} # open the JSON doc for reading with open(filename) as input_file: version = cls.get_version(input_file) if version != cls._fileversion: raise IncompatibleAuxiliaryFileError(cls._id, cls._fileversion, version) # get the data of each item in the JSON doc for name, param in json.load(input_file).items(): # skip the metadata if name == "__metainf__": continue # check if it's in our array of expected parameters, # and throw a warning if it isn't. if name not in cls._get_parameters(): warnings.warn( UnknownParameterWarning(name, cls._id) ) # add the item to the dictionary data[name] = param['value'] return data @staticmethod def get_version(file): # read file as JSON data = json.load(file) # return to start of file if "__metainf__" not in data: # file predates metadata - version -1 return -1 return data["__metainf__"]["version"] @classmethod def _get_parameters(cls) -> Sequence[str]: """ returns an iterable of all the parameters defined for this configuration file - used to check if we should warn about using an undefined parameter. """ return ( for name, item in vars(cls).items() if\ isinstance(item, AuxiliaryParameter) ) def __getitem__(self, item: str) -> Any: """ returns the value of the specified parameter """ if item in self._get_parameters() and item in self._data: return self._data[item] raise MissingParameterError(item, self._id)