112 lines
2.8 KiB
Python
112 lines
2.8 KiB
Python
import logging
|
|
import os
|
|
|
|
from bonobo.errors import ValidationError
|
|
|
|
|
|
def to_bool(s):
|
|
if s is None:
|
|
return False
|
|
if type(s) is bool:
|
|
return s
|
|
if len(s):
|
|
if s.lower() in ('f', 'false', 'n', 'no', '0'):
|
|
return False
|
|
return True
|
|
return False
|
|
|
|
|
|
class Setting:
|
|
__all__ = {}
|
|
|
|
@classmethod
|
|
def clear_all(cls):
|
|
for setting in Setting.__all__.values():
|
|
setting.clear()
|
|
|
|
def __new__(cls, name, *args, **kwargs):
|
|
Setting.__all__[name] = super().__new__(cls)
|
|
return Setting.__all__[name]
|
|
|
|
def __init__(self, name, default=None, validator=None, formatter=None):
|
|
self.name = name
|
|
|
|
if default:
|
|
self.default = default if callable(default) else lambda: default
|
|
else:
|
|
self.default = lambda: None
|
|
|
|
self.validator = validator
|
|
self.formatter = formatter
|
|
|
|
def __repr__(self):
|
|
return '<Setting {}={!r}>'.format(self.name, self.get())
|
|
|
|
def __eq__(self, other):
|
|
return self.get() == other
|
|
|
|
def __bool__(self):
|
|
return bool(self.get())
|
|
|
|
def set(self, value):
|
|
value = self.formatter(value) if self.formatter else value
|
|
if self.validator and not self.validator(value):
|
|
raise ValidationError('Invalid value {!r} for setting {}.'.format(value, self.name))
|
|
self.value = value
|
|
|
|
def set_if_true(self, value):
|
|
"""Sets the value to true if it is actually true. May sound strange but the main usage is enforcing some
|
|
settings from command line."""
|
|
if value:
|
|
self.set(True)
|
|
|
|
def get(self):
|
|
try:
|
|
return self.value
|
|
except AttributeError:
|
|
value = os.environ.get(self.name, None)
|
|
if value is None:
|
|
value = self.default()
|
|
self.set(value)
|
|
return self.value
|
|
|
|
def clear(self):
|
|
try:
|
|
del self.value
|
|
except AttributeError:
|
|
pass
|
|
|
|
|
|
# Debug/verbose mode.
|
|
DEBUG = Setting('DEBUG', formatter=to_bool, default=False)
|
|
|
|
# Profile mode.
|
|
PROFILE = Setting('PROFILE', formatter=to_bool, default=False)
|
|
|
|
# Quiet mode.
|
|
QUIET = Setting('QUIET', formatter=to_bool, default=False)
|
|
|
|
# Logging level.
|
|
LOGGING_LEVEL = Setting(
|
|
'LOGGING_LEVEL',
|
|
formatter=logging._checkLevel,
|
|
validator=logging._checkLevel,
|
|
default=lambda: logging.DEBUG if DEBUG.get() else logging.INFO,
|
|
)
|
|
|
|
# Input/Output format for transformations
|
|
IOFORMAT_ARG0 = 'arg0'
|
|
IOFORMAT_KWARGS = 'kwargs'
|
|
|
|
IOFORMATS = {IOFORMAT_ARG0, IOFORMAT_KWARGS}
|
|
|
|
IOFORMAT = Setting('IOFORMAT', default=IOFORMAT_KWARGS, validator=IOFORMATS.__contains__)
|
|
|
|
|
|
def check():
|
|
if DEBUG.get() and QUIET.get():
|
|
raise RuntimeError('I cannot be verbose and quiet at the same time.')
|
|
|
|
|
|
clear_all = Setting.clear_all
|