diff options
| author | Chris McDonough <chrism@plope.com> | 2010-12-09 01:11:47 -0500 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2010-12-09 01:11:47 -0500 |
| commit | ca13fe0cb7244d4e405bd5a1083d80a8c7158fc7 (patch) | |
| tree | 075bc768af1b65149c353fa4502d4ac1de55e4d4 | |
| parent | aff4437e933d133c866555b71a6ebf3954264aeb (diff) | |
| download | pyramid-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.py | 190 | ||||
| -rw-r--r-- | pyramid/tests/test_config.py | 2 |
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) |
