"""Verify all the things that could go wrong.""" from tfscript import tftypes def verifyConfig(cfg: dict) -> (dict, dict): verifiedConfig = {} errors = {} warnings = {} # Do defaults first defaults = [] classList = [ 'default', 'scout', 'soldier', 'pyro', ('demo','demoman'), ('engi','engineer'), ('heavy','heavyweapons'), 'medic', 'sniper', 'spy' ] for isclass, class_ in enumerate(classList): classCFG = None className = class_ if isinstance(class_, str) and class_ in cfg: classCFG = cfg.pop(class_) elif isinstance(class_, tuple): for tupClass in class_: if tupClass in cfg: classCFG = cfg.pop(tupClass) className = class_[0] break if classCFG is None: # Invalid class, this gets caught later. # It may be less efficient this way, but # it makes for more descriptive error messages continue classBinds = [] errMessages = [] warnMessages = [] for key, data in classCFG.items(): bind = tftypes.ScriptBind(key, data) bind = bind.toTargetType() if isclass: classBinds.append(bind) else: defaults.append(bind) errMessages.extend(bind.errors) warnMessages.extend(bind.warnings) if len(errMessages) > 0: errors.update( {className: errMessages} ) if len(warnMessages) > 0: warnings.update( {className: warnMessages} ) verifiedConfig.update({className: classBinds}) # Turn list into only strings by expanding tuples for i, class_ in enumerate(classList): if isinstance(class_, tuple): classList.insert(i+1, class_[1]) classList.insert(i+1, class_[0]) classList.pop(i) globalErrors = [] for remainingClass in cfg: if remainingClass not in classList: globalErrors.append(f'"{remainingClass}" is not a valid class') else: otherName = findTwin(remainingClass) globalErrors.append(f'Conflicting names for section: "{remainingClass}" and "{otherName}"') if len(globalErrors) > 0: errors.update({'file': globalErrors}) if len(errors) > 0: verifiedConfig.update({'errors': errors}) if len(warnings) > 0: verifiedConfig.update({'warnings': warnings}) return verifiedConfig, defaults def findTwin(className): classDict = { "demo": "demoman", "engi": "engineer", "heavy": "heavyweapons" } for className1, className2 in classDict.items(): if className == className1: return className2 elif className == className2: return className1 return None