def namedEnum(argName, names, first=0): names = list(names) end = first + len(names) for name in names: assert name not in globals( ), "{name} = {val} already defined in globals()".format( name=name, val=globals()[name]) globals()[name] = name def validator(val): try: val = int(val) if val < first or val >= end: error( "Invalid {argName} value {val}. Must be between {first} and {last}", argName=argName, val=val, first=first, last=end - 1) return names[val - first] except ValueError: error("Invalid {argName}. Must be an integer") return spTypeFun( argName, validator, '''{argName}, enumeration from {first} to {last}'''.format( argName=argName, first=first, last=end - 1))
def oneOf(argName, *accepted): accepted = list(accepted) _accepted = frozenset(accepted) def validator(value): if value not in _accepted: error("Invalid {argName}: {value}. Must be one of {accepted}", argName=argName, value=value, accepted=accepted) else: return value return spTypeFun(argName, validator, '''One of {{{accepted}}}'''.format(accepted=", ".join(map(dumps, accepted))))
def intRange(argName, min, max): def validator(i): try: i = int(i) if i < min or i > max: error('Invalid {argName}. Must be between {min} and {max}', argName=argName, min=min, max=max) return i except ValueError: error('Invalid {argName}. Must be an integer', argName=argName) return spTypeFun(argName, validator, '''integer, {min} <= value <= {max}'''.format(min=min, max=max))
def volumeSizeValidator(argName): def validator(size): try: size = int(size) if size < 1: error('Invalid {argName} {size}. Must be positive', argName=argName, size=size) elif size % SECTOR_SIZE: error('Invalid {argName} {size}. Must be a multiple of {sectorSize}', argName=argName, size=size, sectorSize=SECTOR_SIZE) else: return size except ValueError: error('Non-numeric {argName}: {size}', argName=argName, size=size) return spTypeFun(argName, validator, '''a positive integer divisible by {sectorSize}'''.format(sectorSize=SECTOR_SIZE))
def oneOf(argName, *accepted): accepted = list(accepted) _accepted = frozenset(accepted) def validator(value): if value not in _accepted: error("Invalid {argName}: {value}. Must be one of {accepted}", argName=argName, value=value, accepted=accepted) else: return value return spTypeFun( argName, validator, '''One of {{{accepted}}}'''.format( accepted=", ".join(map(dumps, accepted))))
def unlimitedInt(argName, min, unlimited): def validator(val): if val is None: error('No {argName} specified', argName=argName) elif val == unlimited: return val try: val = int(val) if val < min: error('Ivalid {argName}. Must be at least {min}', argName=argName, min=min) else: return val except ValueError: error('Non-numeric {argName}: {value}', argName=argName, value=val) return spTypeFun(argName, validator, '''a positive integer or '{unlimited}' for unlimited'''.format(unlimited=unlimited))
def regex(argName, regex): _regex = re.compile(regex) def validator(string): if string is None: error('No {argName} specified', argName=argName) try: string = str(string) if not _regex.match(string): error('Invalid {argName} "{argVal}". Must match {regex}', argName=argName, argVal=string, regex=regex) return string except ValueError: error('Invalid {argName}. Must be string', argName=argName) return spTypeFun(argName, validator, '''string, regex {regex}'''.format(regex=regex))
def intRange(argName, min, max): def validator(i): try: i = int(i) if i < min or i > max: error('Invalid {argName}. Must be between {min} and {max}', argName=argName, min=min, max=max) return i except ValueError: error('Invalid {argName}. Must be an integer', argName=argName) return spTypeFun( argName, validator, '''integer, {min} <= value <= {max}'''.format(min=min, max=max))
def namedEnum(argName, names, first=0): names = list(names) end = first + len(names) for name in names: assert name not in globals(), "{name} = {val} already defined in globals()".format(name=name, val=globals()[name]) globals()[name] = name def validator(val): try: val = int(val) if val < first or val >= end: error("Invalid {argName} value {val}. Must be between {first} and {last}", argName=argName, val=val, first=first, last=end - 1) return names[val - first] except ValueError: error("Invalid {argName}. Must be an integer") return spTypeFun(argName, validator, '''{argName}, enumeration from {first} to {last}'''.format(argName=argName, first=first, last=end-1))
def unlimitedInt(argName, min, unlimited): def validator(val): if val is None: error('No {argName} specified', argName=argName) elif val == unlimited: return val try: val = int(val) if val < min: error('Ivalid {argName}. Must be at least {min}', argName=argName, min=min) else: return val except ValueError: error('Non-numeric {argName}: {value}', argName=argName, value=val) return spTypeFun( argName, validator, '''a positive integer or '{unlimited}' for unlimited'''.format( unlimited=unlimited))
def volumeSizeValidator(argName): def validator(size): try: size = int(size) if size < 1: error('Invalid {argName} {size}. Must be positive', argName=argName, size=size) elif size % SECTOR_SIZE: error( 'Invalid {argName} {size}. Must be a multiple of {sectorSize}', argName=argName, size=size, sectorSize=SECTOR_SIZE) else: return size except ValueError: error('Non-numeric {argName}: {size}', argName=argName, size=size) return spTypeFun( argName, validator, '''a positive integer divisible by {sectorSize}'''.format( sectorSize=SECTOR_SIZE))
def nameValidator(argName, regex, size, *blacklisted): _regex = re.compile(regex) blacklisted = list(blacklisted) _blacklisted = frozenset(blacklisted) def validator(name): if name is None: error('No {argName} specified', argName=argName) try: name = str(name) if not _regex.match(name): error('Invalid {argName} "{argVal}". Must match {regex}', argName=argName, argVal=name, regex=regex) elif name in _blacklisted: error('{argName} must not be in {blacklisted}', argName=argName, blacklisted=blacklisted) elif len(name) >= size: error('{argName} is too long. Max allowed is {max}', argName=argName, max=size-1) else: return name except ValueError: error('Invalid {argName}. Must be a string', argName=argName) return spTypeFun(argName, validator, '''a string({size}), matching {regex}, except {{{blacklisted}}}'''.format(size=size, regex=regex, blacklisted=", ".join(map(str, blacklisted))))
def nameValidator(argName, regex, size, *blacklisted): _regex = re.compile(regex) blacklisted = list(blacklisted) _blacklisted = frozenset(blacklisted) def validator(name): if name is None: error('No {argName} specified', argName=argName) try: name = str(name) if not _regex.match(name): error('Invalid {argName} "{argVal}". Must match {regex}', argName=argName, argVal=name, regex=regex) elif name in _blacklisted: error('{argName} must not be in {blacklisted}', argName=argName, blacklisted=blacklisted) elif len(name) >= size: error('{argName} is too long. Max allowed is {max}', argName=argName, max=size - 1) else: return name except ValueError: error('Invalid {argName}. Must be a string', argName=argName) return spTypeFun( argName, validator, '''a string({size}), matching {regex}, except {{{blacklisted}}}'''. format(size=size, regex=regex, blacklisted=", ".join(map(str, blacklisted))))