Replaced with current version of Meh

This commit is contained in:
PhilipTrauner 2016-03-21 00:15:27 +01:00
parent 444f73b3f8
commit 894c973974

View file

@ -1,27 +1,38 @@
from imp import load_source from imp import load_source
from os.path import isfile from os.path import isfile
from marshal import dumps, loads
from types import FunctionType
class ValidationFailedError(Exception): class OptionDuplicateError(IndexError):
def __init__(self, name): def __init__(self, name):
super(InputError, self).__init__("validation failed for '%s'" % name) super(IndexError, self).__init__("'%s' already exists" % name)
class OptionNotFoundError(IndexError): class OptionNotFoundError(IndexError):
def __init__(self, name): def __init__(self, name):
super(InputError, self).__init__("'%s' does not exist" % name) super(IndexError, self).__init__("'%s' does not exist" % name)
class NameMustBeStringError(Exception):
def __init__(self):
super(Exception, self).__init__("option names have to be strings")
def make_value(value): def make_value(value):
if type(value) is str: if type(value) is str:
value = '"%s"' % value value = '"%s"' % value
elif type(value) in (list, tuple, tuple): elif type(value) in (list, tuple, dict):
value = str(value) value = str(value)
elif type(value) is FunctionType:
value = dumps(value.__code__)
return value return value
class Option: class Option:
def __init__(self, name, default_value, validator=None, comment=""): def __init__(self, name, default_value, validator=None, comment=""):
if not type(name) is str:
raise NameMustBeStringError()
self.name = name self.name = name
self.default_value = default_value self.default_value = default_value
self.validator = validator self.validator = validator
@ -29,30 +40,52 @@ class Option:
class Config: class Config:
def __init__(self, options=[]): def __init__(self, options=[], validation_failed=None, override_on_error=False):
if type(options) in (list, tuple):
for option in options:
if not type(option) is Option:
raise TypeError("all options must be of type Option")
else:
raise TypeError("options must be a list or tuple containing options of type Option")
self.options = options self.options = options
self.validation_failed = validation_failed
self.override_on_error = override_on_error
def read_from_file(self, file): def read_from_file(self, file):
if isfile(file): if isfile(file):
config = load_source("config", file) config = load_source("config", file)
error = False
for option in self.options: for option in self.options:
found = False # Make sure all options are avaliable
for attr in dir(config): if option.name not in dir(config):
if not attr.startswith("__"): setattr(config, option.name, option.default_value)
if option.name == attr: error = True
found = True else:
break # Make sure all validators pass
if not found: if option.validator != None:
value = getattr(config, option.name)
if not option.validator(value):
setattr(config, option.name, option.default_value)
if self.validation_failed != None:
self.validation_failed(option.name, value)
error = True
if self.override_on_error:
if error:
self.write_to_file(file) self.write_to_file(file)
return self.read_from_file(file)
return config return config
else: else:
raise FileNotFoundError() raise FileNotFoundError()
def add(self, option): def add(self, new_option):
self.options.append(option) if type(new_option) is Option:
for option in self.options:
if new_option.name == option.name:
raise OptionDuplicateError(option.name)
self.options.append(new_option)
else:
raise TypeError("invalid type supplied")
def remove(self, option): def remove(self, option):
@ -67,9 +100,17 @@ class Config:
def get(self): def get(self):
contains_function = False
out = "" out = ""
for option in self.options: for option in self.options:
out += "%s = %s %s\n" % (option.name, make_value(option.default_value), ("# %s" % option.comment) if option.comment else "") value = make_value(option.default_value)
if type(option.default_value) is FunctionType:
if not contains_function:
out = "from marshal import loads; from types import FunctionType\n\n" + out
contains_function = True
value = 'FunctionType(loads(%s), globals(), "%s")' % (value, option.name)
out += "%s = %s%s\n" % (option.name, value,
(" # %s" % option.comment) if option.comment else "")
return out return out