diff --git a/mig/shared/conf.py b/mig/shared/conf.py index 0de37b321..32d49852d 100644 --- a/mig/shared/conf.py +++ b/mig/shared/conf.py @@ -32,6 +32,7 @@ import os import sys +from mig.shared.configuration import RuntimeConfiguration from mig.shared.defaults import MIG_ENV from mig.shared.fileio import unpickle @@ -42,7 +43,6 @@ def get_configuration_object(config_file=None, skip_log=False, and disable_auth_log arguments are passed on to allow skipping the default log initialization and disabling auth log for unit tests. """ - from mig.shared.configuration import Configuration if config_file: _config_file = config_file elif os.environ.get('MIG_CONF', None): @@ -63,7 +63,7 @@ def get_configuration_object(config_file=None, skip_log=False, skip_log = True disable_auth_log = True - configuration = Configuration(_config_file, False, skip_log, + configuration = RuntimeConfiguration(_config_file, False, skip_log, disable_auth_log) return configuration diff --git a/mig/shared/configuration.py b/mig/shared/configuration.py index 91a24549a..0e7a48b81 100644 --- a/mig/shared/configuration.py +++ b/mig/shared/configuration.py @@ -2851,6 +2851,47 @@ def parse_peers(self, peerfile): return peers_dict +class RuntimeConfiguration(Configuration): + """A more specific version of the Configuration which additionally supports + the notion of a context. + + Contextual information that is relevant to the duration of a request is + required in certain cases e.g. to support templating. Given Configuration + objects are threaded into and throough almost all the necessary codepaths + to make this information available, they are an attractive place to put + this - but a Configuration is currently loaded from static per-site data. + + Resolv this ambiguity with this subclass - a raw Confioguration will + continute to represent the static data while a specialised but entirely + compatible object is handed to request processing codepaths. + """ + + def __init__(self, config_file, verbose=False, skip_log=False, + disable_auth_log=False): + super().__init__(config_file, verbose, skip_log, disable_auth_log) + self._context = None + + def context(self, namespace=None): + """Retrieve the context or a previously registered namespace. + """ + + if self._context is None: + self._context = {} + if namespace is None: + return self._context + # allow the KeyError to escape if the registered namespace is missing + return self._context[namespace] + + def context_set(self, value, namespace=None): + """Attach a value as named namespace within the active congifuration. + """ + assert namespace is not None + + context = self.context() + context[namespace] = value + return value + + if '__main__' == __name__: conf = Configuration(os.path.expanduser('~/mig/server/MiGserver.conf'), True) diff --git a/tests/test_mig_shared_configuration.py b/tests/test_mig_shared_configuration.py index 7c9aef06e..506537466 100644 --- a/tests/test_mig_shared_configuration.py +++ b/tests/test_mig_shared_configuration.py @@ -42,7 +42,7 @@ def _is_method(value): def _to_dict(obj): return {k: v for k, v in inspect.getmembers(obj) - if not (k.startswith('__') or _is_method(v))} + if not (k.startswith('_') or _is_method(v))} class MigSharedConfiguration(MigTestCase):