Merge branch 'master' of github.com:djay/pyramid
1 files deleted
3 files added
20 files modified
| | |
| | | Next release |
| | | ============ |
| | | |
| | | - When a ``renderers=`` argument is not specified to the Configurator |
| | | constructor, eagerly register and commit the default renderer set. This |
| | | permits the overriding of the default renderers, which was broken in 1.2a1 |
| | | without a commit directly after Configurator construction. |
| | | |
| | | 1.2a1 (2011-08-24) |
| | | ================== |
| | | |
| | | Features |
| | | -------- |
| | | |
| | |
| | | instead make a separate call to the method for each callable. This change |
| | | was introduced to support the ``route_prefix`` feature of include. |
| | | |
| | | - It may be necessary to more strictly order configuration route and view |
| | | statements when using an "autocommitting" Configurator. In the past, it |
| | | was possible to add a view which named a route name before adding a route |
| | | with that name when you used an autocommitting configurator. For example:: |
| | | |
| | | config = Configurator(autocommit=True) |
| | | config.add_view('my.pkg.someview', route_name='foo') |
| | | config.add_route('foo', '/foo') |
| | | |
| | | The above will raise an exception when the view attempts to add itself. |
| | | Now you must add the route before adding the view:: |
| | | |
| | | config = Configurator(autocommit=True) |
| | | config.add_route('foo', '/foo') |
| | | config.add_view('my.pkg.someview', route_name='foo') |
| | | |
| | | This won't effect "normal" users, only people who have legacy BFG codebases |
| | | that used an autommitting configurator and possibly tests that use the |
| | | configurator API (the configurator returned by ``pyramid.testing.setUp`` is |
| | | an autocommitting configurator). The right way to get around this is to |
| | | use a non-autocommitting configurator (the default), which does not have |
| | | these directive ordering requirements. |
| | | |
| | | - The ``pyramid.config.Configurator.add_route`` directive no longer returns a |
| | | route object. This change was required to make route vs. view |
| | | configuration processing work properly. |
| | | |
| | | Documentation |
| | | ------------- |
| | | |
| | |
| | | Pyramid is the newest web framework produced by the `Pylons Project |
| | | <http://pylonsproject.org/>`_. |
| | | |
| | | Pyramid was previously known as `repoze.bfg <http://bfg.repoze.org>`_. |
| | | |
| | | Support and Documentation |
| | | ------------------------- |
| | | |
| | |
| | | deploying via proxy: |
| | | https://docs.pylonsproject.org/projects/pyramid_cookbook/dev/deployment/nginx.html#step-2-starting-paster |
| | | |
| | | - Fix conflict behavior for routes and auth policies (define phases and use |
| | | order=). |
| | | |
| | | Nice-to-Have |
| | | ------------ |
| | | |
| | | - Add a default-view-config-params decorator that can be applied to a class |
| | | which names defaults for method-based view_config decorator options. |
| | | |
| | | - Flesh out "paste" chapter. |
| | | |
| | | - Move config-related stuff from "renderers" to config/rendering, and |
| | |
| | | # other places throughout the built documents. |
| | | # |
| | | # The short X.Y version. |
| | | version = '1.2dev' |
| | | version = '1.2a1' |
| | | # The full version, including alpha/beta/rc tags. |
| | | release = version |
| | | |
| | |
| | | :meth:`pyramid.config.Configurator.include`, it will break. You now must |
| | | now instead make a separate call to the method for each callable. |
| | | |
| | | - It may be necessary to more strictly order configuration route and view |
| | | statements when using an "autocommitting" :term:`Configurator`. In the |
| | | past, it was possible to add a view which named a route name before adding |
| | | a route with that name when you used an autocommitting configurator. For |
| | | example: |
| | | |
| | | .. code-block:: python |
| | | |
| | | config = Configurator(autocommit=True) |
| | | config.add_view('my.pkg.someview', route_name='foo') |
| | | config.add_route('foo', '/foo') |
| | | |
| | | The above will raise an exception when the view attempts to add itself. |
| | | Now you must add the route before adding the view: |
| | | |
| | | .. code-block:: python |
| | | |
| | | config = Configurator(autocommit=True) |
| | | config.add_route('foo', '/foo') |
| | | config.add_view('my.pkg.someview', route_name='foo') |
| | | |
| | | This won't effect "normal" users, only people who have legacy BFG codebases |
| | | that used an autommitting configurator and possibly tests that use the |
| | | configurator API (the configurator returned by |
| | | :func:`pyramid.testing.setUp` is an autocommitting configurator). The |
| | | right way to get around this is to use a default non-autocommitting |
| | | configurator, which does not have these directive ordering requirements: |
| | | |
| | | .. code-block:: python |
| | | |
| | | config = Configurator() |
| | | config.add_view('my.pkg.someview', route_name='foo') |
| | | config.add_route('foo', '/foo') |
| | | |
| | | The above will work fine. |
| | | |
| | | - The :meth:`pyramid.config.Configurator.add_route` directive no longer |
| | | returns a route object. This change was required to make route vs. view |
| | | configuration processing work properly. |
| | | |
| | | Documentation Enhancements |
| | | -------------------------- |
| | | |
| | |
| | | self.add_view(exceptionresponse_view, context=IExceptionResponse) |
| | | self.add_view(exceptionresponse_view,context=WebobWSGIHTTPException) |
| | | |
| | | # commit before adding default_view_mapper, as the |
| | | # exceptionresponse_view above requires the superdefault view |
| | | # mapper |
| | | # commit below because: |
| | | # |
| | | # - the default exceptionresponse_view requires the superdefault view |
| | | # mapper, so we need to configure it before adding default_view_mapper |
| | | # |
| | | # - superdefault renderers should be overrideable without requiring |
| | | # the user to commit before calling config.add_renderer |
| | | |
| | | 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 |
| | | # should be preferred rather than add-on author implementations (as |
| | | # per automatic conflict resolution). |
| | | # self.commit() should not be called after this point because the |
| | | # following registrations should be treated as analogues of methods |
| | | # called by the user after configurator construction. Rationale: |
| | | # user-supplied implementations should be preferred rather than |
| | | # add-on author implementations with the help of automatic conflict |
| | | # resolution. |
| | | |
| | | 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) |
| | |
| | | from zope.interface import Interface |
| | | |
| | | from pyramid.interfaces import IResponse |
| | | from pyramid.interfaces import PHASE3_CONFIG |
| | | |
| | | from pyramid.config.util import action_method |
| | | |
| | |
| | | iface = (iface,) |
| | | def register(): |
| | | self.registry.registerHandler(subscriber, iface) |
| | | self.action(None, register) |
| | | self.action(None, register, order=PHASE3_CONFIG) |
| | | return subscriber |
| | | |
| | | @action_method |
| | |
| | | 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 |
| | |
| | | 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 |
| | |
| | | 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 |
| | | |
| | |
| | | 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 |
| | | |
| | |
| | | """ |
| | | 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): |
| | |
| | | factory = self.maybe_dotted(factory) |
| | | def register(): |
| | | self.registry.registerUtility(factory, IRequestFactory) |
| | | self.action(IRequestFactory, register) |
| | | self.action(IRequestFactory, register, order=PHASE3_CONFIG) |
| | | |
| | |
| | | |
| | | 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 |
| | | |
| | |
| | | # 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): |
| | |
| | | factory = self.maybe_dotted(factory) |
| | | def register(): |
| | | self.registry.registerUtility(factory, IRendererGlobalsFactory) |
| | | self.action(IRendererGlobalsFactory, register) |
| | | |
| | | self.action(IRendererGlobalsFactory, register, order=PHASE3_CONFIG) |
| | |
| | | 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 |
| | |
| | | custom=custom_predicates |
| | | ) |
| | | |
| | | request_iface = self.registry.queryUtility(IRouteRequest, name=name) |
| | | if request_iface is None: |
| | | if use_global_views: |
| | | bases = (IRequest,) |
| | | else: |
| | | bases = () |
| | | 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) |
| | | factory = self.maybe_dotted(factory) |
| | | if pattern is None: |
| | | pattern = path |
| | | if pattern is None: |
| | | raise ConfigurationError('"pattern" argument may not be None') |
| | | |
| | | # deprecated adding views from add_route |
| | | if self.route_prefix: |
| | | pattern = self.route_prefix.rstrip('/') + '/' + pattern.lstrip('/') |
| | | |
| | | mapper = self.get_routes_mapper() |
| | | |
| | | def register_route_request_iface(): |
| | | request_iface = self.registry.queryUtility(IRouteRequest, name=name) |
| | | if request_iface is None: |
| | | if use_global_views: |
| | | bases = (IRequest,) |
| | | else: |
| | | bases = () |
| | | request_iface = route_request_iface(name, bases) |
| | | self.registry.registerUtility( |
| | | request_iface, IRouteRequest, name=name) |
| | | |
| | | def register_connect(): |
| | | return mapper.connect(name, pattern, factory, predicates=predicates, |
| | | pregenerator=pregenerator, static=static) |
| | | |
| | | |
| | | # We have to connect routes in the order they were provided; |
| | | # we can't use a phase to do that, because when the actions are |
| | | # sorted, actions in the same phase lose relative ordering |
| | | self.action(('route-connect', name), register_connect) |
| | | |
| | | # But IRouteRequest interfaces must be registered before we begin to |
| | | # process view registrations (in phase 3) |
| | | self.action(('route', name), register_route_request_iface, |
| | | order=PHASE2_CONFIG) |
| | | |
| | | # deprecated adding views from add_route; must come after |
| | | # route registration for purposes of autocommit ordering |
| | | if any([view, view_context, view_permission, view_renderer, |
| | | view_for, for_, permission, renderer, view_attr]): |
| | | self._add_view_from_route( |
| | |
| | | renderer=view_renderer or renderer, |
| | | attr=view_attr, |
| | | ) |
| | | |
| | | mapper = self.get_routes_mapper() |
| | | |
| | | factory = self.maybe_dotted(factory) |
| | | if pattern is None: |
| | | pattern = path |
| | | if pattern is None: |
| | | raise ConfigurationError('"pattern" argument may not be None') |
| | | |
| | | if self.route_prefix: |
| | | pattern = self.route_prefix.rstrip('/') + '/' + pattern.lstrip('/') |
| | | |
| | | discriminator = ('route', name) |
| | | self.action(discriminator, None) |
| | | |
| | | return mapper.connect(name, pattern, factory, predicates=predicates, |
| | | pregenerator=pregenerator, static=static) |
| | | |
| | | def get_routes_mapper(self): |
| | | """ Return the :term:`routes mapper` object associated with |
| | |
| | | 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.interfaces import PHASE3_CONFIG |
| | | |
| | | from pyramid.exceptions import ConfigurationError |
| | | from pyramid.config.util import action_method |
| | |
| | | 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) |
| | |
| | | :class:`pyramid.config.Configurator` constructor |
| | | can be used to achieve the same purpose. |
| | | """ |
| | | self._set_authorization_policy(policy) |
| | | def register(): |
| | | self._set_authorization_policy(policy) |
| | | def ensure(): |
| | | if self.autocommit: |
| | | return |
| | | 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) |
| | | 'Cannot configure an authorization policy without ' |
| | | 'also configuring an authentication policy ' |
| | | '(use the set_authorization_policy method)') |
| | | |
| | | # authorization policy used by view config (phase 3) and |
| | | # authentication policy (phase 2) |
| | | self.action(IAuthorizationPolicy, register, order=PHASE1_CONFIG) |
| | | self.action(None, ensure, order=PHASE3_CONFIG) |
| | | |
| | | @action_method |
| | | def _set_authorization_policy(self, policy): |
| | | policy = self.maybe_dotted(policy) |
| | | self.registry.registerUtility(policy, IAuthorizationPolicy) |
| | |
| | | :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) |
| | | |
| | | |
| | |
| | | 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 |
| | |
| | | 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): |
| | |
| | | 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 |
| | |
| | | raise ConfigurationError( |
| | | 'request_type must be an interface, not %s' % request_type) |
| | | |
| | | request_iface = IRequest |
| | | |
| | | if route_name is not None: |
| | | 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, |
| | | match_param=match_param, |
| | | custom_predicates=custom_predicates, context=context, |
| | | mapper = mapper, http_cache = http_cache, |
| | | ) |
| | | view_info = deferred_views.setdefault(route_name, []) |
| | | view_info.append(info) |
| | | return |
| | | |
| | | order, predicates, phash = make_predicates(xhr=xhr, |
| | | request_method=request_method, path_info=path_info, |
| | | request_param=request_param, header=header, accept=accept, |
| | |
| | | registry = self.registry) |
| | | |
| | | def register(permission=permission, renderer=renderer): |
| | | request_iface = IRequest |
| | | if route_name is not None: |
| | | request_iface = self.registry.queryUtility(IRouteRequest, |
| | | name=route_name) |
| | | if request_iface is None: |
| | | # route configuration should have already happened in |
| | | # phase 2 |
| | | raise ConfigurationError( |
| | | 'No route named %s found for view registration' % |
| | | route_name) |
| | | |
| | | 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, |
| | |
| | | |
| | | 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 |
| | |
| | | |
| | | discriminator = [ |
| | | 'view', context, name, request_type, IView, containment, |
| | | request_param, request_method, match_param, route_name, attr, |
| | | xhr, accept, header, path_info] |
| | | request_param, request_method, route_name, attr, |
| | | xhr, accept, header, path_info, match_param] |
| | | 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): |
| | | """ |
| | |
| | | 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): |
| | |
| | | def exception_response(status_code, **kw): |
| | | """Creates an HTTP exception based on a status code. Example:: |
| | | |
| | | raise responsecode(404) # raises an HTTPNotFound exception. |
| | | raise exception_response(404) # raises an HTTPNotFound exception. |
| | | |
| | | The values passed as ``kw`` are provided to the exception's constructor. |
| | | """ |
| | |
| | | '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 |
| | |
| | | from webob import Response |
| | | |
| | | def rdf_view(request): |
| | | """ """ |
| | | return Response('rdf') |
| | | |
| | | def juri_view(request): |
| | | """ """ |
| | | return Response('juri') |
| | | |
| | | def includeme(config): |
| | | config.add_route('rdf', 'licenses/:license_code/:license_version/rdf') |
| | | config.add_route('juri', |
| | | 'licenses/:license_code/:license_version/:jurisdiction') |
| | | config.add_view('.views.rdf_view', route_name='rdf') |
| | | config.add_view('.views.juri_view', route_name='juri') |
| | | |
| | | |
| | | config.add_view(rdf_view, route_name='rdf') |
| | | config.add_view(juri_view, route_name='juri') |
New file |
| | |
| | | from pyramid.response import Response |
| | | from pyramid.authentication import AuthTktAuthenticationPolicy |
| | | from pyramid.authorization import ACLAuthorizationPolicy |
| | | |
| | | def aview(request): |
| | | return Response('a view') |
| | | |
| | | def routeview(request): |
| | | return Response('route view') |
| | | |
| | | def protectedview(request): |
| | | return Response('protected view') |
| | | |
| | | def includeme(config): |
| | | # purposely sorta-randomly ordered (route comes after view naming it, |
| | | # authz comes after views) |
| | | config.add_view(aview) |
| | | config.add_view(protectedview, name='protected', permission='view') |
| | | config.add_view(routeview, route_name='aroute') |
| | | config.add_route('aroute', '/route') |
| | | config.set_authentication_policy(AuthTktAuthenticationPolicy('seekri1t')) |
| | | config.set_authorization_policy(ACLAuthorizationPolicy()) |
| | | config.include('pyramid.tests.conflictapp.included') |
New file |
| | |
| | | from webob import Response |
| | | |
| | | def bview(request): return Response('b view') |
| | | |
| | | def includeme(config): |
| | | config.add_view(bview) |
| | |
| | | this_pkg = sys.modules['pyramid.tests.test_config'] |
| | | self.assertTrue(config.registry.getUtility(ISettings)) |
| | | self.assertEqual(config.package, this_pkg) |
| | | config.commit() |
| | | self.assertTrue(config.registry.getUtility(IRendererFactory, 'json')) |
| | | self.assertTrue(config.registry.getUtility(IRendererFactory, 'string')) |
| | | if not __pypy__: |
| | |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | policy = object() |
| | | config = self._makeOne(authentication_policy=policy) |
| | | config.commit() |
| | | result = config.registry.getUtility(IAuthenticationPolicy) |
| | | self.assertEqual(policy, result) |
| | | |
| | |
| | | from pyramid.interfaces import IRendererFactory |
| | | renderer = object() |
| | | config = self._makeOne(renderers=[('yeah', renderer)]) |
| | | config.commit() |
| | | self.assertEqual(config.registry.getUtility(IRendererFactory, 'yeah'), |
| | | renderer) |
| | | |
| | | def test_ctor_default_renderers(self): |
| | | from pyramid.interfaces import IRendererFactory |
| | | from pyramid.renderers import json_renderer_factory |
| | | config = self._makeOne() |
| | | self.assertEqual(config.registry.getUtility(IRendererFactory, 'json'), |
| | | json_renderer_factory) |
| | | |
| | | def test_ctor_default_permission(self): |
| | | from pyramid.interfaces import IDefaultPermission |
| | | config = self._makeOne(default_permission='view') |
| | | config.commit() |
| | | self.assertEqual(config.registry.getUtility(IDefaultPermission), 'view') |
| | | |
| | | def test_ctor_session_factory(self): |
| | |
| | | from pyramid.interfaces import IViewMapperFactory |
| | | mapper = object() |
| | | config = self._makeOne(default_view_mapper=mapper) |
| | | config.commit() |
| | | self.assertEqual(config.registry.getUtility(IViewMapperFactory), |
| | | mapper) |
| | | |
| | |
| | | reg = Registry() |
| | | config = self._makeOne(reg) |
| | | config.setup_registry(authentication_policy=policy) |
| | | config.commit() |
| | | result = reg.getUtility(IAuthenticationPolicy) |
| | | self.assertEqual(policy, result) |
| | | |
| | |
| | | reg = Registry() |
| | | config = self._makeOne(reg) |
| | | config.setup_registry(authentication_policy='pyramid.tests') |
| | | config.commit() |
| | | result = reg.getUtility(IAuthenticationPolicy) |
| | | import pyramid.tests |
| | | self.assertEqual(result, pyramid.tests) |
| | |
| | | dummy = object() |
| | | config.setup_registry(authentication_policy=dummy, |
| | | authorization_policy='pyramid.tests') |
| | | config.commit() |
| | | result = reg.getUtility(IAuthorizationPolicy) |
| | | import pyramid.tests |
| | | self.assertEqual(result, pyramid.tests) |
| | |
| | | reg = Registry() |
| | | config = self._makeOne(reg) |
| | | config.setup_registry(renderers=[('yeah', renderer)]) |
| | | config.commit() |
| | | self.assertEqual(reg.getUtility(IRendererFactory, 'yeah'), |
| | | renderer) |
| | | |
| | |
| | | reg = Registry() |
| | | config = self._makeOne(reg) |
| | | config.setup_registry(default_permission='view') |
| | | config.commit() |
| | | self.assertEqual(reg.getUtility(IDefaultPermission), 'view') |
| | | |
| | | def test_setup_registry_includes(self): |
| | |
| | | |
| | | def test_add_view_with_route_name(self): |
| | | from pyramid.renderers import null_renderer |
| | | from zope.component import ComponentLookupError |
| | | view = lambda *arg: 'OK' |
| | | config = self._makeOne(autocommit=True) |
| | | config.add_view(view=view, route_name='foo', renderer=null_renderer) |
| | | self.assertEqual(len(config.registry.deferred_route_views), 1) |
| | | infos = config.registry.deferred_route_views['foo'] |
| | | self.assertEqual(len(infos), 1) |
| | | info = infos[0] |
| | | self.assertEqual(info['route_name'], 'foo') |
| | | self.assertEqual(info['view'], view) |
| | | self.assertRaises(ComponentLookupError, |
| | | self._getRouteRequestIface, config, 'foo') |
| | | wrapper = self._getViewCallable(config, None) |
| | | self.assertEqual(wrapper, None) |
| | | config.add_route('foo', '/a/b') |
| | | config.add_view(view=view, route_name='foo', renderer=null_renderer) |
| | | request_iface = self._getRouteRequestIface(config, 'foo') |
| | | self.assertNotEqual(request_iface, None) |
| | | wrapper = self._getViewCallable(config, request_iface=request_iface) |
| | | self.assertNotEqual(wrapper, None) |
| | | self.assertEqual(wrapper(None, None), 'OK') |
| | | |
| | | def test_add_view_with_route_name_deferred_views_already_exist(self): |
| | | def test_add_view_with_nonexistant_route_name(self): |
| | | from pyramid.renderers import null_renderer |
| | | from zope.configuration.config import ConfigurationExecutionError |
| | | view = lambda *arg: 'OK' |
| | | config = self._makeOne(autocommit=True) |
| | | config.registry.deferred_route_views = {'bar':[]} |
| | | config.add_view(view=view, route_name='foo') |
| | | self.assertEqual(len(config.registry.deferred_route_views), 2) |
| | | self.assertEqual(config.registry.deferred_route_views['bar'], []) |
| | | infos = config.registry.deferred_route_views['foo'] |
| | | self.assertEqual(len(infos), 1) |
| | | |
| | | def test_deferred_route_views_retains_custom_predicates(self): |
| | | view = lambda *arg: 'OK' |
| | | config = self._makeOne(autocommit=True) |
| | | config.add_view(view=view, route_name='foo', custom_predicates=('123',)) |
| | | self.assertEqual(len(config.registry.deferred_route_views), 1) |
| | | infos = config.registry.deferred_route_views['foo'] |
| | | self.assertEqual(len(infos), 1) |
| | | info = infos[0] |
| | | self.assertEqual(info['route_name'], 'foo') |
| | | self.assertEqual(info['custom_predicates'], ('123',)) |
| | | config = self._makeOne() |
| | | config.add_view(view=view, route_name='foo', renderer=null_renderer) |
| | | self.assertRaises(ConfigurationExecutionError, config.commit) |
| | | |
| | | def test_add_view_with_route_name_exception(self): |
| | | from pyramid.renderers import null_renderer |
| | | from zope.interface import implementedBy |
| | | from zope.component import ComponentLookupError |
| | | view = lambda *arg: 'OK' |
| | | config = self._makeOne(autocommit=True) |
| | | config.add_route('foo', '/a/b') |
| | | config.add_view(view=view, route_name='foo', context=RuntimeError, |
| | | renderer=null_renderer) |
| | | self.assertEqual(len(config.registry.deferred_route_views), 1) |
| | | infos = config.registry.deferred_route_views['foo'] |
| | | self.assertEqual(len(infos), 1) |
| | | info = infos[0] |
| | | self.assertEqual(info['route_name'], 'foo') |
| | | self.assertEqual(info['view'], view) |
| | | self.assertRaises(ComponentLookupError, |
| | | self._getRouteRequestIface, config, 'foo') |
| | | wrapper_exc_view = self._getViewCallable( |
| | | config, ctx_iface=implementedBy(RuntimeError), |
| | | exception_view=True) |
| | | self.assertEqual(wrapper_exc_view, None) |
| | | config.add_route('foo', '/a/b') |
| | | request_iface = self._getRouteRequestIface(config, 'foo') |
| | | self.assertNotEqual(request_iface, None) |
| | | wrapper_exc_view = self._getViewCallable( |
| | | config, ctx_iface=implementedBy(RuntimeError), |
| | | request_iface=request_iface, exception_view=True) |
| | |
| | | |
| | | def test_add_route_defaults(self): |
| | | config = self._makeOne(autocommit=True) |
| | | route = config.add_route('name', 'path') |
| | | config.add_route('name', 'path') |
| | | self._assertRoute(config, 'name', 'path') |
| | | self.assertEqual(route.name, 'name') |
| | | |
| | | def test_add_route_with_route_prefix(self): |
| | | config = self._makeOne(autocommit=True) |
| | | config.route_prefix = 'root' |
| | | route = config.add_route('name', 'path') |
| | | self.assertEqual(route.name, 'name') |
| | | self.assertEqual(route.pattern, 'root/path') |
| | | |
| | | config.add_route('name', 'path') |
| | | self._assertRoute(config, 'name', 'root/path') |
| | | |
| | | def test_add_route_discriminator(self): |
| | | config = self._makeOne() |
| | | route = config.add_route('name', 'path') |
| | | self._assertRoute(config, 'name', 'path') |
| | | self.assertEqual(route.name, 'name') |
| | | config.add_route('name', 'path') |
| | | self.assertEqual(config._ctx.actions[-1][0], ('route', 'name')) |
| | | |
| | | def test_add_route_with_factory(self): |
| | | config = self._makeOne(autocommit=True) |
| | | factory = object() |
| | | route = config.add_route('name', 'path', factory=factory) |
| | | config.add_route('name', 'path', factory=factory) |
| | | route = self._assertRoute(config, 'name', 'path') |
| | | self.assertEqual(route.factory, factory) |
| | | |
| | | def test_add_route_with_static(self): |
| | | config = self._makeOne(autocommit=True) |
| | | route = config.add_route('name', 'path/{foo}', static=True) |
| | | self.assertEqual(route.name, 'name') |
| | | config.add_route('name', 'path/{foo}', static=True) |
| | | mapper = config.get_routes_mapper() |
| | | self.assertEqual(len(mapper.get_routes()), 0) |
| | | self.assertEqual(mapper.generate('name', {"foo":"a"}), '/path/a') |
| | | |
| | | def test_add_route_with_factory_dottedname(self): |
| | | config = self._makeOne(autocommit=True) |
| | | route = config.add_route( |
| | | config.add_route( |
| | | 'name', 'path', |
| | | factory='pyramid.tests.test_config.dummyfactory') |
| | | route = self._assertRoute(config, 'name', 'path') |
| | | self.assertEqual(route.factory, dummyfactory) |
| | | |
| | | def test_add_route_with_xhr(self): |
| | |
| | | |
| | | def test_add_route_no_pattern_with_path(self): |
| | | config = self._makeOne(autocommit=True) |
| | | route = config.add_route('name', path='path') |
| | | config.add_route('name', path='path') |
| | | self._assertRoute(config, 'name', 'path') |
| | | self.assertEqual(route.name, 'name') |
| | | |
| | | def test_add_route_no_path_no_pattern(self): |
| | | from pyramid.exceptions import ConfigurationError |
| | |
| | | |
| | | def test_add_route_with_pregenerator(self): |
| | | config = self._makeOne(autocommit=True) |
| | | route = config.add_route('name', 'pattern', pregenerator='123') |
| | | config.add_route('name', 'pattern', pregenerator='123') |
| | | route = self._assertRoute(config, 'name', 'pattern') |
| | | self.assertEqual(route.pregenerator, '123') |
| | | |
| | | def test_add_route_no_view_with_view_attr(self): |
| | |
| | | def __call__(self, *arg, **kw): |
| | | return 'moo' |
| | | config.add_renderer(None, moo) |
| | | config.commit() |
| | | def view(request): |
| | | return 'OK' |
| | | result = config.derive_view(view) |
| | |
| | | config = self._makeOne() |
| | | config.add_renderer(None, moo) |
| | | config.add_renderer('foo', foo) |
| | | config.commit() |
| | | result = config.derive_view(view, renderer='foo') |
| | | self.assertFalse(result is view) |
| | | request = self._makeRequest(config) |
| | |
| | | finally: |
| | | config.end() |
| | | self.assertTrue('div' in result.body) |
| | | |
| | | def test_set_authentication_policy_no_authz_policy(self): |
| | | from zope.configuration.config import ConfigurationExecutionError |
| | | config = self._makeOne() |
| | | policy = object() |
| | | config.set_authentication_policy(policy) |
| | | self.assertRaises(ConfigurationExecutionError, config.commit) |
| | | |
| | | def test_set_authentication_policy_no_authz_policy_autocommit(self): |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | config = self._makeOne(autocommit=True) |
| | | policy = object() |
| | | config.set_authentication_policy(policy) |
| | | self.assertEqual( |
| | | config.registry.getUtility(IAuthenticationPolicy), policy) |
| | | |
| | | def test_set_authentication_policy_with_authz_policy(self): |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | config = self._makeOne() |
| | | authn_policy = object() |
| | | authz_policy = object() |
| | | config.registry.registerUtility(authz_policy, IAuthorizationPolicy) |
| | | config.set_authentication_policy(authn_policy) |
| | | config.commit() |
| | | self.assertEqual( |
| | | config.registry.getUtility(IAuthenticationPolicy), authn_policy) |
| | | |
| | | def test_set_authentication_policy_with_authz_policy_autocommit(self): |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | config = self._makeOne(autocommit=True) |
| | | authn_policy = object() |
| | | authz_policy = object() |
| | | config.registry.registerUtility(authz_policy, IAuthorizationPolicy) |
| | | config.set_authentication_policy(authn_policy) |
| | | config.commit() |
| | | self.assertEqual( |
| | | config.registry.getUtility(IAuthenticationPolicy), authn_policy) |
| | | |
| | | def test_set_authorization_policy_no_authn_policy(self): |
| | | from zope.configuration.config import ConfigurationExecutionError |
| | | config = self._makeOne() |
| | | policy = object() |
| | | config.set_authorization_policy(policy) |
| | | self.assertRaises(ConfigurationExecutionError, config.commit) |
| | | |
| | | def test_set_authorization_policy_no_authn_policy_autocommit(self): |
| | | from pyramid.exceptions import ConfigurationError |
| | | config = self._makeOne(autocommit=True) |
| | | policy = object() |
| | | self.assertRaises(ConfigurationError, |
| | | config.set_authorization_policy, policy) |
| | | |
| | | def test_set_authorization_policy_with_authn_policy(self): |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | config = self._makeOne() |
| | | authn_policy = object() |
| | | authz_policy = object() |
| | | config.registry.registerUtility(authn_policy, IAuthenticationPolicy) |
| | | config.set_authorization_policy(authz_policy) |
| | | self.assertEqual( |
| | | config.registry.getUtility(IAuthorizationPolicy), authz_policy) |
| | | |
| | | def test_set_authorization_policy_with_authn_policy_autocommit(self): |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | config = self._makeOne(autocommit=True) |
| | | authn_policy = object() |
| | | authz_policy = object() |
| | | config.registry.registerUtility(authn_policy, IAuthenticationPolicy) |
| | | config.set_authorization_policy(authz_policy) |
| | | self.assertEqual( |
| | | config.registry.getUtility(IAuthorizationPolicy), authz_policy) |
| | | |
| | | def test_set_locale_negotiator(self): |
| | | from pyramid.interfaces import ILocaleNegotiator |
| | |
| | | try: |
| | | config.commit() |
| | | except ConfigurationConflictError, why: |
| | | c1, c2, c3, c4 = self._conflictFunctions(why) |
| | | c1, c2, c3, c4, c5, c6 = self._conflictFunctions(why) |
| | | self.assertEqual(c1, 'test_conflict_route_with_view') |
| | | self.assertEqual(c2, 'test_conflict_route_with_view') |
| | | self.assertEqual(c3, 'test_conflict_route_with_view') |
| | | self.assertEqual(c4, 'test_conflict_route_with_view') |
| | | self.assertEqual(c5, 'test_conflict_route_with_view') |
| | | self.assertEqual(c6, 'test_conflict_route_with_view') |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
New file |
| | |
| | | import unittest |
| | | |
| | | class ConfiguratorSecurityMethodsTests(unittest.TestCase): |
| | | def _makeOne(self, *arg, **kw): |
| | | from pyramid.config import Configurator |
| | | config = Configurator(*arg, **kw) |
| | | return config |
| | | |
| | | def test_set_authentication_policy_no_authz_policy(self): |
| | | from zope.configuration.config import ConfigurationExecutionError |
| | | config = self._makeOne() |
| | | policy = object() |
| | | config.set_authentication_policy(policy) |
| | | self.assertRaises(ConfigurationExecutionError, config.commit) |
| | | |
| | | def test_set_authentication_policy_no_authz_policy_autocommit(self): |
| | | from pyramid.exceptions import ConfigurationError |
| | | config = self._makeOne(autocommit=True) |
| | | policy = object() |
| | | self.assertRaises(ConfigurationError, |
| | | config.set_authentication_policy, policy) |
| | | |
| | | def test_set_authentication_policy_with_authz_policy(self): |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | config = self._makeOne() |
| | | authn_policy = object() |
| | | authz_policy = object() |
| | | config.registry.registerUtility(authz_policy, IAuthorizationPolicy) |
| | | config.set_authentication_policy(authn_policy) |
| | | config.commit() |
| | | self.assertEqual( |
| | | config.registry.getUtility(IAuthenticationPolicy), authn_policy) |
| | | |
| | | def test_set_authentication_policy_with_authz_policy_autocommit(self): |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | config = self._makeOne(autocommit=True) |
| | | authn_policy = object() |
| | | authz_policy = object() |
| | | config.registry.registerUtility(authz_policy, IAuthorizationPolicy) |
| | | config.set_authentication_policy(authn_policy) |
| | | config.commit() |
| | | self.assertEqual( |
| | | config.registry.getUtility(IAuthenticationPolicy), authn_policy) |
| | | |
| | | def test_set_authorization_policy_no_authn_policy(self): |
| | | from zope.configuration.config import ConfigurationExecutionError |
| | | config = self._makeOne() |
| | | policy = object() |
| | | config.set_authorization_policy(policy) |
| | | self.assertRaises(ConfigurationExecutionError, config.commit) |
| | | |
| | | def test_set_authorization_policy_no_authn_policy_autocommit(self): |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | config = self._makeOne(autocommit=True) |
| | | policy = object() |
| | | config.set_authorization_policy(policy) |
| | | self.assertEqual( |
| | | config.registry.getUtility(IAuthorizationPolicy), policy) |
| | | |
| | | def test_set_authorization_policy_with_authn_policy(self): |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | config = self._makeOne() |
| | | authn_policy = object() |
| | | authz_policy = object() |
| | | config.registry.registerUtility(authn_policy, IAuthenticationPolicy) |
| | | config.set_authorization_policy(authz_policy) |
| | | config.commit() |
| | | self.assertEqual( |
| | | config.registry.getUtility(IAuthorizationPolicy), authz_policy) |
| | | |
| | | def test_set_authorization_policy_with_authn_policy_autocommit(self): |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | config = self._makeOne(autocommit=True) |
| | | authn_policy = object() |
| | | authz_policy = object() |
| | | config.registry.registerUtility(authn_policy, IAuthenticationPolicy) |
| | | config.set_authorization_policy(authz_policy) |
| | | self.assertEqual( |
| | | config.registry.getUtility(IAuthorizationPolicy), authz_policy) |
| | | |
| | |
| | | res = self.testapp.get('/route_raise_exception4', status=200) |
| | | self.assertTrue('whoa' in res.body) |
| | | |
| | | class TestConflictApp(unittest.TestCase): |
| | | package = 'pyramid.tests.conflictapp' |
| | | def _makeConfig(self): |
| | | from pyramid.config import Configurator |
| | | config = Configurator() |
| | | return config |
| | | |
| | | def test_autoresolved_view(self): |
| | | config = self._makeConfig() |
| | | config.include(self.package) |
| | | app = config.make_wsgi_app() |
| | | from webtest import TestApp |
| | | self.testapp = TestApp(app) |
| | | res = self.testapp.get('/') |
| | | self.assertTrue('a view' in res.body) |
| | | res = self.testapp.get('/route') |
| | | self.assertTrue('route view' in res.body) |
| | | |
| | | def test_overridden_autoresolved_view(self): |
| | | from pyramid.response import Response |
| | | config = self._makeConfig() |
| | | config.include(self.package) |
| | | def thisview(request): |
| | | return Response('this view') |
| | | config.add_view(thisview) |
| | | app = config.make_wsgi_app() |
| | | from webtest import TestApp |
| | | self.testapp = TestApp(app) |
| | | res = self.testapp.get('/') |
| | | self.assertTrue('this view' in res.body) |
| | | |
| | | def test_overridden_route_view(self): |
| | | from pyramid.response import Response |
| | | config = self._makeConfig() |
| | | config.include(self.package) |
| | | def thisview(request): |
| | | return Response('this view') |
| | | config.add_view(thisview, route_name='aroute') |
| | | app = config.make_wsgi_app() |
| | | from webtest import TestApp |
| | | self.testapp = TestApp(app) |
| | | res = self.testapp.get('/route') |
| | | self.assertTrue('this view' in res.body) |
| | | |
| | | def test_nonoverridden_authorization_policy(self): |
| | | config = self._makeConfig() |
| | | config.include(self.package) |
| | | app = config.make_wsgi_app() |
| | | from webtest import TestApp |
| | | self.testapp = TestApp(app) |
| | | res = self.testapp.get('/protected', status=403) |
| | | self.assertTrue('403 Forbidden' in res) |
| | | |
| | | def test_overridden_authorization_policy(self): |
| | | config = self._makeConfig() |
| | | config.include(self.package) |
| | | from pyramid.testing import DummySecurityPolicy |
| | | config.set_authorization_policy(DummySecurityPolicy('fred')) |
| | | config.set_authentication_policy(DummySecurityPolicy(permissive=True)) |
| | | app = config.make_wsgi_app() |
| | | from webtest import TestApp |
| | | self.testapp = TestApp(app) |
| | | res = self.testapp.get('/protected', status=200) |
| | | self.assertTrue('protected view' in res) |
| | | |
| | | class ImperativeIncludeConfigurationTest(unittest.TestCase): |
| | | def setUp(self): |
| | | from pyramid.config import Configurator |
| | |
| | | install_requires.append('simplejson') |
| | | |
| | | setup(name='pyramid', |
| | | version='1.2dev', |
| | | version='1.2a1', |
| | | description=('The Pyramid web application development framework, a ' |
| | | 'Pylons project'), |
| | | long_description=README + '\n\n' + CHANGES, |