Moving code around a bit

This commit is contained in:
enkore 2013-02-23 18:40:59 +01:00
parent 1cdc722f46
commit d31fe9a62d

View File

@ -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):