summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2010-12-09 01:11:47 -0500
committerChris McDonough <chrism@plope.com>2010-12-09 01:11:47 -0500
commitca13fe0cb7244d4e405bd5a1083d80a8c7158fc7 (patch)
tree075bc768af1b65149c353fa4502d4ac1de55e4d4
parentaff4437e933d133c866555b71a6ebf3954264aeb (diff)
downloadpyramid-ca13fe0cb7244d4e405bd5a1083d80a8c7158fc7.tar.gz
pyramid-ca13fe0cb7244d4e405bd5a1083d80a8c7158fc7.tar.bz2
pyramid-ca13fe0cb7244d4e405bd5a1083d80a8c7158fc7.zip
get rid of config_method decorator; rename _action to action
-rw-r--r--pyramid/config.py190
-rw-r--r--pyramid/tests/test_config.py2
2 files changed, 106 insertions, 86 deletions
diff --git a/pyramid/config.py b/pyramid/config.py
index 87981a0f8..7d2da8b8d 100644
--- a/pyramid/config.py
+++ b/pyramid/config.py
@@ -103,32 +103,6 @@ if chameleon_text:
if chameleon_zpt:
DEFAULT_RENDERERS += (('.txt', chameleon_text.renderer_factory),)
-def config_method(wrapped):
- def wrapper(self, *arg, **kw):
- context = self._ctx
- if context is not None:
- if (not context.autocommit) and (not context.info):
- # Try to provide more accurate info for conflict reports by
- # wrapping the context in a decorator and attaching caller info
- # to it, unless the context already has info (if it already has
- # info, it's likely a context generated by a ZCML directive).
- # This is nasty.
- newctx = GroupingContextDecorator(context)
- try:
- f = traceback.extract_stack(limit=3)
- info = f[-2]
- except:
- info = ''
- newctx.info = info
- self._ctx = newctx
- result = wrapped(self, *arg, **kw)
- if context is not None:
- self._ctx = context
- return result
- wrapper.__doc__ = wrapped.__doc__
- wrapper.__name__ = wrapped.__name__
- return wrapper
-
class Configurator(object):
"""
A Configurator is used to configure a :app:`Pyramid`
@@ -236,7 +210,19 @@ class Configurator(object):
default, this argument is ``None``, indicating that no session
factory will be configured (and thus accessing ``request.session``
will throw an error) unless ``set_session_factory`` is called later
- during configuration. """
+ during configuration.
+
+ If ``autocommit`` is ``True``, every method called on the configurator
+ will cause an immediate action, and no configuration conflict detection
+ will be used. If ``autocommit`` is ``False``, most methods of the
+ configurator will defer their action until
+ :meth:`pyramid.config.Configurator.commit` is called. When
+ :meth:`pyramid.config.Configurator.commit` is called, the actions implied
+ by the called methods will be checked for configuration conflicts unless
+ ``autocommit`` is ``True``. If a conflict is detected a
+ ``ConfigurationConflictError`` will be raised. NB: calling
+ :meth:`pyramid.config.Configurator.make_wsgi_app` always implies a final
+ commit."""
manager = manager # for testing injection
venusian = venusian # for testing injection
@@ -283,24 +269,12 @@ class Configurator(object):
session_factory=session_factory,
)
- def _action(self, discriminator, callable=None, args=(), kw=None, order=0):
- """ Register an action which will be executed during a commit. """
- if kw is None:
- kw = {}
- if self.autocommit:
- if callable is not None:
- callable(*args, **kw)
- else:
- if self._ctx is None:
- self._ctx = self._make_context(self.autocommit)
- self._ctx.action(discriminator, callable, args, kw, order)
-
def _set_settings(self, mapping):
settings = Settings(mapping or {})
self.registry.settings = settings
return settings
- @config_method
+ #@action_method
def _set_root_factory(self, factory):
""" Add a :term:`root factory` to the current configuration
state. If the ``factory`` argument is ``None`` a default root
@@ -311,24 +285,24 @@ class Configurator(object):
def register():
self.registry.registerUtility(factory, IRootFactory)
self.registry.registerUtility(factory, IDefaultRootFactory) # b/c
- self._action(IRootFactory, register)
+ self.action(IRootFactory, register)
- @config_method
+ #@action_method
def _set_authentication_policy(self, policy):
""" Add a :app:`Pyramid` :term:`authentication policy` to
the current configuration."""
policy = self.maybe_dotted(policy)
self.registry.registerUtility(policy, IAuthenticationPolicy)
- self._action(IAuthenticationPolicy)
+ self.action(IAuthenticationPolicy)
- @config_method
+ #@action_method
def _set_authorization_policy(self, policy):
""" Add a :app:`Pyramid` :term:`authorization policy` to
the current configuration state (also accepts a :term:`dotted
Python name`."""
policy = self.maybe_dotted(policy)
self.registry.registerUtility(policy, IAuthorizationPolicy)
- self._action(IAuthorizationPolicy, None)
+ self.action(IAuthorizationPolicy, None)
def _make_spec(self, path_or_spec):
package, filename = resolve_resource_spec(path_or_spec,
@@ -412,8 +386,56 @@ class Configurator(object):
# API
+ def action(self, discriminator, callable=None, args=(), kw=None, order=0):
+ """ Register an action which will be executed when
+ :meth:`pyramid.config.Configuration.commit` is called (or executed
+ immediately if ``autocommit`` is ``True``).
+
+ .. note:: This method is typically only used by :app:`Pyramid`
+ framework extension authors, not by :app:`Pyramid` application
+ developers.
+
+ The ``discriminator`` uniquely identifies the action. It must be
+ given, but it can be ``None``, to indicate that the action never
+ conflicts. It must be a hashable value.
+
+ The ``callable`` is a callable object which performs the action. It
+ is optional. ``args`` and ``kw`` are tuple and dict objects
+ respectively, which are passed to ``callable`` when this action is
+ executed.
+
+ ``order`` is a crude order control mechanism, rarely used.
+ """
+ if kw is None:
+ kw = {}
+ if self.autocommit:
+ if callable is not None:
+ callable(*args, **kw)
+ else:
+ context = self._ctx
+ if context is None: # defer expensive creation of context
+ context = self._ctx = self._make_context(self.autocommit)
+ if not context.info:
+ # Try to provide more accurate info for conflict reports by
+ # wrapping the context in a decorator and attaching caller info
+ # to it, unless the context already has info (if it already has
+ # info, it's likely a context generated by a ZCML directive).
+ context = GroupingContextDecorator(context)
+ try:
+ f = traceback.extract_stack(limit=3)
+ info = f[-3]
+ except: # pragma: no cover
+ info = ''
+ context.info = info
+ context.action(discriminator, callable, args, kw, order)
+
def commit(self):
- """ Commit pending configuration actions. """
+ """ Commit any pending configuration actions added. If a
+ configuration conflict has occurred, this method will raise a
+ :exc:`ConfigurationConflictError`; within the traceback of this error
+ will be information about the source of the conflict, usually
+ including file names and line numbers of the cause of the
+ configuration conflicts."""
if self._ctx is None:
return
self._ctx.execute_actions()
@@ -472,23 +494,21 @@ class Configurator(object):
default_permission=None,
session_factory=None):
""" When you pass a non-``None`` ``registry`` argument to the
- :term:`Configurator` constructor, no initial 'setup' is
- performed against the registry. This is because the registry
- you pass in may have already been initialized for use under
- :app:`Pyramid` via a different configurator. However, in
- some circumstances, such as when you want to use the Zope
- 'global` registry instead of a registry created as a result of
- the Configurator constructor, or when you want to reset the
- initial setup of a registry, you *do* want to explicitly
- initialize the registry associated with a Configurator for use
- under :app:`Pyramid`. Use ``setup_registry`` to do this
+ :term:`Configurator` constructor, no initial 'setup' is performed
+ against the registry. This is because the registry you pass in may
+ have already been initialized for use under :app:`Pyramid` via a
+ different configurator. However, in some circumstances (such as when
+ you want to use the Zope 'global` registry instead of a registry
+ created as a result of the Configurator constructor), or when you
+ want to reset the initial setup of a registry, you *do* want to
+ explicitly initialize the registry associated with a Configurator for
+ use under :app:`Pyramid`. Use ``setup_registry`` to do this
initialization.
- ``setup_registry`` configures settings, a root factory,
- security policies, renderers, a debug logger, a locale
- negotiator, and various other settings using the
- configurator's current registry, as per the descriptions in
- the Configurator constructor."""
+ ``setup_registry`` configures settings, a root factory, security
+ policies, renderers, a debug logger, a locale negotiator, and various
+ other settings using the configurator's current registry, as per the
+ descriptions in the Configurator constructor."""
registry = self.registry
self._fix_registry()
self._set_settings(settings)
@@ -641,7 +661,7 @@ class Configurator(object):
renderer = {'name':renderer, 'package':self.package}
return self._derive_view(view, attr=attr, renderer=renderer)
- @config_method
+ #@action_method
def add_subscriber(self, subscriber, iface=None):
"""Add an event :term:`subscriber` for the event stream
implied by the supplied ``iface`` interface. The
@@ -663,7 +683,7 @@ class Configurator(object):
iface = (iface,)
def register():
self.registry.registerHandler(subscriber, iface)
- self._action(None, register)
+ self.action(None, register)
return subscriber
def add_settings(self, settings=None, **kw):
@@ -728,7 +748,7 @@ class Configurator(object):
self.manager.pop()
return app
- @config_method
+ #@action_method
def load_zcml(self, spec='configure.zcml', lock=threading.Lock()):
""" Load configuration from a :term:`ZCML` file into the
current configuration state. The ``spec`` argument is an
@@ -752,7 +772,7 @@ class Configurator(object):
try:
context.package = package
xmlconfig.file(filename, package, context=context,
- execute=self.autocommit)
+ execute=context.autocommit)
finally:
lock.release()
self.manager.pop()
@@ -907,7 +927,7 @@ class Configurator(object):
return route
- @config_method
+ #@action_method
def add_view(self, view=None, name="", for_=None, permission=None,
request_type=None, route_name=None, request_method=None,
request_param=None, containment=None, attr=None,
@@ -1333,9 +1353,9 @@ class Configurator(object):
xhr, accept, header, path_info]
discriminator.extend(sorted(custom_predicates))
discriminator = tuple(discriminator)
- self._action(discriminator, register)
+ self.action(discriminator, register)
- @config_method
+ #@action_method
def add_route(self,
name,
pattern=None,
@@ -1683,7 +1703,7 @@ class Configurator(object):
discriminator.extend(sorted(custom_predicates))
discriminator = tuple(discriminator)
- self._action(discriminator, None)
+ self.action(discriminator, None)
return mapper.connect(name, pattern, factory, predicates=predicates,
pregenerator=pregenerator)
@@ -1697,7 +1717,7 @@ class Configurator(object):
self.registry.registerUtility(mapper, IRoutesMapper)
return mapper
- @config_method
+ #@action_method
def scan(self, package=None, categories=None):
""" Scan a Python package and any of its subpackages for
objects marked with :term:`configuration decoration` such as
@@ -1733,7 +1753,7 @@ class Configurator(object):
scanner = self.venusian.Scanner(config=self)
scanner.scan(package, categories=categories)
- @config_method
+ #@action_method
def add_renderer(self, name, factory):
"""
Add a :app:`Pyramid` :term:`renderer` factory to the
@@ -1763,9 +1783,9 @@ class Configurator(object):
# 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)
+ self.action((IRendererFactory, name), None)
- @config_method
+ #@action_method
def override_resource(self, to_override, override_with, _override=None):
""" Add a :app:`Pyramid` resource override to the current
configuration state.
@@ -1811,7 +1831,7 @@ class Configurator(object):
from_package = sys.modules[package]
to_package = sys.modules[override_package]
override(from_package, path, to_package, override_prefix)
- self._action(None, register)
+ self.action(None, register)
def set_forbidden_view(self, view=None, attr=None, renderer=None,
wrapper=None):
@@ -1887,7 +1907,7 @@ class Configurator(object):
return view(context, request)
return self.add_view(bwcompat_view, context=NotFound, wrapper=wrapper)
- @config_method
+ #@action_method
def set_request_factory(self, factory):
""" The object passed as ``factory`` should be an object (or a
:term:`dotted Python name` which refers to an object) which
@@ -1904,9 +1924,9 @@ class Configurator(object):
factory = self.maybe_dotted(factory)
def register():
self.registry.registerUtility(factory, IRequestFactory)
- self._action(IRequestFactory, register)
+ self.action(IRequestFactory, register)
- @config_method
+ #@action_method
def set_renderer_globals_factory(self, factory):
""" The object passed as ``factory`` should be an callable (or
a :term:`dotted Python name` which refers to an callable) that
@@ -1928,9 +1948,9 @@ class Configurator(object):
factory = self.maybe_dotted(factory)
def register():
self.registry.registerUtility(factory, IRendererGlobalsFactory)
- self._action(IRendererGlobalsFactory, register)
+ self.action(IRendererGlobalsFactory, register)
- @config_method
+ #@action_method
def set_locale_negotiator(self, negotiator):
"""
Set the :term:`locale negotiator` for this application. The
@@ -1952,9 +1972,9 @@ class Configurator(object):
negotiator = self.maybe_dotted(negotiator)
def register():
self.registry.registerUtility(negotiator, ILocaleNegotiator)
- self._action(ILocaleNegotiator, register)
+ self.action(ILocaleNegotiator, register)
- @config_method
+ #@action_method
def set_default_permission(self, permission):
"""
Set the default permission to be used by all subsequent
@@ -1983,9 +2003,9 @@ class Configurator(object):
"""
# default permission used during view registration
self.registry.registerUtility(permission, IDefaultPermission)
- self._action(IDefaultPermission, None)
+ self.action(IDefaultPermission, None)
- @config_method
+ #@action_method
def set_session_factory(self, session_factory):
"""
Configure the application with a :term:`session factory`. If
@@ -1994,9 +2014,9 @@ class Configurator(object):
"""
def register():
self.registry.registerUtility(session_factory, ISessionFactory)
- self._action(ISessionFactory, register)
+ self.action(ISessionFactory, register)
- @config_method
+ #@action_method
def add_translation_dirs(self, *specs):
""" Add one or more :term:`translation directory` paths to the
current configuration state. The ``specs`` argument is a
diff --git a/pyramid/tests/test_config.py b/pyramid/tests/test_config.py
index 2a41f1504..7f84362ab 100644
--- a/pyramid/tests/test_config.py
+++ b/pyramid/tests/test_config.py
@@ -4569,5 +4569,5 @@ class DummyHandler(object): # pragma: no cover
return 'response 2'
def dummy_include(config):
- config._action('discrim', None, config.package)
+ config.action('discrim', None, config.package)