summaryrefslogtreecommitdiff
path: root/paste/config.py
diff options
context:
space:
mode:
authorpjenvey <devnull@localhost>2006-12-21 21:51:39 +0000
committerpjenvey <devnull@localhost>2006-12-21 21:51:39 +0000
commit63efb333ce97d54cc7e1d2328ab2bc69eedb7f0e (patch)
tree1bdc20a82e024387a7eba9e2e92878e68514666c /paste/config.py
parent2318ea0e076ad9dd7d7c7551df17d32982fadd3e (diff)
downloadpaste-63efb333ce97d54cc7e1d2328ab2bc69eedb7f0e.tar.gz
added paste.config, a rewrite of paste.deploy.config using the registry
Diffstat (limited to 'paste/config.py')
-rw-r--r--paste/config.py118
1 files changed, 118 insertions, 0 deletions
diff --git a/paste/config.py b/paste/config.py
new file mode 100644
index 0000000..a33c919
--- /dev/null
+++ b/paste/config.py
@@ -0,0 +1,118 @@
+# (c) 2006 Ian Bicking, Philip Jenvey and contributors
+# Written for Paste (http://pythonpaste.org)
+# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
+"""Paste Configuration Middleware and Objects"""
+from paste.registry import RegistryManager, StackedObjectProxy
+
+__all__ = ['DispatchingConfig', 'CONFIG', 'ConfigMiddleware']
+
+class DispatchingConfig(StackedObjectProxy):
+ """
+ This is a configuration object that can be used globally,
+ imported, have references held onto. The configuration may differ
+ by thread (or may not).
+
+ Specific configurations are registered (and deregistered) either
+ for the process or for threads.
+ """
+ # @@: What should happen when someone tries to add this
+ # configuration to itself? Probably the conf should become
+ # resolved, and get rid of this delegation wrapper
+
+ def __init__(self):
+ super(DispatchingConfig, self).__init__(name='DispatchingConfig')
+ self.__dict__['_process_configs'] = []
+
+ def push_thread_config(self, conf):
+ """
+ Make ``conf`` the active configuration for this thread.
+ Thread-local configuration always overrides process-wide
+ configuration.
+
+ This should be used like::
+
+ conf = make_conf()
+ dispatching_config.push_thread_config(conf)
+ try:
+ ... do stuff ...
+ finally:
+ dispatching_config.pop_thread_config(conf)
+ """
+ self._push_object(conf)
+
+ def pop_thread_config(self, conf=None):
+ """
+ Remove a thread-local configuration. If ``conf`` is given,
+ it is checked against the popped configuration and an error
+ is emitted if they don't match.
+ """
+ self._pop_object(conf)
+
+ def push_process_config(self, conf):
+ """
+ Like push_thread_config, but applies the configuration to
+ the entire process.
+ """
+ self._process_configs.append(conf)
+
+ def pop_process_config(self, conf=None):
+ self._pop_from(self._process_configs, conf)
+
+ def _pop_from(self, lst, conf):
+ popped = lst.pop()
+ if conf is not None and popped is not conf:
+ raise AssertionError(
+ "The config popped (%s) is not the same as the config "
+ "expected (%s)"
+ % (popped, conf))
+
+ def _current_obj(self):
+ try:
+ return super(DispatchingConfig, self)._current_obj()
+ except TypeError:
+ if self._process_configs:
+ return self._process_configs[-1]
+ raise AttributeError(
+ "No configuration has been registered for this process "
+ "or thread")
+
+ def current_conf(self):
+ return self._current_obj()
+
+CONFIG = DispatchingConfig()
+
+class ConfigMiddleware(RegistryManager):
+ """
+ A WSGI middleware that adds a ``paste.config`` key to the request
+ environment, as well as registering the configuration temporarily
+ (for the length of the request) with ``paste.config.CONFIG``.
+ """
+
+ def __init__(self, application, config):
+ """
+ This delegates all requests to `application`, adding a *copy*
+ of the configuration `config`.
+ """
+ def register_config(environ, start_response):
+ popped_config = None
+ if 'paste.config' in environ:
+ popped_config = environ['paste.config']
+
+ conf = environ['paste.config'] = config.copy()
+ environ['paste.registry'].register(CONFIG, conf)
+
+ try:
+ app_iter = application(environ, start_response)
+ finally:
+ if popped_config is not None:
+ environ['paste.config'] = popped_config
+ return app_iter
+
+ super(self.__class__, self).__init__(register_config)
+
+def make_config_filter(app, global_conf, **local_conf):
+ conf = global_conf.copy()
+ conf.update(local_conf)
+ return ConfigMiddleware(app, conf)
+
+make_config_middleware = ConfigMiddleware.__doc__