summaryrefslogtreecommitdiff
path: root/paste/deploy
diff options
context:
space:
mode:
authorAlex Gr?nholm <alex.gronholm@nextday.fi>2011-05-24 02:08:17 +0300
committerAlex Gr?nholm <alex.gronholm@nextday.fi>2011-05-24 02:08:17 +0300
commitbb46e560c30f095b7a5344b64307bd7663b4bea5 (patch)
tree914b24f48ed37ee33ce17394e5c08d72ecb052f8 /paste/deploy
parenta977fb83c12475e71b96c587de785ad423b8f196 (diff)
parentf819a48f6744e2a26386f0035cfb9bc989772514 (diff)
downloadpastedeploy-bb46e560c30f095b7a5344b64307bd7663b4bea5.tar.gz
Added support for the call: protocol, contributed by Jason Stitt
Diffstat (limited to 'paste/deploy')
-rw-r--r--paste/deploy/loadwsgi.py49
-rw-r--r--paste/deploy/util.py14
2 files changed, 62 insertions, 1 deletions
diff --git a/paste/deploy/loadwsgi.py b/paste/deploy/loadwsgi.py
index 2da8213..fe24add 100644
--- a/paste/deploy/loadwsgi.py
+++ b/paste/deploy/loadwsgi.py
@@ -8,7 +8,7 @@ import re
import pkg_resources
from paste.deploy.compat import ConfigParser, unquote, iteritems
-from paste.deploy.util import fix_call
+from paste.deploy.util import fix_call, lookup_object
__all__ = ['loadapp', 'loadserver', 'loadfilter', 'appconfig']
@@ -332,6 +332,14 @@ def _loadegg(object_type, uri, spec, name, relative_to,
_loaders['egg'] = _loadegg
+def _loadfunc(object_type, uri, spec, name, relative_to,
+ global_conf):
+
+ loader = FuncLoader(spec)
+ return loader.get_context(object_type, name, global_conf)
+
+_loaders['call'] = _loadfunc
+
############################################################
## Loaders
############################################################
@@ -475,6 +483,20 @@ class ConfigLoader(_Loader):
context.global_conf['__file__'] = global_conf['__file__']
# @@: Should loader be overwritten?
context.loader = self
+
+ if context.protocol is None:
+ # Determine protocol from section type
+ section_protocol = section.split(':', 1)[0]
+ if section_protocol in ('application', 'app'):
+ context.protocol = 'paste.app_factory'
+ elif section_protocol in ('composit', 'composite'):
+ context.protocol = 'paste.composit_factory'
+ else:
+ # This will work with 'server' and 'filter', otherwise it
+ # could fail but there is an error message already for
+ # bad protocols
+ context.protocol = 'paste.%s_factory' % context_protocol
+
return context
def _context_from_explicit(self, object_type, local_conf, global_conf,
@@ -644,6 +666,31 @@ class EggLoader(_Loader):
return possible[0]
+class FuncLoader(_Loader):
+ """ Loader that supports specifying functions inside modules, without
+ using eggs at all. Configuration should be in the format:
+ use = call:my.module.path:function_name
+
+ Dot notation is supported in both the module and function name, e.g.:
+ use = call:my.module.path:object.method
+ """
+ def __init__(self, spec):
+ self.spec = spec
+ if not ':' in spec:
+ raise LookupError("Configuration not in format module:function")
+
+ def get_context(self, object_type, name=None, global_conf=None):
+ obj = lookup_object(self.spec)
+ return LoaderContext(
+ obj,
+ object_type,
+ None, # determine protocol from section type
+ global_conf or {},
+ {},
+ self,
+ )
+
+
class LoaderContext(object):
def __init__(self, obj, object_type, protocol,
diff --git a/paste/deploy/util.py b/paste/deploy/util.py
index c5056b2..02d3fa2 100644
--- a/paste/deploy/util.py
+++ b/paste/deploy/util.py
@@ -58,3 +58,17 @@ def fix_call(callable, *args, **kw):
exc_info = fix_type_error(None, callable, args, kw)
reraise(*exc_info)
return val
+
+
+def lookup_object(spec):
+ """
+ Looks up a module or object from a some.module:func_name specification.
+ To just look up a module, omit the colon and everything after it.
+ """
+ parts, target = spec.split(':') if ':' in spec else (spec, None)
+ module = __import__(parts)
+
+ for part in parts.split('.')[1:] + ([target] if target else []):
+ module = getattr(module, part)
+
+ return module