summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-08-22 21:36:21 -0400
committerChris McDonough <chrism@plope.com>2011-08-22 21:36:21 -0400
commiteb2fee960c0434a8369e252a930115e9c9356164 (patch)
tree6e8e63e5edfd83d4c7d634edb7e9293c2dba8f69
parent0025e98c245a170d319510b0ba02a1b745d7adc8 (diff)
downloadpyramid-eb2fee960c0434a8369e252a930115e9c9356164.tar.gz
pyramid-eb2fee960c0434a8369e252a930115e9c9356164.tar.bz2
pyramid-eb2fee960c0434a8369e252a930115e9c9356164.zip
first cut, tests fail
-rw-r--r--pyramid/config/__init__.py11
-rw-r--r--pyramid/config/adapters.py5
-rw-r--r--pyramid/config/assets.py1
-rw-r--r--pyramid/config/factories.py7
-rw-r--r--pyramid/config/rendering.py14
-rw-r--r--pyramid/config/routes.py21
-rw-r--r--pyramid/config/security.py35
-rw-r--r--pyramid/config/tweens.py14
-rw-r--r--pyramid/config/views.py37
-rw-r--r--pyramid/interfaces.py10
10 files changed, 81 insertions, 74 deletions
diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py
index c7ee8c47f..baae824ac 100644
--- a/pyramid/config/__init__.py
+++ b/pyramid/config/__init__.py
@@ -309,10 +309,6 @@ class Configurator(
self.commit()
- if default_view_mapper is not None:
- self.set_view_mapper(default_view_mapper)
- self.commit()
-
# The following registrations should be treated as if the methods had
# been called after configurator construction (commit should not be
# called after this). Rationale: user-supplied implementations
@@ -322,10 +318,13 @@ class Configurator(
if authentication_policy and not authorization_policy:
authorization_policy = ACLAuthorizationPolicy() # default
- if authentication_policy:
- self.set_authentication_policy(authentication_policy)
if authorization_policy:
self.set_authorization_policy(authorization_policy)
+ if authentication_policy:
+ self.set_authentication_policy(authentication_policy)
+
+ if default_view_mapper is not None:
+ self.set_view_mapper(default_view_mapper)
for name, renderer in renderers:
self.add_renderer(name, renderer)
diff --git a/pyramid/config/adapters.py b/pyramid/config/adapters.py
index f022e7f08..6c6ca92b7 100644
--- a/pyramid/config/adapters.py
+++ b/pyramid/config/adapters.py
@@ -1,6 +1,7 @@
from zope.interface import Interface
from pyramid.interfaces import IResponse
+from pyramid.interfaces import PHASE3_CONFIG
from pyramid.config.util import action_method
@@ -27,7 +28,7 @@ class AdaptersConfiguratorMixin(object):
iface = (iface,)
def register():
self.registry.registerHandler(subscriber, iface)
- self.action(None, register)
+ self.action(None, register, order=PHASE3_CONFIG)
return subscriber
@action_method
@@ -52,7 +53,7 @@ class AdaptersConfiguratorMixin(object):
reg.registerSelfAdapter((type_or_iface,), IResponse)
else:
reg.registerAdapter(adapter, (type_or_iface,), IResponse)
- self.action((IResponse, type_or_iface), register)
+ self.action((IResponse, type_or_iface), register, order=PHASE3_CONFIG)
def _register_response_adapters(self):
# cope with WebOb response objects that aren't decorated with IResponse
diff --git a/pyramid/config/assets.py b/pyramid/config/assets.py
index 931ffb74c..1b5254072 100644
--- a/pyramid/config/assets.py
+++ b/pyramid/config/assets.py
@@ -235,6 +235,7 @@ class AssetsConfiguratorMixin(object):
from_package = sys.modules[package]
to_package = sys.modules[override_package]
override(from_package, path, to_package, override_prefix)
+
self.action(None, register)
override_resource = override_asset # bw compat
diff --git a/pyramid/config/factories.py b/pyramid/config/factories.py
index 1421082cd..53db93c64 100644
--- a/pyramid/config/factories.py
+++ b/pyramid/config/factories.py
@@ -4,6 +4,7 @@ from pyramid.interfaces import IDefaultRootFactory
from pyramid.interfaces import IRequestFactory
from pyramid.interfaces import IRootFactory
from pyramid.interfaces import ISessionFactory
+from pyramid.interfaces import PHASE3_CONFIG
from pyramid.traversal import DefaultRootFactory
@@ -24,7 +25,7 @@ class FactoriesConfiguratorMixin(object):
def register():
self.registry.registerUtility(factory, IRootFactory)
self.registry.registerUtility(factory, IDefaultRootFactory) # b/c
- self.action(IRootFactory, register)
+ self.action(IRootFactory, register, order=PHASE3_CONFIG)
_set_root_factory = set_root_factory # bw compat
@@ -41,7 +42,7 @@ class FactoriesConfiguratorMixin(object):
"""
def register():
self.registry.registerUtility(session_factory, ISessionFactory)
- self.action(ISessionFactory, register)
+ self.action(ISessionFactory, register, order=PHASE3_CONFIG)
@action_method
def set_request_factory(self, factory):
@@ -60,5 +61,5 @@ class FactoriesConfiguratorMixin(object):
factory = self.maybe_dotted(factory)
def register():
self.registry.registerUtility(factory, IRequestFactory)
- self.action(IRequestFactory, register)
+ self.action(IRequestFactory, register, order=PHASE3_CONFIG)
diff --git a/pyramid/config/rendering.py b/pyramid/config/rendering.py
index 3096b3d8e..deb1404e7 100644
--- a/pyramid/config/rendering.py
+++ b/pyramid/config/rendering.py
@@ -2,6 +2,8 @@ import warnings
from pyramid.interfaces import IRendererFactory
from pyramid.interfaces import IRendererGlobalsFactory
+from pyramid.interfaces import PHASE1_CONFIG
+from pyramid.interfaces import PHASE3_CONFIG
from pyramid.config.util import action_method
@@ -49,10 +51,11 @@ class RenderingConfiguratorMixin(object):
# as a name
if not name:
name = ''
- # we need to register renderers eagerly because they are used during
- # view configuration
- self.registry.registerUtility(factory, IRendererFactory, name=name)
- self.action((IRendererFactory, name), None)
+ def register():
+ self.registry.registerUtility(factory, IRendererFactory, name=name)
+ # we need to register renderers early (in phase 1) because they are
+ # used during view configuration (which happens in phase 3)
+ self.action((IRendererFactory, name), register, order=PHASE1_CONFIG)
@action_method
def set_renderer_globals_factory(self, factory, warn=True):
@@ -86,5 +89,4 @@ class RenderingConfiguratorMixin(object):
factory = self.maybe_dotted(factory)
def register():
self.registry.registerUtility(factory, IRendererGlobalsFactory)
- self.action(IRendererGlobalsFactory, register)
-
+ self.action(IRendererGlobalsFactory, register, order=PHASE3_CONFIG)
diff --git a/pyramid/config/routes.py b/pyramid/config/routes.py
index 625ef436d..b83ca346c 100644
--- a/pyramid/config/routes.py
+++ b/pyramid/config/routes.py
@@ -3,6 +3,7 @@ import warnings
from pyramid.interfaces import IRequest
from pyramid.interfaces import IRouteRequest
from pyramid.interfaces import IRoutesMapper
+from pyramid.interfaces import PHASE2_CONFIG
from pyramid.exceptions import ConfigurationError
from pyramid.request import route_request_iface
@@ -353,10 +354,6 @@ class RoutesConfiguratorMixin(object):
request_iface = route_request_iface(name, bases)
self.registry.registerUtility(
request_iface, IRouteRequest, name=name)
- deferred_views = getattr(self.registry, 'deferred_route_views', {})
- view_info = deferred_views.pop(name, ())
- for info in view_info:
- self.add_view(**info)
# deprecated adding views from add_route
if any([view, view_context, view_permission, view_renderer,
@@ -370,8 +367,6 @@ class RoutesConfiguratorMixin(object):
attr=view_attr,
)
- mapper = self.get_routes_mapper()
-
factory = self.maybe_dotted(factory)
if pattern is None:
pattern = path
@@ -381,11 +376,17 @@ class RoutesConfiguratorMixin(object):
if self.route_prefix:
pattern = self.route_prefix.rstrip('/') + '/' + pattern.lstrip('/')
- discriminator = ('route', name)
- self.action(discriminator, None)
+ mapper = self.get_routes_mapper()
+
+ def register():
+ return mapper.connect(name, pattern, factory, predicates=predicates,
+ pregenerator=pregenerator, static=static)
+
- return mapper.connect(name, pattern, factory, predicates=predicates,
- pregenerator=pregenerator, static=static)
+ # route actions must run before view registration actions; all
+ # IRouteRequest interfaces must be registered before we begin to
+ # process view registrations
+ self.action(('route', name), register, order=PHASE2_CONFIG)
def get_routes_mapper(self):
""" Return the :term:`routes mapper` object associated with
diff --git a/pyramid/config/security.py b/pyramid/config/security.py
index 897d4bbec..96e2c1479 100644
--- a/pyramid/config/security.py
+++ b/pyramid/config/security.py
@@ -1,6 +1,8 @@
from pyramid.interfaces import IAuthorizationPolicy
from pyramid.interfaces import IAuthenticationPolicy
from pyramid.interfaces import IDefaultPermission
+from pyramid.interfaces import PHASE1_CONFIG
+from pyramid.interfaces import PHASE2_CONFIG
from pyramid.exceptions import ConfigurationError
from pyramid.config.util import action_method
@@ -18,18 +20,16 @@ class SecurityConfiguratorMixin(object):
can be used to achieve the same purpose.
"""
- self._set_authentication_policy(policy)
- def ensure():
- if self.autocommit:
- return
+ def register():
+ self._set_authentication_policy(policy)
if self.registry.queryUtility(IAuthorizationPolicy) is None:
raise ConfigurationError(
'Cannot configure an authentication policy without '
'also configuring an authorization policy '
- '(see the set_authorization_policy method)')
- self.action(IAuthenticationPolicy, callable=ensure)
+ '(use the set_authorization_policy method)')
+ # authentication policy used by view config (phase 3)
+ self.action(IAuthenticationPolicy, register, order=PHASE2_CONFIG)
- @action_method
def _set_authentication_policy(self, policy):
policy = self.maybe_dotted(policy)
self.registry.registerUtility(policy, IAuthenticationPolicy)
@@ -45,16 +45,12 @@ class SecurityConfiguratorMixin(object):
:class:`pyramid.config.Configurator` constructor
can be used to achieve the same purpose.
"""
- self._set_authorization_policy(policy)
- def ensure():
- if self.registry.queryUtility(IAuthenticationPolicy) is None:
- raise ConfigurationError(
- 'Cannot configure an authorization policy without also '
- 'configuring an authentication policy '
- '(see the set_authentication_policy method)')
- self.action(IAuthorizationPolicy, callable=ensure)
+ def register():
+ self._set_authorization_policy(policy)
+ # authorization policy used by view config (phase 3) and
+ # authentication policy (phase 2)
+ self.action(IAuthorizationPolicy, register, order=PHASE1_CONFIG)
- @action_method
def _set_authorization_policy(self, policy):
policy = self.maybe_dotted(policy)
self.registry.registerUtility(policy, IAuthorizationPolicy)
@@ -96,8 +92,9 @@ class SecurityConfiguratorMixin(object):
:class:`pyramid.config.Configurator` constructor
can be used to achieve the same purpose.
"""
- # default permission used during view registration
- self.registry.registerUtility(permission, IDefaultPermission)
- self.action(IDefaultPermission, None)
+ # default permission used during view registration (phase 3)
+ def register():
+ self.registry.registerUtility(permission, IDefaultPermission)
+ self.action(IDefaultPermission, register, order=PHASE1_CONFIG)
diff --git a/pyramid/config/tweens.py b/pyramid/config/tweens.py
index be7f3d478..bf127b5df 100644
--- a/pyramid/config/tweens.py
+++ b/pyramid/config/tweens.py
@@ -1,6 +1,7 @@
from zope.interface import implements
from pyramid.interfaces import ITweens
+from pyramid.interfaces import PHASE3_CONFIG
from pyramid.exceptions import ConfigurationError
from pyramid.tweens import excview_tween_factory
@@ -128,17 +129,20 @@ class TweensConfiguratorMixin(object):
raise ConfigurationError('%s cannot be under MAIN' % name)
registry = self.registry
+
tweens = registry.queryUtility(ITweens)
if tweens is None:
tweens = Tweens()
registry.registerUtility(tweens, ITweens)
tweens.add_implicit(EXCVIEW, excview_tween_factory, over=MAIN)
- if explicit:
- tweens.add_explicit(name, tween_factory)
- else:
- tweens.add_implicit(name, tween_factory, under=under, over=over)
- self.action(('tween', name, explicit))
+ def register():
+ if explicit:
+ tweens.add_explicit(name, tween_factory)
+ else:
+ tweens.add_implicit(name, tween_factory, under=under, over=over)
+
+ self.action(('tween', name, explicit), register, order=PHASE3_CONFIG)
class CyclicDependencyError(Exception):
def __init__(self, cycles):
diff --git a/pyramid/config/views.py b/pyramid/config/views.py
index 2d39524ac..633906468 100644
--- a/pyramid/config/views.py
+++ b/pyramid/config/views.py
@@ -25,6 +25,8 @@ from pyramid.interfaces import IViewClassifier
from pyramid.interfaces import IRequest
from pyramid.interfaces import IRouteRequest
from pyramid.interfaces import IRendererFactory
+from pyramid.interfaces import PHASE1_CONFIG
+from pyramid.interfaces import PHASE3_CONFIG
from pyramid.exceptions import ConfigurationError
from pyramid.exceptions import PredicateMismatch
@@ -874,24 +876,11 @@ class ViewsConfiguratorMixin(object):
request_iface = self.registry.queryUtility(IRouteRequest,
name=route_name)
if request_iface is None:
- deferred_views = getattr(self.registry,
- 'deferred_route_views', None)
- if deferred_views is None:
- deferred_views = self.registry.deferred_route_views = {}
- info = dict(
- view=view, name=name, for_=for_, permission=permission,
- request_type=request_type, route_name=route_name,
- request_method=request_method, request_param=request_param,
- containment=containment, attr=attr,
- renderer=renderer, wrapper=wrapper, xhr=xhr, accept=accept,
- header=header, path_info=path_info,
- custom_predicates=custom_predicates, context=context,
- mapper = mapper, http_cache = http_cache,
- )
- view_info = deferred_views.setdefault(route_name, [])
- view_info.append(info)
- return
-
+ # route configuration should have already happened
+ raise ConfigurationError(
+ 'No route named %s found for view registration' %
+ route_name)
+
order, predicates, phash = make_predicates(xhr=xhr,
request_method=request_method, path_info=path_info,
request_param=request_param, header=header, accept=accept,
@@ -914,7 +903,7 @@ class ViewsConfiguratorMixin(object):
def register(permission=permission, renderer=renderer):
if renderer is None:
- # use default renderer if one exists
+ # use default renderer if one exists (reg'd in phase 1)
if self.registry.queryUtility(IRendererFactory) is not None:
renderer = renderers.RendererHelper(
name=None,
@@ -923,6 +912,7 @@ class ViewsConfiguratorMixin(object):
if permission is None:
# intent: will be None if no default permission is registered
+ # (reg'd in phase 1)
permission = self.registry.queryUtility(IDefaultPermission)
# __no_permission_required__ handled by _secure_view
@@ -1044,7 +1034,7 @@ class ViewsConfiguratorMixin(object):
xhr, accept, header, path_info]
discriminator.extend(sorted(custom_predicates))
discriminator = tuple(discriminator)
- self.action(discriminator, register)
+ self.action(discriminator, register, order=PHASE3_CONFIG)
def derive_view(self, view, attr=None, renderer=None):
"""
@@ -1263,8 +1253,11 @@ class ViewsConfiguratorMixin(object):
can be used to achieve the same purpose.
"""
mapper = self.maybe_dotted(mapper)
- self.registry.registerUtility(mapper, IViewMapperFactory)
- self.action(IViewMapperFactory, None)
+ def register():
+ self.registry.registerUtility(mapper, IViewMapperFactory)
+ # IViewMapperFactory is looked up as the result of view config
+ # in phase 3
+ self.action(IViewMapperFactory, register, order=PHASE1_CONFIG)
@action_method
def add_static_view(self, name, path, **kw):
diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py
index 6864e5dfb..408135711 100644
--- a/pyramid/interfaces.py
+++ b/pyramid/interfaces.py
@@ -847,4 +847,12 @@ class IRendererInfo(Interface):
'renderer was created')
settings = Attribute('The deployment settings dictionary related '
'to the current application')
-
+
+
+# configuration phases: a lower phase number means the actions associated
+# with this phase will be executed earlier than those with later phase
+# numbers
+
+PHASE1_CONFIG = -20
+PHASE2_CONFIG = -10
+PHASE3_CONFIG = 0