Moving code around a bit
This commit is contained in:
parent
1cdc722f46
commit
d31fe9a62d
@ -7,6 +7,15 @@ import time
|
|||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
import types
|
import types
|
||||||
import inspect
|
import inspect
|
||||||
|
import functools
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"SettingsBase", "ClassFinder", "ModuleFinder",
|
||||||
|
"ConfigurationError",
|
||||||
|
"Module", "AsyncModule", "IntervalModule",
|
||||||
|
"i3pystatus", "I3statusHandler",
|
||||||
|
"get_path" # We need that for mkdocs
|
||||||
|
]
|
||||||
|
|
||||||
class ConfigurationError(Exception):
|
class ConfigurationError(Exception):
|
||||||
def __init__(self, module, key=None, missing=None, ambigious_classes=None, invalid=False):
|
def __init__(self, module, key=None, missing=None, ambigious_classes=None, invalid=False):
|
||||||
@ -22,6 +31,9 @@ class ConfigurationError(Exception):
|
|||||||
|
|
||||||
super().__init__(message)
|
super().__init__(message)
|
||||||
|
|
||||||
|
def get_path():
|
||||||
|
return __path__
|
||||||
|
|
||||||
class SettingsBase:
|
class SettingsBase:
|
||||||
"""
|
"""
|
||||||
Support class for providing a nice and flexible settings interface
|
Support class for providing a nice and flexible settings interface
|
||||||
@ -108,6 +120,37 @@ class IntervalModule(AsyncModule):
|
|||||||
self.run()
|
self.run()
|
||||||
time.sleep(self.interval)
|
time.sleep(self.interval)
|
||||||
|
|
||||||
|
class ClassFinder:
|
||||||
|
"""Support class to find classes of specific bases in a module"""
|
||||||
|
|
||||||
|
def __init__(self, baseclass, exclude=[]):
|
||||||
|
self.baseclass = baseclass
|
||||||
|
self.exclude = exclude
|
||||||
|
|
||||||
|
def predicate(self, obj):
|
||||||
|
return inspect.isclass(obj) and issubclass(obj, self.baseclass) and obj not in self.exclude
|
||||||
|
|
||||||
|
def search_module(self, module):
|
||||||
|
# Neat trick: [(x,y),(u,v)] becomes [(x,u),(y,v)]
|
||||||
|
return list(zip(*inspect.getmembers(module, self.predicate)))[1]
|
||||||
|
|
||||||
|
def get_class(self, module):
|
||||||
|
classes = self.search_module(module)
|
||||||
|
|
||||||
|
if len(classes) > 1:
|
||||||
|
# If there are multiple Module clases bundled in one module,
|
||||||
|
# well, we can't decide for the user.
|
||||||
|
raise ConfigurationError(module.__name__, ambigious_classes=classes)
|
||||||
|
elif not classes:
|
||||||
|
raise ConfigurationError(module.__name__, invalid=True)
|
||||||
|
|
||||||
|
return classes[0]
|
||||||
|
|
||||||
|
def instanciate_class(self, module, *args, **kwargs):
|
||||||
|
return self.get_class(module)(*args, **kwargs)
|
||||||
|
|
||||||
|
ModuleFinder = functools.partial(ClassFinder, baseclass=Module, exclude=[Module, IntervalModule, AsyncModule])
|
||||||
|
|
||||||
class IOHandler:
|
class IOHandler:
|
||||||
def __init__(self, inp=sys.stdin, out=sys.stdout):
|
def __init__(self, inp=sys.stdin, out=sys.stdout):
|
||||||
self.inp = inp
|
self.inp = inp
|
||||||
@ -207,35 +250,6 @@ class JSONIO:
|
|||||||
yield j
|
yield j
|
||||||
self.io.write_line(prefix + json.dumps(j))
|
self.io.write_line(prefix + json.dumps(j))
|
||||||
|
|
||||||
class ClassFinder:
|
|
||||||
"""Support class to find classes of specific bases in a module"""
|
|
||||||
|
|
||||||
def __init__(self, baseclass, exclude=[]):
|
|
||||||
self.baseclass = baseclass
|
|
||||||
self.exclude = exclude
|
|
||||||
|
|
||||||
def predicate(self, obj):
|
|
||||||
return inspect.isclass(obj) and issubclass(obj, self.baseclass) and obj not in self.exclude
|
|
||||||
|
|
||||||
def search_module(self, module):
|
|
||||||
# Neat trick: [(x,y),(u,v)] becomes [(x,u),(y,v)]
|
|
||||||
return list(zip(*inspect.getmembers(module, self.predicate)))[1]
|
|
||||||
|
|
||||||
def get_class(self, module):
|
|
||||||
classes = self.search_module(module)
|
|
||||||
|
|
||||||
if len(classes) > 1:
|
|
||||||
# If there are multiple Module clases bundled in one module,
|
|
||||||
# well, we can't decide for the user.
|
|
||||||
raise ConfigurationError(module.__name__, ambigious_classes=classes)
|
|
||||||
elif not classes:
|
|
||||||
raise ConfigurationError(module.__name__, invalid=True)
|
|
||||||
|
|
||||||
return classes[0]
|
|
||||||
|
|
||||||
def instanciate_class(self, module, *args, **kwargs):
|
|
||||||
return self.get_class(module)(*args, **kwargs)
|
|
||||||
|
|
||||||
class i3pystatus:
|
class i3pystatus:
|
||||||
modules = []
|
modules = []
|
||||||
|
|
||||||
@ -245,7 +259,7 @@ class i3pystatus:
|
|||||||
else:
|
else:
|
||||||
self.io = IOHandler(input_stream)
|
self.io = IOHandler(input_stream)
|
||||||
|
|
||||||
self.finder = ClassFinder(baseclass=Module, exclude=[Module, IntervalModule, AsyncModule])
|
self.finder = ModuleFinder()
|
||||||
|
|
||||||
def get_instance_for_module(self, module, position, args, kwargs):
|
def get_instance_for_module(self, module, position, args, kwargs):
|
||||||
if isinstance(module, types.ModuleType):
|
if isinstance(module, types.ModuleType):
|
||||||
|
Loading…
Reference in New Issue
Block a user