Reworked exceptions
This commit is contained in:
parent
70155b2f18
commit
ebe3d718e3
@ -11,26 +11,36 @@ import functools
|
|||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"SettingsBase", "ClassFinder", "ModuleFinder",
|
"SettingsBase", "ClassFinder", "ModuleFinder",
|
||||||
"ConfigurationError",
|
"ConfigError", "ConfigKeyError", "ConfigMissingError", "ConfigAmbigiousClassesError", "ConfigInvalidModuleError",
|
||||||
"Module", "AsyncModule", "IntervalModule",
|
"Module", "AsyncModule", "IntervalModule",
|
||||||
"i3pystatus", "I3statusHandler",
|
"i3pystatus", "I3statusHandler",
|
||||||
"get_path" # We need that for mkdocs
|
"get_path" # We need that for mkdocs
|
||||||
]
|
]
|
||||||
|
|
||||||
class ConfigurationError(Exception):
|
class ConfigError(Exception):
|
||||||
def __init__(self, module, key=None, missing=None, ambigious_classes=None, invalid=False):
|
"""ABC for configuration exceptions"""
|
||||||
message = "Module '{0}'".format(module)
|
def __init__(self, module, *args, **kwargs):
|
||||||
if key is not None:
|
message = "Module '{0}': {1}".format(module, self.format(*args, **kwargs))
|
||||||
message += ": invalid option '{0}'".format(key)
|
|
||||||
if missing is not None:
|
|
||||||
message += ": missing required options: {0}".format(missing)
|
|
||||||
if ambigious_classes is not None:
|
|
||||||
message += ": ambigious module specification, found multiple classes: {0}".format(ambigious_classes)
|
|
||||||
if invalid:
|
|
||||||
message += ": no class found"
|
|
||||||
|
|
||||||
super().__init__(message)
|
super().__init__(message)
|
||||||
|
|
||||||
|
class ConfigKeyError(ConfigError, KeyError):
|
||||||
|
def format(self, key):
|
||||||
|
return "invalid option '{0}'".format(key)
|
||||||
|
|
||||||
|
class ConfigMissingError(ConfigError):
|
||||||
|
def format(self, missing):
|
||||||
|
return "missing required options: {0}".format(missing)
|
||||||
|
super().__init__(module)
|
||||||
|
|
||||||
|
class ConfigAmbigiousClassesError(ConfigError):
|
||||||
|
def format(self, ambigious_classes):
|
||||||
|
return "ambigious module specification, found multiple classes: {0}".format(ambigious_classes)
|
||||||
|
|
||||||
|
class ConfigInvalidModuleError(ConfigError):
|
||||||
|
def format(self):
|
||||||
|
return "no class found"
|
||||||
|
|
||||||
def get_path():
|
def get_path():
|
||||||
return __path__
|
return __path__
|
||||||
|
|
||||||
@ -71,7 +81,6 @@ class SettingsBase:
|
|||||||
if len(args) == 1 and not kwargs:
|
if len(args) == 1 and not kwargs:
|
||||||
# User can also pass in a dict for their settings
|
# User can also pass in a dict for their settings
|
||||||
# Note: you could do that anyway, with the ** syntax
|
# Note: you could do that anyway, with the ** syntax
|
||||||
# Note2: just for backwards compatibility
|
|
||||||
kwargs = args[0]
|
kwargs = args[0]
|
||||||
|
|
||||||
for key, value in kwargs.items():
|
for key, value in kwargs.items():
|
||||||
@ -79,12 +88,12 @@ class SettingsBase:
|
|||||||
setattr(self, key, value)
|
setattr(self, key, value)
|
||||||
required.add(key)
|
required.add(key)
|
||||||
else:
|
else:
|
||||||
raise ConfigurationError(type(self).__name__, key=key)
|
raise ConfigKeyError(type(self).__name__, key=key)
|
||||||
|
|
||||||
# Some nice set magic :-)
|
# Some nice set magic :-) [that's more efficient if we have classes with a few thousand settings]
|
||||||
required &= set(self.required)
|
required &= set(self.required)
|
||||||
if len(required) != len(self.required):
|
if len(required) != len(self.required):
|
||||||
raise ConfigurationError(type(self).__name__, missing=self.required-required)
|
raise ConfigMissingError(type(self).__name__, self.required-required)
|
||||||
|
|
||||||
self.init()
|
self.init()
|
||||||
|
|
||||||
@ -140,13 +149,13 @@ class ClassFinder:
|
|||||||
if len(classes) > 1:
|
if len(classes) > 1:
|
||||||
# If there are multiple Module clases bundled in one module,
|
# If there are multiple Module clases bundled in one module,
|
||||||
# well, we can't decide for the user.
|
# well, we can't decide for the user.
|
||||||
raise ConfigurationError(module.__name__, ambigious_classes=classes)
|
raise ConfigAmbigiousClassesError(module.__name__, classes)
|
||||||
elif not classes:
|
elif not classes:
|
||||||
raise ConfigurationError(module.__name__, invalid=True)
|
raise ConfigInvalidModuleError(module.__name__)
|
||||||
|
|
||||||
return classes[0]
|
return classes[0]
|
||||||
|
|
||||||
def instanciate_class(self, module, *args, **kwargs):
|
def instanciate_class_from_module(self, module, *args, **kwargs):
|
||||||
return self.get_class(module)(*args, **kwargs)
|
return self.get_class(module)(*args, **kwargs)
|
||||||
|
|
||||||
ModuleFinder = functools.partial(ClassFinder, baseclass=Module, exclude=[Module, IntervalModule, AsyncModule])
|
ModuleFinder = functools.partial(ClassFinder, baseclass=Module, exclude=[Module, IntervalModule, AsyncModule])
|
||||||
@ -271,7 +280,7 @@ class i3pystatus:
|
|||||||
args = (position,)
|
args = (position,)
|
||||||
position = 0
|
position = 0
|
||||||
|
|
||||||
module = self.finder.instanciate_class(module, *args, **kwargs)
|
module = self.finder.instanciate_class_from_module(module, *args, **kwargs)
|
||||||
elif args or kwargs:
|
elif args or kwargs:
|
||||||
raise ValueError("Additional arguments are invalid if 'module' is already an object")
|
raise ValueError("Additional arguments are invalid if 'module' is already an object")
|
||||||
|
|
||||||
|
@ -131,11 +131,9 @@ def get_all():
|
|||||||
for cls in classes:
|
for cls in classes:
|
||||||
mods.append(Module(cls, neighbours=len(classes), module_name=name, module=module))
|
mods.append(Module(cls, neighbours=len(classes), module_name=name, module=module))
|
||||||
|
|
||||||
return mods
|
return sorted(mods, key=lambda module: module.name)
|
||||||
|
|
||||||
with open("template.md", "r") as template:
|
with open("template.md", "r") as template:
|
||||||
tpl = template.read()
|
|
||||||
|
|
||||||
moddoc = "".join(map(lambda module: module.format(), get_all()))
|
moddoc = "".join(map(lambda module: module.format(), get_all()))
|
||||||
|
|
||||||
print(tpl.replace("!!module_doc!!", moddoc))
|
print(template.read().replace("!!module_doc!!", moddoc))
|
||||||
|
Loading…
Reference in New Issue
Block a user