{
    "file_diffs": [
        {
            "old_file_content": "import inspect\nimport operator\nimport os\nimport warnings\n\nfrom zope.interface import (\n    Interface,\n    implementedBy,\n    implementer,\n    provider,\n    )\n\nfrom zope.interface.interfaces import IInterface\n\nfrom pyramid.interfaces import (\n    IAuthenticationPolicy,\n    IAuthorizationPolicy,\n    IDebugLogger,\n    IDefaultPermission,\n    IException,\n    IExceptionViewClassifier,\n    IMultiView,\n    IRendererFactory,\n    IRequest,\n    IResponse,\n    IRouteRequest,\n    ISecuredView,\n    IStaticURLInfo,\n    IView,\n    IViewClassifier,\n    IViewMapper,\n    IViewMapperFactory,\n    PHASE1_CONFIG,\n    )\n\nfrom pyramid import renderers\n\nfrom pyramid.compat import (\n    string_types,\n    urlparse,\n    url_quote,\n    WIN,\n    is_bound_method,\n    is_nonstr_iter\n    )\n\nfrom pyramid.exceptions import (\n    ConfigurationError,\n    PredicateMismatch,\n    )\n\nfrom pyramid.httpexceptions import (\n    HTTPForbidden,\n    HTTPNotFound,\n    )\n\nfrom pyramid.registry import (\n    predvalseq,\n    Deferred,\n    )\n\nfrom pyramid.response import Response\n\nfrom pyramid.security import NO_PERMISSION_REQUIRED\nfrom pyramid.static import static_view\nfrom pyramid.threadlocal import get_current_registry\n\nfrom pyramid.view import (\n    render_view_to_response,\n    AppendSlashNotFoundViewFactory,\n    )\n\nfrom pyramid.util import (\n    object_description,\n    viewdefaults,\n    action_method,\n    )\n\nimport pyramid.config.predicates\n\nfrom pyramid.config.util import (\n    DEFAULT_PHASH,\n    MAX_ORDER,\n    takes_one_arg,\n    )\n\nurljoin = urlparse.urljoin\nurl_parse = urlparse.urlparse\n\ndef view_description(view):\n    try:\n        return view.__text__\n    except AttributeError:\n        # custom view mappers might not add __text__\n        return object_description(view)\n\ndef wraps_view(wrapper):\n    def inner(self, view):\n        wrapper_view = wrapper(self, view)\n        return preserve_view_attrs(view, wrapper_view)\n    return inner\n\ndef preserve_view_attrs(view, wrapper):\n    if view is None:\n        return wrapper\n\n    if wrapper is view:\n        return view\n\n    original_view = getattr(view, '__original_view__', None)\n\n    if original_view is None:\n        original_view = view\n\n    wrapper.__wraps__ = view\n    wrapper.__original_view__ = original_view\n    wrapper.__module__ = view.__module__\n    wrapper.__doc__ = view.__doc__\n\n    try:\n        wrapper.__name__ = view.__name__\n    except AttributeError:\n        wrapper.__name__ = repr(view)\n\n    # attrs that may not exist on \"view\", but, if so, must be attached to\n    # \"wrapped view\"\n    for attr in ('__permitted__', '__call_permissive__', '__permission__',\n                 '__predicated__', '__predicates__', '__accept__',\n                 '__order__', '__text__'):\n        try:\n            setattr(wrapper, attr, getattr(view, attr))\n        except AttributeError:\n            pass\n\n    return wrapper\n\nclass ViewDeriver(object):\n    def __init__(self, **kw):\n        self.kw = kw\n        self.registry = kw['registry']\n        self.authn_policy = self.registry.queryUtility(IAuthenticationPolicy)\n        self.authz_policy = self.registry.queryUtility(IAuthorizationPolicy)\n        self.logger = self.registry.queryUtility(IDebugLogger)\n\n    def __call__(self, view):\n        return self.attr_wrapped_view(\n            self.predicated_view(\n                self.authdebug_view(\n                    self.secured_view(\n                        self.owrapped_view(\n                            self.http_cached_view(\n                                self.decorated_view(\n                                    self.rendered_view(\n                                        self.mapped_view(\n                                                view)))))))))\n\n    @wraps_view\n    def mapped_view(self, view):\n        mapper = self.kw.get('mapper')\n        if mapper is None:\n            mapper = getattr(view, '__view_mapper__', None)\n            if mapper is None:\n                mapper = self.registry.queryUtility(IViewMapperFactory)\n                if mapper is None:\n                    mapper = DefaultViewMapper\n\n        mapped_view = mapper(**self.kw)(view)\n        return mapped_view\n\n    @wraps_view\n    def owrapped_view(self, view):\n        wrapper_viewname = self.kw.get('wrapper_viewname')\n        viewname = self.kw.get('viewname')\n        if not wrapper_viewname:\n            return view\n        def _owrapped_view(context, request):\n            response = view(context, request)\n            request.wrapped_response = response\n            request.wrapped_body = response.body\n            request.wrapped_view = view\n            wrapped_response = render_view_to_response(context, request,\n                                                       wrapper_viewname)\n            if wrapped_response is None:\n                raise ValueError(\n                    'No wrapper view named %r found when executing view '\n                    'named %r' % (wrapper_viewname, viewname))\n            return wrapped_response\n        return _owrapped_view\n\n    @wraps_view\n    def http_cached_view(self, view):\n        if self.registry.settings.get('prevent_http_cache', False):\n            return view\n\n        seconds = self.kw.get('http_cache')\n\n        if seconds is None:\n            return view\n\n        options = {}\n\n        if isinstance(seconds, (tuple, list)):\n            try:\n                seconds, options = seconds\n            except ValueError:\n                raise ConfigurationError(\n                    'If http_cache parameter is a tuple or list, it must be '\n                    'in the form (seconds, options); not %s' % (seconds,))\n\n        def wrapper(context, request):\n            response = view(context, request)\n            prevent_caching = getattr(response.cache_control, 'prevent_auto',\n                                      False)\n            if not prevent_caching:\n                response.cache_expires(seconds, **options)\n            return response\n\n        return wrapper\n\n    @wraps_view\n    def secured_view(self, view):\n        permission = self.kw.get('permission')\n        if permission == NO_PERMISSION_REQUIRED:\n            # allow views registered within configurations that have a\n            # default permission to explicitly override the default\n            # permission, replacing it with no permission at all\n            permission = None\n\n        wrapped_view = view\n        if self.authn_policy and self.authz_policy and (permission is not None):\n            def _permitted(context, request):\n                principals = self.authn_policy.effective_principals(request)\n                return self.authz_policy.permits(context, principals,\n                                                 permission)\n            def _secured_view(context, request):\n                result = _permitted(context, request)\n                if result:\n                    return view(context, request)\n                view_name = getattr(view, '__name__', view)\n                msg = getattr(\n                    request, 'authdebug_message',\n                    'Unauthorized: %s failed permission check' % view_name)\n                raise HTTPForbidden(msg, result=result)\n            _secured_view.__call_permissive__ = view\n            _secured_view.__permitted__ = _permitted\n            _secured_view.__permission__ = permission\n            wrapped_view = _secured_view\n\n        return wrapped_view\n\n    @wraps_view\n    def authdebug_view(self, view):\n        wrapped_view = view\n        settings = self.registry.settings\n        permission = self.kw.get('permission')\n        if settings and settings.get('debug_authorization', False):\n            def _authdebug_view(context, request):\n                view_name = getattr(request, 'view_name', None)\n\n                if self.authn_policy and self.authz_policy:\n                    if permission is NO_PERMISSION_REQUIRED:\n                        msg = 'Allowed (NO_PERMISSION_REQUIRED)'\n                    elif permission is None:\n                        msg = 'Allowed (no permission registered)'\n                    else:\n                        principals = self.authn_policy.effective_principals(\n                            request)\n                        msg = str(self.authz_policy.permits(context, principals,\n                                                            permission))\n                else:\n                    msg = 'Allowed (no authorization policy in use)'\n\n                view_name = getattr(request, 'view_name', None)\n                url = getattr(request, 'url', None)\n                msg = ('debug_authorization of url %s (view name %r against '\n                       'context %r): %s' % (url, view_name, context, msg))\n                self.logger and self.logger.debug(msg)\n                if request is not None:\n                    request.authdebug_message = msg\n                return view(context, request)\n\n            wrapped_view = _authdebug_view\n\n        return wrapped_view\n\n    @wraps_view\n    def predicated_view(self, view):\n        preds = self.kw.get('predicates', ())\n        if not preds:\n            return view\n        def predicate_wrapper(context, request):\n            for predicate in preds:\n                if not predicate(context, request):\n                    view_name = getattr(view, '__name__', view)\n                    raise PredicateMismatch(\n                         'predicate mismatch for view %s (%s)' % (\n                         view_name, predicate.text()))\n            return view(context, request)        \n        def checker(context, request):\n            return all((predicate(context, request) for predicate in\n                        preds))\n        predicate_wrapper.__predicated__ = checker\n        predicate_wrapper.__predicates__ = preds\n        return predicate_wrapper\n\n    @wraps_view\n    def attr_wrapped_view(self, view):\n        kw = self.kw\n        accept, order, phash = (kw.get('accept', None),\n                                kw.get('order', MAX_ORDER),\n                                kw.get('phash', DEFAULT_PHASH))\n        # this is a little silly but we don't want to decorate the original\n        # function with attributes that indicate accept, order, and phash,\n        # so we use a wrapper\n        if (\n            (accept is None) and\n            (order == MAX_ORDER) and\n            (phash == DEFAULT_PHASH)\n            ):\n            return view # defaults\n        def attr_view(context, request):\n            return view(context, request)\n        attr_view.__accept__ = accept\n        attr_view.__order__ = order\n        attr_view.__phash__ = phash\n        attr_view.__view_attr__ = self.kw.get('attr')\n        attr_view.__permission__ = self.kw.get('permission')\n        return attr_view\n\n    @wraps_view\n    def rendered_view(self, view):\n        # one way or another this wrapper must produce a Response (unless\n        # the renderer is a NullRendererHelper)\n        renderer = self.kw.get('renderer')\n        if renderer is None:\n            # register a default renderer if you want super-dynamic\n            # rendering.  registering a default renderer will also allow\n            # override_renderer to work if a renderer is left unspecified for\n            # a view registration.\n            return self._response_resolved_view(view)\n        if renderer is renderers.null_renderer:\n            return view\n        return self._rendered_view(view, renderer)\n\n    def _rendered_view(self, view, view_renderer):\n        def rendered_view(context, request):\n            renderer = view_renderer\n            result = view(context, request)\n            if result.__class__ is Response: # potential common case\n                response = result\n            else:\n                registry = self.registry\n                # this must adapt, it can't do a simple interface check\n                # (avoid trying to render webob responses)\n                response = registry.queryAdapterOrSelf(result, IResponse)\n                if response is None:\n                    attrs = getattr(request, '__dict__', {})\n                    if 'override_renderer' in attrs:\n                        # renderer overridden by newrequest event or other\n                        renderer_name = attrs.pop('override_renderer')\n                        renderer = renderers.RendererHelper(\n                            name=renderer_name,\n                            package=self.kw.get('package'),\n                            registry = registry)\n                    if '__view__' in attrs:\n                        view_inst = attrs.pop('__view__')\n                    else:\n                        view_inst = getattr(view, '__original_view__', view)\n                    response = renderer.render_view(request, result, view_inst,\n                                                    context)\n            return response\n\n        return rendered_view\n\n    def _response_resolved_view(self, view):\n        registry = self.registry\n        def viewresult_to_response(context, request):\n            result = view(context, request)\n            if result.__class__ is Response: # common case\n                response = result\n            else:\n                response = registry.queryAdapterOrSelf(result, IResponse)\n                if response is None:\n                    if result is None:\n                        append = (' You may have forgotten to return a value '\n                                  'from the view callable.')\n                    elif isinstance(result, dict):\n                        append = (' You may have forgotten to define a '\n                                  'renderer in the view configuration.')\n                    else:\n                        append = ''\n\n                    msg = ('Could not convert return value of the view '\n                           'callable %s into a response object. '\n                           'The value returned was %r.' + append)\n\n                    raise ValueError(msg % (view_description(view), result))\n\n            return response\n\n        return viewresult_to_response\n\n    @wraps_view\n    def decorated_view(self, view):\n        decorator = self.kw.get('decorator')\n        if decorator is None:\n            return view\n        return decorator(view)\n\n@implementer(IViewMapper)\n@provider(IViewMapperFactory)\nclass DefaultViewMapper(object):\n    def __init__(self, **kw):\n        self.attr = kw.get('attr')\n\n    def __call__(self, view):\n        if inspect.isclass(view):\n            view = self.map_class(view)\n        else:\n            view = self.map_nonclass(view)\n        return view\n\n    def map_class(self, view):\n        ronly = requestonly(view, self.attr)\n        if ronly:\n            mapped_view = self.map_class_requestonly(view)\n        else:\n            mapped_view = self.map_class_native(view)\n        mapped_view.__text__ = 'method %s of %s' % (\n            self.attr or '__call__', object_description(view))\n        return mapped_view\n\n    def map_nonclass(self, view):\n        # We do more work here than appears necessary to avoid wrapping the\n        # view unless it actually requires wrapping (to avoid function call\n        # overhead).\n        mapped_view = view\n        ronly = requestonly(view, self.attr)\n        if ronly:\n            mapped_view = self.map_nonclass_requestonly(view)\n        elif self.attr:\n            mapped_view = self.map_nonclass_attr(view)\n        if inspect.isroutine(mapped_view):\n            # This branch will be true if the view is a function or a method.\n            # We potentially mutate an unwrapped object here if it's a\n            # function.  We do this to avoid function call overhead of\n            # injecting another wrapper.  However, we must wrap if the\n            # function is a bound method because we can't set attributes on a\n            # bound method.\n            if is_bound_method(view):\n                _mapped_view = mapped_view\n                def mapped_view(context, request):\n                    return _mapped_view(context, request)\n            if self.attr is not None:\n                mapped_view.__text__ = 'attr %s of %s' % (\n                    self.attr, object_description(view))\n            else:\n                mapped_view.__text__ = object_description(view)\n        return mapped_view\n\n    def map_class_requestonly(self, view):\n        # its a class that has an __init__ which only accepts request\n        attr = self.attr\n        def _class_requestonly_view(context, request):\n            inst = view(request)\n            request.__view__ = inst\n            if attr is None:\n                response = inst()\n            else:\n                response = getattr(inst, attr)()\n            return response\n        return _class_requestonly_view\n\n    def map_class_native(self, view):\n        # its a class that has an __init__ which accepts both context and\n        # request\n        attr = self.attr\n        def _class_view(context, request):\n            inst = view(context, request)\n            request.__view__ = inst\n            if attr is None:\n                response = inst()\n            else:\n                response = getattr(inst, attr)()\n            return response\n        return _class_view\n\n    def map_nonclass_requestonly(self, view):\n        # its a function that has a __call__ which accepts only a single\n        # request argument\n        attr = self.attr\n        def _requestonly_view(context, request):\n            if attr is None:\n                response = view(request)\n            else:\n                response = getattr(view, attr)(request)\n            return response\n        return _requestonly_view\n\n    def map_nonclass_attr(self, view):\n        # its a function that has a __call__ which accepts both context and\n        # request, but still has an attr\n        def _attr_view(context, request):\n            response = getattr(view, self.attr)(context, request)\n            return response\n        return _attr_view\n\ndef requestonly(view, attr=None):\n    return takes_one_arg(view, attr=attr, argname='request')\n\n@implementer(IMultiView)\nclass MultiView(object):\n\n    def __init__(self, name):\n        self.name = name\n        self.media_views = {}\n        self.views = []\n        self.accepts = []\n\n    def __discriminator__(self, context, request):\n        # used by introspection systems like so:\n        # view = adapters.lookup(....)\n        # view.__discriminator__(context, request) -> view's discriminator\n        # so that superdynamic systems can feed the discriminator to\n        # the introspection system to get info about it\n        view = self.match(context, request)\n        return view.__discriminator__(context, request)\n\n    def add(self, view, order, accept=None, phash=None):\n        if phash is not None:\n            for i, (s, v, h) in enumerate(list(self.views)):\n                if phash == h:\n                    self.views[i] = (order, view, phash)\n                    return\n\n        if accept is None or '*' in accept:\n            self.views.append((order, view, phash))\n            self.views.sort(key=operator.itemgetter(0))\n        else:\n            subset = self.media_views.setdefault(accept, [])\n            for i, (s, v, h) in enumerate(list(subset)):\n                if phash == h:\n                    subset[i] = (order, view, phash)\n                    return\n            else:\n                subset.append((order, view, phash))\n                subset.sort(key=operator.itemgetter(0))\n            accepts = set(self.accepts)\n            accepts.add(accept)\n            self.accepts = list(accepts) # dedupe\n\n    def get_views(self, request):\n        if self.accepts and hasattr(request, 'accept'):\n            accepts = self.accepts[:]\n            views = []\n            while accepts:\n                match = request.accept.best_match(accepts)\n                if match is None:\n                    break\n                subset = self.media_views[match]\n                views.extend(subset)\n                accepts.remove(match)\n            views.extend(self.views)\n            return views\n        return self.views\n\n    def match(self, context, request):\n        for order, view, phash in self.get_views(request):\n            if not hasattr(view, '__predicated__'):\n                return view\n            if view.__predicated__(context, request):\n                return view\n        raise PredicateMismatch(self.name)\n\n    def __permitted__(self, context, request):\n        view = self.match(context, request)\n        if hasattr(view, '__permitted__'):\n            return view.__permitted__(context, request)\n        return True\n\n    def __call_permissive__(self, context, request):\n        view = self.match(context, request)\n        view = getattr(view, '__call_permissive__', view)\n        return view(context, request)\n\n    def __call__(self, context, request):\n        for order, view, phash in self.get_views(request):\n            try:\n                return view(context, request)\n            except PredicateMismatch:\n                continue\n        raise PredicateMismatch(self.name)\n\nclass ViewsConfiguratorMixin(object):\n    @viewdefaults\n    @action_method\n    def add_view(\n        self,\n        view=None,\n        name=\"\",\n        for_=None,\n        permission=None,\n        request_type=None,\n        route_name=None,\n        request_method=None,\n        request_param=None,\n        containment=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        context=None,\n        decorator=None,\n        mapper=None,\n        http_cache=None,\n        match_param=None,\n        check_csrf=None,\n        **predicates):\n        \"\"\" Add a :term:`view configuration` to the current\n        configuration state.  Arguments to ``add_view`` are broken\n        down below into *predicate* arguments and *non-predicate*\n        arguments.  Predicate arguments narrow the circumstances in\n        which the view callable will be invoked when a request is\n        presented to :app:`Pyramid`; non-predicate arguments are\n        informational.\n\n        Non-Predicate Arguments\n\n        view\n\n          A :term:`view callable` or a :term:`dotted Python name`\n          which refers to a view callable.  This argument is required\n          unless a ``renderer`` argument also exists.  If a\n          ``renderer`` argument is passed, and a ``view`` argument is\n          not provided, the view callable defaults to a callable that\n          returns an empty dictionary (see\n          :ref:`views_which_use_a_renderer`).\n\n        permission\n\n          A :term:`permission` that the user must possess in order to invoke\n          the :term:`view callable`.  See :ref:`view_security_section` for\n          more information about view security and permissions.  This is\n          often a string like ``view`` or ``edit``.\n\n          If ``permission`` is omitted, a *default* permission may be used\n          for this view registration if one was named as the\n          :class:`pyramid.config.Configurator` constructor's\n          ``default_permission`` argument, or if\n          :meth:`pyramid.config.Configurator.set_default_permission` was used\n          prior to this view registration.  Pass the value\n          :data:`pyramid.security.NO_PERMISSION_REQUIRED` as the permission\n          argument to explicitly indicate that the view should always be\n          executable by entirely anonymous users, regardless of the default\n          permission, bypassing any :term:`authorization policy` that may be\n          in effect.\n\n        attr\n\n          This knob is most useful when the view definition is a class.\n\n          The view machinery defaults to using the ``__call__`` method\n          of the :term:`view callable` (or the function itself, if the\n          view callable is a function) to obtain a response.  The\n          ``attr`` value allows you to vary the method attribute used\n          to obtain the response.  For example, if your view was a\n          class, and the class has a method named ``index`` and you\n          wanted to use this method instead of the class' ``__call__``\n          method to return the response, you'd say ``attr=\"index\"`` in the\n          view configuration for the view.\n\n        renderer\n\n          This is either a single string term (e.g. ``json``) or a\n          string implying a path or :term:`asset specification`\n          (e.g. ``templates/views.pt``) naming a :term:`renderer`\n          implementation.  If the ``renderer`` value does not contain\n          a dot ``.``, the specified string will be used to look up a\n          renderer implementation, and that renderer implementation\n          will be used to construct a response from the view return\n          value.  If the ``renderer`` value contains a dot (``.``),\n          the specified term will be treated as a path, and the\n          filename extension of the last element in the path will be\n          used to look up the renderer implementation, which will be\n          passed the full path.  The renderer implementation will be\n          used to construct a :term:`response` from the view return\n          value.\n\n          Note that if the view itself returns a :term:`response` (see\n          :ref:`the_response`), the specified renderer implementation\n          is never called.\n\n          When the renderer is a path, although a path is usually just\n          a simple relative pathname (e.g. ``templates/foo.pt``,\n          implying that a template named \"foo.pt\" is in the\n          \"templates\" directory relative to the directory of the\n          current :term:`package` of the Configurator), a path can be\n          absolute, starting with a slash on UNIX or a drive letter\n          prefix on Windows.  The path can alternately be a\n          :term:`asset specification` in the form\n          ``some.dotted.package_name:relative/path``, making it\n          possible to address template assets which live in a\n          separate package.\n\n          The ``renderer`` attribute is optional.  If it is not\n          defined, the \"null\" renderer is assumed (no rendering is\n          performed and the value is passed back to the upstream\n          :app:`Pyramid` machinery unmodified).\n\n        http_cache\n\n          .. versionadded:: 1.1\n\n          When you supply an ``http_cache`` value to a view configuration,\n          the ``Expires`` and ``Cache-Control`` headers of a response\n          generated by the associated view callable are modified.  The value\n          for ``http_cache`` may be one of the following:\n\n          - A nonzero integer.  If it's a nonzero integer, it's treated as a\n            number of seconds.  This number of seconds will be used to\n            compute the ``Expires`` header and the ``Cache-Control:\n            max-age`` parameter of responses to requests which call this view.\n            For example: ``http_cache=3600`` instructs the requesting browser\n            to 'cache this response for an hour, please'.\n\n          - A ``datetime.timedelta`` instance.  If it's a\n            ``datetime.timedelta`` instance, it will be converted into a\n            number of seconds, and that number of seconds will be used to\n            compute the ``Expires`` header and the ``Cache-Control:\n            max-age`` parameter of responses to requests which call this view.\n            For example: ``http_cache=datetime.timedelta(days=1)`` instructs\n            the requesting browser to 'cache this response for a day, please'.\n\n          - Zero (``0``).  If the value is zero, the ``Cache-Control`` and\n            ``Expires`` headers present in all responses from this view will\n            be composed such that client browser cache (and any intermediate\n            caches) are instructed to never cache the response.\n\n          - A two-tuple.  If it's a two tuple (e.g. ``http_cache=(1,\n            {'public':True})``), the first value in the tuple may be a\n            nonzero integer or a ``datetime.timedelta`` instance; in either\n            case this value will be used as the number of seconds to cache\n            the response.  The second value in the tuple must be a\n            dictionary.  The values present in the dictionary will be used as\n            input to the ``Cache-Control`` response header.  For example:\n            ``http_cache=(3600, {'public':True})`` means 'cache for an hour,\n            and add ``public`` to the Cache-Control header of the response'.\n            All keys and values supported by the\n            ``webob.cachecontrol.CacheControl`` interface may be added to the\n            dictionary.  Supplying ``{'public':True}`` is equivalent to\n            calling ``response.cache_control.public = True``.\n\n          Providing a non-tuple value as ``http_cache`` is equivalent to\n          calling ``response.cache_expires(value)`` within your view's body.\n\n          Providing a two-tuple value as ``http_cache`` is equivalent to\n          calling ``response.cache_expires(value[0], **value[1])`` within your\n          view's body.\n\n          If you wish to avoid influencing, the ``Expires`` header, and\n          instead wish to only influence ``Cache-Control`` headers, pass a\n          tuple as ``http_cache`` with the first element of ``None``, e.g.:\n          ``(None, {'public':True})``.\n\n          If you wish to prevent a view that uses ``http_cache`` in its\n          configuration from having its caching response headers changed by\n          this machinery, set ``response.cache_control.prevent_auto = True``\n          before returning the response from the view.  This effectively\n          disables any HTTP caching done by ``http_cache`` for that response.\n\n        wrapper\n\n          The :term:`view name` of a different :term:`view\n          configuration` which will receive the response body of this\n          view as the ``request.wrapped_body`` attribute of its own\n          :term:`request`, and the :term:`response` returned by this\n          view as the ``request.wrapped_response`` attribute of its\n          own request.  Using a wrapper makes it possible to \"chain\"\n          views together to form a composite response.  The response\n          of the outermost wrapper view will be returned to the user.\n          The wrapper view will be found as any view is found: see\n          :ref:`view_lookup`.  The \"best\" wrapper view will be found\n          based on the lookup ordering: \"under the hood\" this wrapper\n          view is looked up via\n          ``pyramid.view.render_view_to_response(context, request,\n          'wrapper_viewname')``. The context and request of a wrapper\n          view is the same context and request of the inner view.  If\n          this attribute is unspecified, no view wrapping is done.\n\n        decorator\n\n          A :term:`dotted Python name` to function (or the function itself,\n          or an iterable of the aforementioned) which will be used to\n          decorate the registered :term:`view callable`.  The decorator\n          function(s) will be called with the view callable as a single\n          argument.  The view callable it is passed will accept\n          ``(context, request)``.  The decorator(s) must return a\n          replacement view callable which also accepts ``(context,\n          request)``.\n\n          If decorator is an iterable, the callables will be combined and\n          used in the order provided as a decorator.\n          For example::\n\n            @view_config(...,\n                decorator=(decorator2,\n                           decorator1))\n            def myview(request):\n                ....\n\n          Is similar to doing::\n\n            @view_config(...)\n            @decorator2\n            @decorator1\n            def myview(request):\n                ...\n\n          Except with the existing benefits of ``decorator=`` (having a common\n          decorator syntax for all view calling conventions and not having to\n          think about preserving function attributes such as ``__name__`` and\n          ``__module__`` within decorator logic).\n\n          .. versionchanged:: 1.4a4\n             Passing an iterable.\n\n        mapper\n\n          A Python object or :term:`dotted Python name` which refers to a\n          :term:`view mapper`, or ``None``.  By default it is ``None``, which\n          indicates that the view should use the default view mapper.  This\n          plug-point is useful for Pyramid extension developers, but it's not\n          very useful for 'civilians' who are just developing stock Pyramid\n          applications. Pay no attention to the man behind the curtain.\n\n        Predicate Arguments\n\n        name\n\n          The :term:`view name`.  Read :ref:`traversal_chapter` to\n          understand the concept of a view name.\n\n        context\n\n          An object or a :term:`dotted Python name` referring to an\n          interface or class object that the :term:`context` must be\n          an instance of, *or* the :term:`interface` that the\n          :term:`context` must provide in order for this view to be\n          found and called.  This predicate is true when the\n          :term:`context` is an instance of the represented class or\n          if the :term:`context` provides the represented interface;\n          it is otherwise false.  This argument may also be provided\n          to ``add_view`` as ``for_`` (an older, still-supported\n          spelling).\n\n        route_name\n\n          This value must match the ``name`` of a :term:`route\n          configuration` declaration (see :ref:`urldispatch_chapter`)\n          that must match before this view will be called.\n\n        request_type\n\n          This value should be an :term:`interface` that the\n          :term:`request` must provide in order for this view to be\n          found and called.  This value exists only for backwards\n          compatibility purposes.\n\n        request_method\n\n          This value can be one of the strings ``GET``, ``POST``, ``PUT``,\n          ``DELETE``, or ``HEAD`` representing an HTTP ``REQUEST_METHOD``, or\n          a tuple containing one or more of these strings.  A view\n          declaration with this argument ensures that the view will only be\n          called when the request's ``method`` attribute (aka the\n          ``REQUEST_METHOD`` of the WSGI environment) string matches a\n          supplied value.  Note that use of ``GET`` also implies that the\n          view will respond to ``HEAD`` as of Pyramid 1.4.\n\n          .. versionchanged:: 1.2\n             The ability to pass a tuple of items as ``request_method``.\n             Previous versions allowed only a string.\n\n        request_param\n\n          This value can be any string or any sequence of strings.  A view \n          declaration with this argument ensures that the view will only be \n          called when the :term:`request` has a key in the ``request.params``\n          dictionary (an HTTP ``GET`` or ``POST`` variable) that has a\n          name which matches the supplied value (if the value is a string)\n          or values (if the value is a tuple).  If any value\n          supplied has a ``=`` sign in it,\n          e.g. ``request_param=\"foo=123\"``, then the key (``foo``)\n          must both exist in the ``request.params`` dictionary, *and*\n          the value must match the right hand side of the expression\n          (``123``) for the view to \"match\" the current request.\n\n        match_param\n\n          .. versionadded:: 1.2\n\n          This value can be a string of the format \"key=value\" or a tuple\n          containing one or more of these strings.\n\n          A view declaration with this argument ensures that the view will\n          only be called when the :term:`request` has key/value pairs in its\n          :term:`matchdict` that equal those supplied in the predicate.\n          e.g. ``match_param=\"action=edit\" would require the ``action``\n          parameter in the :term:`matchdict` match the right hand side of\n          the expression (``edit``) for the view to \"match\" the current\n          request.\n\n          If the ``match_param`` is a tuple, every key/value pair must match\n          for the predicate to pass.\n\n        containment\n\n          This value should be a Python class or :term:`interface` (or a\n          :term:`dotted Python name`) that an object in the\n          :term:`lineage` of the context must provide in order for this view\n          to be found and called.  The nodes in your object graph must be\n          \"location-aware\" to use this feature.  See\n          :ref:`location_aware` for more information about\n          location-awareness.\n\n        xhr\n\n          This value should be either ``True`` or ``False``.  If this\n          value is specified and is ``True``, the :term:`request`\n          must possess an ``HTTP_X_REQUESTED_WITH`` (aka\n          ``X-Requested-With``) header that has the value\n          ``XMLHttpRequest`` for this view to be found and called.\n          This is useful for detecting AJAX requests issued from\n          jQuery, Prototype and other Javascript libraries.\n\n        accept\n\n          The value of this argument represents a match query for one\n          or more mimetypes in the ``Accept`` HTTP request header.  If\n          this value is specified, it must be in one of the following\n          forms: a mimetype match token in the form ``text/plain``, a\n          wildcard mimetype match token in the form ``text/*`` or a\n          match-all wildcard mimetype match token in the form ``*/*``.\n          If any of the forms matches the ``Accept`` header of the\n          request, this predicate will be true.\n\n        header\n\n          This value represents an HTTP header name or a header\n          name/value pair.  If the value contains a ``:`` (colon), it\n          will be considered a name/value pair\n          (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``).  The\n          value portion should be a regular expression.  If the value\n          does not contain a colon, the entire value will be\n          considered to be the header name\n          (e.g. ``If-Modified-Since``).  If the value evaluates to a\n          header name only without a value, the header specified by\n          the name must be present in the request for this predicate\n          to be true.  If the value evaluates to a header name/value\n          pair, the header specified by the name must be present in\n          the request *and* the regular expression specified as the\n          value must match the header value.  Whether or not the value\n          represents a header name or a header name/value pair, the\n          case of the header name is not significant.\n\n        path_info\n\n          This value represents a regular expression pattern that will\n          be tested against the ``PATH_INFO`` WSGI environment\n          variable.  If the regex matches, this predicate will be\n          ``True``.\n\n        check_csrf\n\n          If specified, this value should be one of ``None``, ``True``,\n          ``False``, or a string representing the 'check name'.  If the value\n          is ``True`` or a string, CSRF checking will be performed.  If the\n          value is ``False`` or ``None``, CSRF checking will not be performed.\n\n          If the value provided is a string, that string will be used as the\n          'check name'.  If the value provided is ``True``, ``csrf_token`` will\n          be used as the check name.\n\n          If CSRF checking is performed, the checked value will be the value\n          of ``request.params[check_name]``.  This value will be compared\n          against the value of ``request.session.get_csrf_token()``, and the\n          check will pass if these two values are the same.  If the check\n          passes, the associated view will be permitted to execute.  If the\n          check fails, the associated view will not be permitted to execute.\n\n          Note that using this feature requires a :term:`session factory` to\n          have been configured.\n         \n          .. versionadded:: 1.4a2\n\n        physical_path\n\n          If specified, this value should be a string or a tuple representing\n          the :term:`physical path` of the context found via traversal for this\n          predicate to match as true.  For example: ``physical_path='/'`` or\n          ``physical_path='/a/b/c'`` or ``physical_path=('', 'a', 'b', 'c')``.\n          This is not a path prefix match or a regex, it's a whole-path match.\n          It's useful when you want to always potentially show a view when some\n          object is traversed to, but you can't be sure about what kind of\n          object it will be, so you can't use the ``context`` predicate.  The\n          individual path elements inbetween slash characters or in tuple\n          elements should be the Unicode representation of the name of the\n          resource and should not be encoded in any way.\n\n          .. versionadded:: 1.4a3\n\n        effective_principals\n\n          If specified, this value should be a :term:`principal` identifier or\n          a sequence of principal identifiers.  If the\n          :func:`pyramid.security.effective_principals` method indicates that\n          every principal named in the argument list is present in the current\n          request, this predicate will return True; otherwise it will return\n          False.  For example:\n          ``effective_principals=pyramid.security.Authenticated`` or\n          ``effective_principals=('fred', 'group:admins')``.\n\n          .. versionadded:: 1.4a4\n\n        custom_predicates\n\n          .. deprecated:: 1.5\n\n          This value should be a sequence of references to custom predicate\n          callables.  Use custom predicates when no set of predefined\n          predicates do what you need.  Custom predicates can be combined with\n          predefined predicates as necessary.  Each custom predicate callable\n          should accept two arguments: ``context`` and ``request`` and should\n          return either ``True`` or ``False`` after doing arbitrary evaluation\n          of the context and/or the request.  The ``predicates`` argument to\n          this method and the ability to register third-party view predicates\n          via :meth:`pyramid.config.Configurator.add_view_predicate` obsoletes\n          this argument, but it is kept around for backwards compatibility.\n\n        predicates\n\n          Pass a key/value pair here to use a third-party predicate\n          registered via\n          :meth:`pyramid.config.Configurator.add_view_predicate`.  More than\n          one key/value pair can be used at the same time.  See\n          :ref:`view_and_route_predicates` for more information about\n          third-party predicates.\n\n          .. versionadded: 1.4a1\n\n        \"\"\"\n        if custom_predicates:\n            warnings.warn(\n                ('The \"custom_predicates\" argument to Configurator.add_view '\n                 'is deprecated as of Pyramid 1.5.  Use '\n                 '\"config.add_view_predicate\" and use the registered '\n                 'view predicate as a predicate argument to add_view instead. '\n                 'See \"Adding A Third Party View, Route, or Subscriber '\n                 'Predicate\" in the \"Hooks\" chapter of the documentation '\n                 'for more information.'),\n                DeprecationWarning,\n                stacklevel=4\n                )\n        \n        view = self.maybe_dotted(view)\n        context = self.maybe_dotted(context)\n        for_ = self.maybe_dotted(for_)\n        containment = self.maybe_dotted(containment)\n        mapper = self.maybe_dotted(mapper)\n\n        def combine(*decorators):\n            def decorated(view_callable):\n                # reversed() is allows a more natural ordering in the api\n                for decorator in reversed(decorators):\n                    view_callable = decorator(view_callable)\n                return view_callable\n            return decorated\n\n        if is_nonstr_iter(decorator):\n            decorator = combine(*map(self.maybe_dotted, decorator))\n        else:\n            decorator = self.maybe_dotted(decorator)\n\n        if not view:\n            if renderer:\n                def view(context, request):\n                    return {}\n            else:\n                raise ConfigurationError('\"view\" was not specified and '\n                                         'no \"renderer\" specified')\n\n        if request_type is not None:\n            request_type = self.maybe_dotted(request_type)\n            if not IInterface.providedBy(request_type):\n                raise ConfigurationError(\n                    'request_type must be an interface, not %s' % request_type)\n\n        if context is None:\n            context = for_\n\n        r_context = context\n        if r_context is None:\n            r_context = Interface\n        if not IInterface.providedBy(r_context):\n            r_context = implementedBy(r_context)\n\n        if isinstance(renderer, string_types):\n            renderer = renderers.RendererHelper(\n                name=renderer, package=self.package,\n                registry = self.registry)\n\n        if accept is not None:\n            accept = accept.lower()\n\n        introspectables = []\n        pvals = predicates.copy()\n        pvals.update(\n            dict(\n                xhr=xhr,\n                request_method=request_method,\n                path_info=path_info,\n                request_param=request_param,\n                header=header,\n                accept=accept,\n                containment=containment,\n                request_type=request_type,\n                match_param=match_param,\n                check_csrf=check_csrf,\n                custom=predvalseq(custom_predicates),\n                )\n            )\n\n        def discrim_func():\n            # We need to defer the discriminator until we know what the phash\n            # is.  It can't be computed any sooner because thirdparty\n            # predicates may not yet exist when add_view is called.\n            order, preds, phash = predlist.make(self, **pvals)\n            view_intr.update({'phash':phash, 'order':order, 'predicates':preds})\n            return ('view', context, name, route_name, phash)\n\n        discriminator = Deferred(discrim_func)\n\n        if inspect.isclass(view) and attr:\n            view_desc = 'method %r of %s' % (\n                attr, self.object_description(view))\n        else:\n            view_desc = self.object_description(view)\n\n        tmpl_intr = None\n            \n        view_intr = self.introspectable('views',\n                                        discriminator,\n                                        view_desc,\n                                        'view')\n        view_intr.update(\n            dict(name=name,\n                 context=context,\n                 containment=containment,\n                 request_param=request_param,\n                 request_methods=request_method,\n                 route_name=route_name,\n                 attr=attr,\n                 xhr=xhr,\n                 accept=accept,\n                 header=header,\n                 path_info=path_info,\n                 match_param=match_param,\n                 check_csrf=check_csrf,\n                 callable=view,\n                 mapper=mapper,\n                 decorator=decorator,\n                 )\n            )\n        view_intr.update(**predicates)\n        introspectables.append(view_intr)\n        predlist = self.get_predlist('view')\n\n        def register(permission=permission, renderer=renderer):\n            # the discrim_func above is guaranteed to have been called already\n            order = view_intr['order']\n            preds = view_intr['predicates']\n            phash = view_intr['phash']\n            request_iface = IRequest\n            if route_name is not None:\n                request_iface = self.registry.queryUtility(IRouteRequest,\n                                                           name=route_name)\n                if request_iface is None:\n                    # route configuration should have already happened in\n                    # phase 2\n                    raise ConfigurationError(\n                        'No route named %s found for view registration' %\n                        route_name)\n\n            if renderer is None:\n                # use default renderer if one exists (reg'd in phase 1)\n                if self.registry.queryUtility(IRendererFactory) is not None:\n                    renderer = renderers.RendererHelper(\n                        name=None,\n                        package=self.package,\n                        registry=self.registry\n                        )\n\n            if permission is None:\n                # intent: will be None if no default permission is registered\n                # (reg'd in phase 1)\n                permission = self.registry.queryUtility(IDefaultPermission)\n\n            # added by discrim_func above during conflict resolving\n            preds = view_intr['predicates']\n            order = view_intr['order']\n            phash = view_intr['phash']\n\n            # __no_permission_required__ handled by _secure_view\n            deriver = ViewDeriver(\n                registry=self.registry,\n                permission=permission,\n                predicates=preds,\n                attr=attr,\n                renderer=renderer,\n                wrapper_viewname=wrapper,\n                viewname=name,\n                accept=accept,\n                order=order,\n                phash=phash,\n                package=self.package,\n                mapper=mapper,\n                decorator=decorator,\n                http_cache=http_cache,\n                )\n            derived_view = deriver(view)\n            derived_view.__discriminator__ = lambda *arg: discriminator\n            # __discriminator__ is used by superdynamic systems\n            # that require it for introspection after manual view lookup;\n            # see also MultiView.__discriminator__\n            view_intr['derived_callable'] = derived_view\n\n            registered = self.registry.adapters.registered\n\n            # A multiviews is a set of views which are registered for\n            # exactly the same context type/request type/name triad.  Each\n            # consituent view in a multiview differs only by the\n            # predicates which it possesses.\n\n            # To find a previously registered view for a context\n            # type/request type/name triad, we need to use the\n            # ``registered`` method of the adapter registry rather than\n            # ``lookup``.  ``registered`` ignores interface inheritance\n            # for the required and provided arguments, returning only a\n            # view registered previously with the *exact* triad we pass\n            # in.\n\n            # We need to do this three times, because we use three\n            # different interfaces as the ``provided`` interface while\n            # doing registrations, and ``registered`` performs exact\n            # matches on all the arguments it receives.\n\n            old_view = None\n\n            for view_type in (IView, ISecuredView, IMultiView):\n                old_view = registered((IViewClassifier, request_iface,\n                                       r_context), view_type, name)\n                if old_view is not None:\n                    break\n\n            isexc = isexception(context)\n\n            def regclosure():\n                if hasattr(derived_view, '__call_permissive__'):\n                    view_iface = ISecuredView\n                else:\n                    view_iface = IView\n                self.registry.registerAdapter(\n                    derived_view,\n                    (IViewClassifier, request_iface, context), view_iface, name\n                    )\n                if isexc:\n                    self.registry.registerAdapter(\n                        derived_view,\n                        (IExceptionViewClassifier, request_iface, context),\n                        view_iface, name)\n\n            is_multiview = IMultiView.providedBy(old_view)\n            old_phash = getattr(old_view, '__phash__', DEFAULT_PHASH)\n\n            if old_view is None:\n                # - No component was yet registered for any of our I*View\n                #   interfaces exactly; this is the first view for this\n                #   triad.\n                regclosure()\n\n            elif (not is_multiview) and (old_phash == phash):\n                # - A single view component was previously registered with\n                #   the same predicate hash as this view; this registration\n                #   is therefore an override.\n                regclosure()\n\n            else:\n                # - A view or multiview was already registered for this\n                #   triad, and the new view is not an override.\n\n                # XXX we could try to be more efficient here and register\n                # a non-secured view for a multiview if none of the\n                # multiview's consituent views have a permission\n                # associated with them, but this code is getting pretty\n                # rough already\n                if is_multiview:\n                    multiview = old_view\n                else:\n                    multiview = MultiView(name)\n                    old_accept = getattr(old_view, '__accept__', None)\n                    old_order = getattr(old_view, '__order__', MAX_ORDER)\n                    multiview.add(old_view, old_order, old_accept, old_phash)\n                multiview.add(derived_view, order, accept, phash)\n                for view_type in (IView, ISecuredView):\n                    # unregister any existing views\n                    self.registry.adapters.unregister(\n                        (IViewClassifier, request_iface, r_context),\n                        view_type, name=name)\n                    if isexc:\n                        self.registry.adapters.unregister(\n                            (IExceptionViewClassifier, request_iface,\n                             r_context), view_type, name=name)\n                self.registry.registerAdapter(\n                    multiview,\n                    (IViewClassifier, request_iface, context),\n                    IMultiView, name=name)\n                if isexc:\n                    self.registry.registerAdapter(\n                        multiview,\n                        (IExceptionViewClassifier, request_iface, context),\n                        IMultiView, name=name)\n            renderer_type = getattr(renderer, 'type', None) # gard against None\n            intrspc = self.introspector\n            if (\n                renderer_type is not None and\n                tmpl_intr is not None and\n                intrspc is not None and\n                intrspc.get('renderer factories', renderer_type) is not None\n                ):\n                # allow failure of registered template factories to be deferred\n                # until view execution, like other bad renderer factories; if\n                # we tried to relate this to an existing renderer factory\n                # without checking if it the factory actually existed, we'd end\n                # up with a KeyError at startup time, which is inconsistent\n                # with how other bad renderer registrations behave (they throw\n                # a ValueError at view execution time)\n                tmpl_intr.relate('renderer factories', renderer.type)\n\n        if mapper:\n            mapper_intr = self.introspectable(\n                'view mappers',\n                discriminator,\n                'view mapper for %s' % view_desc,\n                'view mapper'\n                )\n            mapper_intr['mapper'] = mapper\n            mapper_intr.relate('views', discriminator)\n            introspectables.append(mapper_intr)\n        if route_name:\n            view_intr.relate('routes', route_name) # see add_route\n        if renderer is not None and renderer.name and '.' in renderer.name:\n            # the renderer is a template\n            tmpl_intr = self.introspectable(\n                'templates',\n                discriminator,\n                renderer.name,\n                'template'\n                )\n            tmpl_intr.relate('views', discriminator)\n            tmpl_intr['name'] = renderer.name\n            tmpl_intr['type'] = renderer.type\n            tmpl_intr['renderer'] = renderer\n            introspectables.append(tmpl_intr)\n        if permission is not None:\n            # if a permission exists, register a permission introspectable\n            perm_intr = self.introspectable(\n                'permissions',\n                permission,\n                permission,\n                'permission'\n                )\n            perm_intr['value'] = permission\n            perm_intr.relate('views', discriminator)\n            introspectables.append(perm_intr)\n        self.action(discriminator, register, introspectables=introspectables)\n\n    @action_method\n    def add_view_predicate(self, name, factory, weighs_more_than=None,\n                           weighs_less_than=None):\n        \"\"\"\n        .. versionadded:: 1.4\n\n        Adds a view predicate factory.  The associated view predicate can\n        later be named as a keyword argument to\n        :meth:`pyramid.config.Configurator.add_view` in the\n        ``predicates`` anonyous keyword argument dictionary.\n\n        ``name`` should be the name of the predicate.  It must be a valid\n        Python identifier (it will be used as a keyword argument to\n        ``add_view`` by others).\n\n        ``factory`` should be a :term:`predicate factory` or :term:`dotted\n        Python name` which refers to a predicate factory.\n\n        See :ref:`view_and_route_predicates` for more information.\n        \"\"\"\n        self._add_predicate(\n            'view',\n            name,\n            factory,\n            weighs_more_than=weighs_more_than,\n            weighs_less_than=weighs_less_than\n            )\n\n    def add_default_view_predicates(self):\n        p = pyramid.config.predicates\n        for (name, factory) in (\n            ('xhr', p.XHRPredicate),\n            ('request_method', p.RequestMethodPredicate),\n            ('path_info', p.PathInfoPredicate),\n            ('request_param', p.RequestParamPredicate),\n            ('header', p.HeaderPredicate),\n            ('accept', p.AcceptPredicate),\n            ('containment', p.ContainmentPredicate),\n            ('request_type', p.RequestTypePredicate),\n            ('match_param', p.MatchParamPredicate),\n            ('check_csrf', p.CheckCSRFTokenPredicate),\n            ('physical_path', p.PhysicalPathPredicate),\n            ('effective_principals', p.EffectivePrincipalsPredicate),\n            ('custom', p.CustomPredicate),\n            ):\n            self.add_view_predicate(name, factory)\n\n    def derive_view(self, view, attr=None, renderer=None):\n        \"\"\"\n        Create a :term:`view callable` using the function, instance,\n        or class (or :term:`dotted Python name` referring to the same)\n        provided as ``view`` object.\n\n        .. warning::\n\n           This method is typically only used by :app:`Pyramid` framework\n           extension authors, not by :app:`Pyramid` application developers.\n\n        This is API is useful to framework extenders who create\n        pluggable systems which need to register 'proxy' view\n        callables for functions, instances, or classes which meet the\n        requirements of being a :app:`Pyramid` view callable.  For\n        example, a ``some_other_framework`` function in another\n        framework may want to allow a user to supply a view callable,\n        but he may want to wrap the view callable in his own before\n        registering the wrapper as a :app:`Pyramid` view callable.\n        Because a :app:`Pyramid` view callable can be any of a\n        number of valid objects, the framework extender will not know\n        how to call the user-supplied object.  Running it through\n        ``derive_view`` normalizes it to a callable which accepts two\n        arguments: ``context`` and ``request``.\n\n        For example:\n\n        .. code-block:: python\n\n           def some_other_framework(user_supplied_view):\n               config = Configurator(reg)\n               proxy_view = config.derive_view(user_supplied_view)\n               def my_wrapper(context, request):\n                   do_something_that_mutates(request)\n                   return proxy_view(context, request)\n               config.add_view(my_wrapper)\n\n        The ``view`` object provided should be one of the following:\n\n        - A function or another non-class callable object that accepts\n          a :term:`request` as a single positional argument and which\n          returns a :term:`response` object.\n\n        - A function or other non-class callable object that accepts\n          two positional arguments, ``context, request`` and which\n          returns a :term:`response` object.\n\n        - A class which accepts a single positional argument in its\n          constructor named ``request``, and which has a ``__call__``\n          method that accepts no arguments that returns a\n          :term:`response` object.\n\n        - A class which accepts two positional arguments named\n          ``context, request``, and which has a ``__call__`` method\n          that accepts no arguments that returns a :term:`response`\n          object.\n\n        - A :term:`dotted Python name` which refers to any of the\n          kinds of objects above.\n\n        This API returns a callable which accepts the arguments\n        ``context, request`` and which returns the result of calling\n        the provided ``view`` object.\n\n        The ``attr`` keyword argument is most useful when the view\n        object is a class.  It names the method that should be used as\n        the callable.  If ``attr`` is not provided, the attribute\n        effectively defaults to ``__call__``.  See\n        :ref:`class_as_view` for more information.\n\n        The ``renderer`` keyword argument should be a renderer\n        name. If supplied, it will cause the returned callable to use\n        a :term:`renderer` to convert the user-supplied view result to\n        a :term:`response` object.  If a ``renderer`` argument is not\n        supplied, the user-supplied view must itself return a\n        :term:`response` object.  \"\"\"\n        return self._derive_view(view, attr=attr, renderer=renderer)\n\n    # b/w compat\n    def _derive_view(self, view, permission=None, predicates=(),\n                     attr=None, renderer=None, wrapper_viewname=None,\n                     viewname=None, accept=None, order=MAX_ORDER,\n                     phash=DEFAULT_PHASH, decorator=None,\n                     mapper=None, http_cache=None):\n        view = self.maybe_dotted(view)\n        mapper = self.maybe_dotted(mapper)\n        if isinstance(renderer, string_types):\n            renderer = renderers.RendererHelper(\n                name=renderer, package=self.package,\n                registry = self.registry)\n        if renderer is None:\n            # use default renderer if one exists\n            if self.registry.queryUtility(IRendererFactory) is not None:\n                renderer = renderers.RendererHelper(\n                    name=None,\n                    package=self.package,\n                    registry=self.registry)\n\n        deriver = ViewDeriver(registry=self.registry,\n                              permission=permission,\n                              predicates=predicates,\n                              attr=attr,\n                              renderer=renderer,\n                              wrapper_viewname=wrapper_viewname,\n                              viewname=viewname,\n                              accept=accept,\n                              order=order,\n                              phash=phash,\n                              package=self.package,\n                              mapper=mapper,\n                              decorator=decorator,\n                              http_cache=http_cache)\n\n        return deriver(view)\n\n    @action_method\n    def add_forbidden_view(\n        self,\n        view=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        route_name=None,\n        request_type=None,\n        request_method=None, \n        request_param=None,\n        containment=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        decorator=None,\n        mapper=None,\n        match_param=None,\n        **predicates\n        ):\n        \"\"\" Add a forbidden view to the current configuration state.  The\n        view will be called when Pyramid or application code raises a\n        :exc:`pyramid.httpexceptions.HTTPForbidden` exception and the set of\n        circumstances implied by the predicates provided are matched.  The\n        simplest example is:\n\n          .. code-block:: python\n\n            def forbidden(request):\n                return Response('Forbidden', status='403 Forbidden')\n\n            config.add_forbidden_view(forbidden)\n\n        All arguments have the same meaning as\n        :meth:`pyramid.config.Configurator.add_view` and each predicate\n        argument restricts the set of circumstances under which this notfound\n        view will be invoked.  Unlike\n        :meth:`pyramid.config.Configurator.add_view`, this method will raise\n        an exception if passed ``name``, ``permission``, ``context``,\n        ``for_``, or ``http_cache`` keyword arguments.  These argument values\n        make no sense in the context of a forbidden view.\n\n        .. versionadded:: 1.3\n        \"\"\"\n        for arg in ('name', 'permission', 'context', 'for_', 'http_cache'):\n            if arg in predicates:\n                raise ConfigurationError(\n                    '%s may not be used as an argument to add_forbidden_view'\n                    % arg\n                    )\n        \n        settings = dict(\n            view=view,\n            context=HTTPForbidden,\n            wrapper=wrapper,\n            request_type=request_type,\n            request_method=request_method,\n            request_param=request_param,\n            containment=containment,\n            xhr=xhr,\n            accept=accept,\n            header=header, \n            path_info=path_info,\n            custom_predicates=custom_predicates,\n            decorator=decorator,\n            mapper=mapper,\n            match_param=match_param,\n            route_name=route_name,\n            permission=NO_PERMISSION_REQUIRED,\n            attr=attr,\n            renderer=renderer,\n            )\n        settings.update(predicates)\n        return self.add_view(**settings)\n\n    set_forbidden_view = add_forbidden_view # deprecated sorta-bw-compat alias\n    \n    @action_method\n    def add_notfound_view(\n        self,\n        view=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        route_name=None,\n        request_type=None,\n        request_method=None, \n        request_param=None,\n        containment=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        decorator=None,\n        mapper=None,\n        match_param=None,\n        append_slash=False,\n        **predicates\n        ):\n        \"\"\" Add a default Not Found View to the current configuration state.\n        The view will be called when Pyramid or application code raises an\n        :exc:`pyramid.httpexceptions.HTTPNotFound` exception (e.g. when a\n        view cannot be found for the request).  The simplest example is:\n\n          .. code-block:: python\n\n            def notfound(request):\n                return Response('Not Found', status='404 Not Found')\n\n            config.add_notfound_view(notfound)\n\n        All arguments except ``append_slash`` have the same meaning as\n        :meth:`pyramid.config.Configurator.add_view` and each predicate\n        argument restricts the set of circumstances under which this notfound\n        view will be invoked.  Unlike\n        :meth:`pyramid.config.Configurator.add_view`, this method will raise\n        an exception if passed ``name``, ``permission``, ``context``,\n        ``for_``, or ``http_cache`` keyword arguments.  These argument values\n        make no sense in the context of a Not Found View.\n\n        If ``append_slash`` is ``True``, when this Not Found View is invoked,\n        and the current path info does not end in a slash, the notfound logic\n        will attempt to find a :term:`route` that matches the request's path\n        info suffixed with a slash.  If such a route exists, Pyramid will\n        issue a redirect to the URL implied by the route; if it does not,\n        Pyramid will return the result of the view callable provided as\n        ``view``, as normal.\n\n        .. versionadded:: 1.3\n        \"\"\"\n        for arg in ('name', 'permission', 'context', 'for_', 'http_cache'):\n            if arg in predicates:\n                raise ConfigurationError(\n                    '%s may not be used as an argument to add_notfound_view'\n                    % arg\n                    )\n                    \n        settings = dict(\n            view=view,\n            context=HTTPNotFound,\n            wrapper=wrapper,\n            request_type=request_type,\n            request_method=request_method,\n            request_param=request_param,\n            containment=containment,\n            xhr=xhr,\n            accept=accept,\n            header=header, \n            path_info=path_info,\n            custom_predicates=custom_predicates,\n            decorator=decorator,\n            mapper=mapper,\n            match_param=match_param,\n            route_name=route_name,\n            permission=NO_PERMISSION_REQUIRED,\n            )\n        settings.update(predicates)\n        if append_slash:\n            view = self._derive_view(view, attr=attr, renderer=renderer)\n            view = AppendSlashNotFoundViewFactory(view)\n            settings['view'] = view\n        else:\n            settings['attr'] = attr\n            settings['renderer'] = renderer\n        return self.add_view(**settings)\n\n    set_notfound_view = add_notfound_view # deprecated sorta-bw-compat alias\n\n    @action_method\n    def set_view_mapper(self, mapper):\n        \"\"\"\n        Setting a :term:`view mapper` makes it possible to make use of\n        :term:`view callable` objects which implement different call\n        signatures than the ones supported by :app:`Pyramid` as described in\n        its narrative documentation.\n\n        The ``mapper`` should argument be an object implementing\n        :class:`pyramid.interfaces.IViewMapperFactory` or a :term:`dotted\n        Python name` to such an object.  The provided ``mapper`` will become\n        the default view mapper to be used by all subsequent :term:`view\n        configuration` registrations.\n\n        See also :ref:`using_a_view_mapper`.\n\n        .. note::\n\n           Using the ``default_view_mapper`` argument to the\n           :class:`pyramid.config.Configurator` constructor\n           can be used to achieve the same purpose.\n        \"\"\"\n        mapper = self.maybe_dotted(mapper)\n        def register():\n            self.registry.registerUtility(mapper, IViewMapperFactory)\n        # IViewMapperFactory is looked up as the result of view config\n        # in phase 3\n        intr = self.introspectable('view mappers',\n                                   IViewMapperFactory,\n                                   self.object_description(mapper),\n                                   'default view mapper')\n        intr['mapper'] = mapper\n        self.action(IViewMapperFactory, register, order=PHASE1_CONFIG,\n                    introspectables=(intr,))\n\n    @action_method\n    def add_static_view(self, name, path, **kw):\n        \"\"\" Add a view used to render static assets such as images\n        and CSS files.\n\n        The ``name`` argument is a string representing an\n        application-relative local URL prefix.  It may alternately be a full\n        URL.\n\n        The ``path`` argument is the path on disk where the static files\n        reside.  This can be an absolute path, a package-relative path, or a\n        :term:`asset specification`.\n\n        The ``cache_max_age`` keyword argument is input to set the\n        ``Expires`` and ``Cache-Control`` headers for static assets served.\n        Note that this argument has no effect when the ``name`` is a *url\n        prefix*.  By default, this argument is ``None``, meaning that no\n        particular Expires or Cache-Control headers are set in the response.\n\n        The ``permission`` keyword argument is used to specify the\n        :term:`permission` required by a user to execute the static view.  By\n        default, it is the string\n        :data:`pyramid.security.NO_PERMISSION_REQUIRED`, a special sentinel\n        which indicates that, even if a :term:`default permission` exists for\n        the current application, the static view should be renderered to\n        completely anonymous users.  This default value is permissive\n        because, in most web apps, static assets seldom need protection from\n        viewing.  If ``permission`` is specified, the security checking will\n        be performed against the default root factory ACL.\n\n        Any other keyword arguments sent to ``add_static_view`` are passed on\n        to :meth:`pyramid.config.Configurator.add_route` (e.g. ``factory``,\n        perhaps to define a custom factory with a custom ACL for this static\n        view).\n\n        *Usage*\n\n        The ``add_static_view`` function is typically used in conjunction\n        with the :meth:`pyramid.request.Request.static_url` method.\n        ``add_static_view`` adds a view which renders a static asset when\n        some URL is visited; :meth:`pyramid.request.Request.static_url`\n        generates a URL to that asset.\n\n        The ``name`` argument to ``add_static_view`` is usually a simple URL\n        prefix (e.g. ``'images'``).  When this is the case, the\n        :meth:`pyramid.request.Request.static_url` API will generate a URL\n        which points to a Pyramid view, which will serve up a set of assets\n        that live in the package itself. For example:\n\n        .. code-block:: python\n\n           add_static_view('images', 'mypackage:images/')\n\n        Code that registers such a view can generate URLs to the view via\n        :meth:`pyramid.request.Request.static_url`:\n\n        .. code-block:: python\n\n           request.static_url('mypackage:images/logo.png')\n\n        When ``add_static_view`` is called with a ``name`` argument that\n        represents a URL prefix, as it is above, subsequent calls to\n        :meth:`pyramid.request.Request.static_url` with paths that start with\n        the ``path`` argument passed to ``add_static_view`` will generate a\n        URL something like ``http://<Pyramid app URL>/images/logo.png``,\n        which will cause the ``logo.png`` file in the ``images`` subdirectory\n        of the ``mypackage`` package to be served.\n\n        ``add_static_view`` can alternately be used with a ``name`` argument\n        which is a *URL*, causing static assets to be served from an external\n        webserver.  This happens when the ``name`` argument is a fully\n        qualified URL (e.g. starts with ``http://`` or similar).  In this\n        mode, the ``name`` is used as the prefix of the full URL when\n        generating a URL using :meth:`pyramid.request.Request.static_url`.\n        Furthermore, if a protocol-relative URL (e.g. ``//example.com/images``)\n        is used as the ``name`` argument, the generated URL will use the\n        protocol of the request (http or https, respectively).\n\n        For example, if ``add_static_view`` is called like so:\n\n        .. code-block:: python\n\n           add_static_view('http://example.com/images', 'mypackage:images/')\n\n        Subsequently, the URLs generated by\n        :meth:`pyramid.request.Request.static_url` for that static view will\n        be prefixed with ``http://example.com/images`` (the external webserver\n        listening on ``example.com`` must be itself configured to respond\n        properly to such a request.):\n\n        .. code-block:: python\n\n           static_url('mypackage:images/logo.png', request)\n\n        See :ref:`static_assets_section` for more information.\n        \"\"\"\n        spec = self._make_spec(path)\n        info = self.registry.queryUtility(IStaticURLInfo)\n        if info is None:\n            info = StaticURLInfo()\n            self.registry.registerUtility(info, IStaticURLInfo)\n        info.add(self, name, spec, **kw)\n\ndef isexception(o):\n    if IInterface.providedBy(o):\n        if IException.isEqualOrExtendedBy(o):\n            return True\n    return (\n        isinstance(o, Exception) or\n        (inspect.isclass(o) and (issubclass(o, Exception)))\n        )\n\n\n@implementer(IStaticURLInfo)\nclass StaticURLInfo(object):\n\n    def _get_registrations(self, registry):\n        try:\n            reg = registry._static_url_registrations\n        except AttributeError:\n            reg = registry._static_url_registrations = []\n        return reg\n\n    def generate(self, path, request, **kw):\n        try:\n            registry = request.registry\n        except AttributeError: # bw compat (for tests)\n            registry = get_current_registry()\n        for (url, spec, route_name) in self._get_registrations(registry):\n            if path.startswith(spec):\n                subpath = path[len(spec):]\n                if WIN: # pragma: no cover\n                    subpath = subpath.replace('\\\\', '/') # windows\n                if url is None:\n                    kw['subpath'] = subpath\n                    return request.route_url(route_name, **kw)\n                else:\n                    parsed = url_parse(url)\n                    if not parsed.scheme:\n                        # parsed.scheme is readonly, so we have to parse again\n                        # to change the scheme, sigh.\n                        url = urlparse.urlunparse(url_parse(\n                            url, scheme=request.environ['wsgi.url_scheme']))\n                    subpath = url_quote(subpath)\n                    return urljoin(url, subpath)\n\n        raise ValueError('No static URL definition matching %s' % path)\n\n    def add(self, config, name, spec, **extra):\n        # This feature only allows for the serving of a directory and\n        # the files contained within, not of a single asset;\n        # appending a slash here if the spec doesn't have one is\n        # required for proper prefix matching done in ``generate``\n        # (``subpath = path[len(spec):]``).\n        if os.path.isabs(spec): # FBO windows\n            sep = os.sep\n        else:\n            sep = '/'\n        if not spec.endswith(sep):\n            spec = spec + sep\n\n        # we also make sure the name ends with a slash, purely as a\n        # convenience: a name that is a url is required to end in a\n        # slash, so that ``urljoin(name, subpath))`` will work above\n        # when the name is a URL, and it doesn't hurt things for it to\n        # have a name that ends in a slash if it's used as a route\n        # name instead of a URL.\n        if not name.endswith('/'):\n            # make sure it ends with a slash\n            name = name + '/'\n\n        if url_parse(name).netloc:\n            # it's a URL\n            # url, spec, route_name\n            url = name\n            route_name = None\n        else:\n            # it's a view name\n            url = None\n            cache_max_age = extra.pop('cache_max_age', None)\n            # create a view\n            view = static_view(spec, cache_max_age=cache_max_age,\n                               use_subpath=True)\n\n            # Mutate extra to allow factory, etc to be passed through here.\n            # Treat permission specially because we'd like to default to\n            # permissiveness (see docs of config.add_static_view).\n            permission = extra.pop('permission', None)\n            if permission is None:\n                permission = NO_PERMISSION_REQUIRED\n\n            context = extra.pop('context', None)\n            if context is None:\n                context = extra.pop('for_', None)\n\n            renderer = extra.pop('renderer', None)\n\n            # register a route using the computed view, permission, and\n            # pattern, plus any extras passed to us via add_static_view\n            pattern = \"%s*subpath\" % name # name already ends with slash\n            if config.route_prefix:\n                route_name = '__%s/%s' % (config.route_prefix, name)\n            else:\n                route_name = '__%s' % name\n            config.add_route(route_name, pattern, **extra)\n            config.add_view(\n                route_name=route_name,\n                view=view,\n                permission=permission,\n                context=context,\n                renderer=renderer,\n                )\n\n        def register():\n            registrations = self._get_registrations(config.registry)\n\n            names = [ t[0] for t in  registrations ]\n\n            if name in names:\n                idx = names.index(name)\n                registrations.pop(idx)\n\n            # url, spec, route_name\n            registrations.append((url, spec, route_name))\n\n        intr = config.introspectable('static views',\n                                     name,\n                                     'static view for %r' % name,\n                                     'static view')\n        intr['name'] = name\n        intr['spec'] = spec\n\n        config.action(None, callable=register, introspectables=(intr,))\n\n\n",
            "new_file_content": "import inspect\nimport operator\nimport os\nimport warnings\n\nfrom zope.interface import (\n    Interface,\n    implementedBy,\n    implementer,\n    provider,\n    )\n\nfrom zope.interface.interfaces import IInterface\n\nfrom pyramid.interfaces import (\n    IAuthenticationPolicy,\n    IAuthorizationPolicy,\n    IDebugLogger,\n    IDefaultPermission,\n    IException,\n    IExceptionViewClassifier,\n    IMultiView,\n    IRendererFactory,\n    IRequest,\n    IResponse,\n    IRouteRequest,\n    ISecuredView,\n    IStaticURLInfo,\n    IView,\n    IViewClassifier,\n    IViewMapper,\n    IViewMapperFactory,\n    PHASE1_CONFIG,\n    )\n\nfrom pyramid import renderers\n\nfrom pyramid.compat import (\n    string_types,\n    urlparse,\n    url_quote,\n    WIN,\n    is_bound_method,\n    is_nonstr_iter\n    )\n\nfrom pyramid.exceptions import (\n    ConfigurationError,\n    PredicateMismatch,\n    )\n\nfrom pyramid.httpexceptions import (\n    HTTPForbidden,\n    HTTPNotFound,\n    )\n\nfrom pyramid.registry import (\n    predvalseq,\n    Deferred,\n    )\n\nfrom pyramid.response import Response\n\nfrom pyramid.security import NO_PERMISSION_REQUIRED\nfrom pyramid.static import static_view\nfrom pyramid.threadlocal import get_current_registry\n\nfrom pyramid.view import (\n    render_view_to_response,\n    AppendSlashNotFoundViewFactory,\n    )\n\nfrom pyramid.util import (\n    object_description,\n    viewdefaults,\n    action_method,\n    )\n\nimport pyramid.config.predicates\n\nfrom pyramid.config.util import (\n    DEFAULT_PHASH,\n    MAX_ORDER,\n    takes_one_arg,\n    )\n\nurljoin = urlparse.urljoin\nurl_parse = urlparse.urlparse\n\ndef view_description(view):\n    try:\n        return view.__text__\n    except AttributeError:\n        # custom view mappers might not add __text__\n        return object_description(view)\n\ndef wraps_view(wrapper):\n    def inner(self, view):\n        wrapper_view = wrapper(self, view)\n        return preserve_view_attrs(view, wrapper_view)\n    return inner\n\ndef preserve_view_attrs(view, wrapper):\n    if view is None:\n        return wrapper\n\n    if wrapper is view:\n        return view\n\n    original_view = getattr(view, '__original_view__', None)\n\n    if original_view is None:\n        original_view = view\n\n    wrapper.__wraps__ = view\n    wrapper.__original_view__ = original_view\n    wrapper.__module__ = view.__module__\n    wrapper.__doc__ = view.__doc__\n\n    try:\n        wrapper.__name__ = view.__name__\n    except AttributeError:\n        wrapper.__name__ = repr(view)\n\n    # attrs that may not exist on \"view\", but, if so, must be attached to\n    # \"wrapped view\"\n    for attr in ('__permitted__', '__call_permissive__', '__permission__',\n                 '__predicated__', '__predicates__', '__accept__',\n                 '__order__', '__text__'):\n        try:\n            setattr(wrapper, attr, getattr(view, attr))\n        except AttributeError:\n            pass\n\n    return wrapper\n\nclass ViewDeriver(object):\n    def __init__(self, **kw):\n        self.kw = kw\n        self.registry = kw['registry']\n        self.authn_policy = self.registry.queryUtility(IAuthenticationPolicy)\n        self.authz_policy = self.registry.queryUtility(IAuthorizationPolicy)\n        self.logger = self.registry.queryUtility(IDebugLogger)\n\n    def __call__(self, view):\n        return self.attr_wrapped_view(\n            self.predicated_view(\n                self.authdebug_view(\n                    self.secured_view(\n                        self.owrapped_view(\n                            self.http_cached_view(\n                                self.decorated_view(\n                                    self.rendered_view(\n                                        self.mapped_view(\n                                                view)))))))))\n\n    @wraps_view\n    def mapped_view(self, view):\n        mapper = self.kw.get('mapper')\n        if mapper is None:\n            mapper = getattr(view, '__view_mapper__', None)\n            if mapper is None:\n                mapper = self.registry.queryUtility(IViewMapperFactory)\n                if mapper is None:\n                    mapper = DefaultViewMapper\n\n        mapped_view = mapper(**self.kw)(view)\n        return mapped_view\n\n    @wraps_view\n    def owrapped_view(self, view):\n        wrapper_viewname = self.kw.get('wrapper_viewname')\n        viewname = self.kw.get('viewname')\n        if not wrapper_viewname:\n            return view\n        def _owrapped_view(context, request):\n            response = view(context, request)\n            request.wrapped_response = response\n            request.wrapped_body = response.body\n            request.wrapped_view = view\n            wrapped_response = render_view_to_response(context, request,\n                                                       wrapper_viewname)\n            if wrapped_response is None:\n                raise ValueError(\n                    'No wrapper view named %r found when executing view '\n                    'named %r' % (wrapper_viewname, viewname))\n            return wrapped_response\n        return _owrapped_view\n\n    @wraps_view\n    def http_cached_view(self, view):\n        if self.registry.settings.get('prevent_http_cache', False):\n            return view\n\n        seconds = self.kw.get('http_cache')\n\n        if seconds is None:\n            return view\n\n        options = {}\n\n        if isinstance(seconds, (tuple, list)):\n            try:\n                seconds, options = seconds\n            except ValueError:\n                raise ConfigurationError(\n                    'If http_cache parameter is a tuple or list, it must be '\n                    'in the form (seconds, options); not %s' % (seconds,))\n\n        def wrapper(context, request):\n            response = view(context, request)\n            prevent_caching = getattr(response.cache_control, 'prevent_auto',\n                                      False)\n            if not prevent_caching:\n                response.cache_expires(seconds, **options)\n            return response\n\n        return wrapper\n\n    @wraps_view\n    def secured_view(self, view):\n        permission = self.kw.get('permission')\n        if permission == NO_PERMISSION_REQUIRED:\n            # allow views registered within configurations that have a\n            # default permission to explicitly override the default\n            # permission, replacing it with no permission at all\n            permission = None\n\n        wrapped_view = view\n        if self.authn_policy and self.authz_policy and (permission is not None):\n            def _permitted(context, request):\n                principals = self.authn_policy.effective_principals(request)\n                return self.authz_policy.permits(context, principals,\n                                                 permission)\n            def _secured_view(context, request):\n                result = _permitted(context, request)\n                if result:\n                    return view(context, request)\n                view_name = getattr(view, '__name__', view)\n                msg = getattr(\n                    request, 'authdebug_message',\n                    'Unauthorized: %s failed permission check' % view_name)\n                raise HTTPForbidden(msg, result=result)\n            _secured_view.__call_permissive__ = view\n            _secured_view.__permitted__ = _permitted\n            _secured_view.__permission__ = permission\n            wrapped_view = _secured_view\n\n        return wrapped_view\n\n    @wraps_view\n    def authdebug_view(self, view):\n        wrapped_view = view\n        settings = self.registry.settings\n        permission = self.kw.get('permission')\n        if settings and settings.get('debug_authorization', False):\n            def _authdebug_view(context, request):\n                view_name = getattr(request, 'view_name', None)\n\n                if self.authn_policy and self.authz_policy:\n                    if permission is NO_PERMISSION_REQUIRED:\n                        msg = 'Allowed (NO_PERMISSION_REQUIRED)'\n                    elif permission is None:\n                        msg = 'Allowed (no permission registered)'\n                    else:\n                        principals = self.authn_policy.effective_principals(\n                            request)\n                        msg = str(self.authz_policy.permits(context, principals,\n                                                            permission))\n                else:\n                    msg = 'Allowed (no authorization policy in use)'\n\n                view_name = getattr(request, 'view_name', None)\n                url = getattr(request, 'url', None)\n                msg = ('debug_authorization of url %s (view name %r against '\n                       'context %r): %s' % (url, view_name, context, msg))\n                self.logger and self.logger.debug(msg)\n                if request is not None:\n                    request.authdebug_message = msg\n                return view(context, request)\n\n            wrapped_view = _authdebug_view\n\n        return wrapped_view\n\n    @wraps_view\n    def predicated_view(self, view):\n        preds = self.kw.get('predicates', ())\n        if not preds:\n            return view\n        def predicate_wrapper(context, request):\n            for predicate in preds:\n                if not predicate(context, request):\n                    view_name = getattr(view, '__name__', view)\n                    raise PredicateMismatch(\n                         'predicate mismatch for view %s (%s)' % (\n                         view_name, predicate.text()))\n            return view(context, request)        \n        def checker(context, request):\n            return all((predicate(context, request) for predicate in\n                        preds))\n        predicate_wrapper.__predicated__ = checker\n        predicate_wrapper.__predicates__ = preds\n        return predicate_wrapper\n\n    @wraps_view\n    def attr_wrapped_view(self, view):\n        kw = self.kw\n        accept, order, phash = (kw.get('accept', None),\n                                kw.get('order', MAX_ORDER),\n                                kw.get('phash', DEFAULT_PHASH))\n        # this is a little silly but we don't want to decorate the original\n        # function with attributes that indicate accept, order, and phash,\n        # so we use a wrapper\n        if (\n            (accept is None) and\n            (order == MAX_ORDER) and\n            (phash == DEFAULT_PHASH)\n            ):\n            return view # defaults\n        def attr_view(context, request):\n            return view(context, request)\n        attr_view.__accept__ = accept\n        attr_view.__order__ = order\n        attr_view.__phash__ = phash\n        attr_view.__view_attr__ = self.kw.get('attr')\n        attr_view.__permission__ = self.kw.get('permission')\n        return attr_view\n\n    @wraps_view\n    def rendered_view(self, view):\n        # one way or another this wrapper must produce a Response (unless\n        # the renderer is a NullRendererHelper)\n        renderer = self.kw.get('renderer')\n        if renderer is None:\n            # register a default renderer if you want super-dynamic\n            # rendering.  registering a default renderer will also allow\n            # override_renderer to work if a renderer is left unspecified for\n            # a view registration.\n            return self._response_resolved_view(view)\n        if renderer is renderers.null_renderer:\n            return view\n        return self._rendered_view(view, renderer)\n\n    def _rendered_view(self, view, view_renderer):\n        def rendered_view(context, request):\n            renderer = view_renderer\n            result = view(context, request)\n            if result.__class__ is Response: # potential common case\n                response = result\n            else:\n                registry = self.registry\n                # this must adapt, it can't do a simple interface check\n                # (avoid trying to render webob responses)\n                response = registry.queryAdapterOrSelf(result, IResponse)\n                if response is None:\n                    attrs = getattr(request, '__dict__', {})\n                    if 'override_renderer' in attrs:\n                        # renderer overridden by newrequest event or other\n                        renderer_name = attrs.pop('override_renderer')\n                        renderer = renderers.RendererHelper(\n                            name=renderer_name,\n                            package=self.kw.get('package'),\n                            registry = registry)\n                    if '__view__' in attrs:\n                        view_inst = attrs.pop('__view__')\n                    else:\n                        view_inst = getattr(view, '__original_view__', view)\n                    response = renderer.render_view(request, result, view_inst,\n                                                    context)\n            return response\n\n        return rendered_view\n\n    def _response_resolved_view(self, view):\n        registry = self.registry\n        def viewresult_to_response(context, request):\n            result = view(context, request)\n            if result.__class__ is Response: # common case\n                response = result\n            else:\n                response = registry.queryAdapterOrSelf(result, IResponse)\n                if response is None:\n                    if result is None:\n                        append = (' You may have forgotten to return a value '\n                                  'from the view callable.')\n                    elif isinstance(result, dict):\n                        append = (' You may have forgotten to define a '\n                                  'renderer in the view configuration.')\n                    else:\n                        append = ''\n\n                    msg = ('Could not convert return value of the view '\n                           'callable %s into a response object. '\n                           'The value returned was %r.' + append)\n\n                    raise ValueError(msg % (view_description(view), result))\n\n            return response\n\n        return viewresult_to_response\n\n    @wraps_view\n    def decorated_view(self, view):\n        decorator = self.kw.get('decorator')\n        if decorator is None:\n            return view\n        return decorator(view)\n\n@implementer(IViewMapper)\n@provider(IViewMapperFactory)\nclass DefaultViewMapper(object):\n    def __init__(self, **kw):\n        self.attr = kw.get('attr')\n\n    def __call__(self, view):\n        if inspect.isclass(view):\n            view = self.map_class(view)\n        else:\n            view = self.map_nonclass(view)\n        return view\n\n    def map_class(self, view):\n        ronly = requestonly(view, self.attr)\n        if ronly:\n            mapped_view = self.map_class_requestonly(view)\n        else:\n            mapped_view = self.map_class_native(view)\n        mapped_view.__text__ = 'method %s of %s' % (\n            self.attr or '__call__', object_description(view))\n        return mapped_view\n\n    def map_nonclass(self, view):\n        # We do more work here than appears necessary to avoid wrapping the\n        # view unless it actually requires wrapping (to avoid function call\n        # overhead).\n        mapped_view = view\n        ronly = requestonly(view, self.attr)\n        if ronly:\n            mapped_view = self.map_nonclass_requestonly(view)\n        elif self.attr:\n            mapped_view = self.map_nonclass_attr(view)\n        if inspect.isroutine(mapped_view):\n            # This branch will be true if the view is a function or a method.\n            # We potentially mutate an unwrapped object here if it's a\n            # function.  We do this to avoid function call overhead of\n            # injecting another wrapper.  However, we must wrap if the\n            # function is a bound method because we can't set attributes on a\n            # bound method.\n            if is_bound_method(view):\n                _mapped_view = mapped_view\n                def mapped_view(context, request):\n                    return _mapped_view(context, request)\n            if self.attr is not None:\n                mapped_view.__text__ = 'attr %s of %s' % (\n                    self.attr, object_description(view))\n            else:\n                mapped_view.__text__ = object_description(view)\n        return mapped_view\n\n    def map_class_requestonly(self, view):\n        # its a class that has an __init__ which only accepts request\n        attr = self.attr\n        def _class_requestonly_view(context, request):\n            inst = view(request)\n            request.__view__ = inst\n            if attr is None:\n                response = inst()\n            else:\n                response = getattr(inst, attr)()\n            return response\n        return _class_requestonly_view\n\n    def map_class_native(self, view):\n        # its a class that has an __init__ which accepts both context and\n        # request\n        attr = self.attr\n        def _class_view(context, request):\n            inst = view(context, request)\n            request.__view__ = inst\n            if attr is None:\n                response = inst()\n            else:\n                response = getattr(inst, attr)()\n            return response\n        return _class_view\n\n    def map_nonclass_requestonly(self, view):\n        # its a function that has a __call__ which accepts only a single\n        # request argument\n        attr = self.attr\n        def _requestonly_view(context, request):\n            if attr is None:\n                response = view(request)\n            else:\n                response = getattr(view, attr)(request)\n            return response\n        return _requestonly_view\n\n    def map_nonclass_attr(self, view):\n        # its a function that has a __call__ which accepts both context and\n        # request, but still has an attr\n        def _attr_view(context, request):\n            response = getattr(view, self.attr)(context, request)\n            return response\n        return _attr_view\n\ndef requestonly(view, attr=None):\n    return takes_one_arg(view, attr=attr, argname='request')\n\n@implementer(IMultiView)\nclass MultiView(object):\n\n    def __init__(self, name):\n        self.name = name\n        self.media_views = {}\n        self.views = []\n        self.accepts = []\n\n    def __discriminator__(self, context, request):\n        # used by introspection systems like so:\n        # view = adapters.lookup(....)\n        # view.__discriminator__(context, request) -> view's discriminator\n        # so that superdynamic systems can feed the discriminator to\n        # the introspection system to get info about it\n        view = self.match(context, request)\n        return view.__discriminator__(context, request)\n\n    def add(self, view, order, accept=None, phash=None):\n        if phash is not None:\n            for i, (s, v, h) in enumerate(list(self.views)):\n                if phash == h:\n                    self.views[i] = (order, view, phash)\n                    return\n\n        if accept is None or '*' in accept:\n            self.views.append((order, view, phash))\n            self.views.sort(key=operator.itemgetter(0))\n        else:\n            subset = self.media_views.setdefault(accept, [])\n            for i, (s, v, h) in enumerate(list(subset)):\n                if phash == h:\n                    subset[i] = (order, view, phash)\n                    return\n            else:\n                subset.append((order, view, phash))\n                subset.sort(key=operator.itemgetter(0))\n            accepts = set(self.accepts)\n            accepts.add(accept)\n            self.accepts = list(accepts) # dedupe\n\n    def get_views(self, request):\n        if self.accepts and hasattr(request, 'accept'):\n            accepts = self.accepts[:]\n            views = []\n            while accepts:\n                match = request.accept.best_match(accepts)\n                if match is None:\n                    break\n                subset = self.media_views[match]\n                views.extend(subset)\n                accepts.remove(match)\n            views.extend(self.views)\n            return views\n        return self.views\n\n    def match(self, context, request):\n        for order, view, phash in self.get_views(request):\n            if not hasattr(view, '__predicated__'):\n                return view\n            if view.__predicated__(context, request):\n                return view\n        raise PredicateMismatch(self.name)\n\n    def __permitted__(self, context, request):\n        view = self.match(context, request)\n        if hasattr(view, '__permitted__'):\n            return view.__permitted__(context, request)\n        return True\n\n    def __call_permissive__(self, context, request):\n        view = self.match(context, request)\n        view = getattr(view, '__call_permissive__', view)\n        return view(context, request)\n\n    def __call__(self, context, request):\n        for order, view, phash in self.get_views(request):\n            try:\n                return view(context, request)\n            except PredicateMismatch:\n                continue\n        raise PredicateMismatch(self.name)\n\nclass ViewsConfiguratorMixin(object):\n    @viewdefaults\n    @action_method\n    def add_view(\n        self,\n        view=None,\n        name=\"\",\n        for_=None,\n        permission=None,\n        request_type=None,\n        route_name=None,\n        request_method=None,\n        request_param=None,\n        containment=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        context=None,\n        decorator=None,\n        mapper=None,\n        http_cache=None,\n        match_param=None,\n        check_csrf=None,\n        **predicates):\n        \"\"\" Add a :term:`view configuration` to the current\n        configuration state.  Arguments to ``add_view`` are broken\n        down below into *predicate* arguments and *non-predicate*\n        arguments.  Predicate arguments narrow the circumstances in\n        which the view callable will be invoked when a request is\n        presented to :app:`Pyramid`; non-predicate arguments are\n        informational.\n\n        Non-Predicate Arguments\n\n        view\n\n          A :term:`view callable` or a :term:`dotted Python name`\n          which refers to a view callable.  This argument is required\n          unless a ``renderer`` argument also exists.  If a\n          ``renderer`` argument is passed, and a ``view`` argument is\n          not provided, the view callable defaults to a callable that\n          returns an empty dictionary (see\n          :ref:`views_which_use_a_renderer`).\n\n        permission\n\n          A :term:`permission` that the user must possess in order to invoke\n          the :term:`view callable`.  See :ref:`view_security_section` for\n          more information about view security and permissions.  This is\n          often a string like ``view`` or ``edit``.\n\n          If ``permission`` is omitted, a *default* permission may be used\n          for this view registration if one was named as the\n          :class:`pyramid.config.Configurator` constructor's\n          ``default_permission`` argument, or if\n          :meth:`pyramid.config.Configurator.set_default_permission` was used\n          prior to this view registration.  Pass the value\n          :data:`pyramid.security.NO_PERMISSION_REQUIRED` as the permission\n          argument to explicitly indicate that the view should always be\n          executable by entirely anonymous users, regardless of the default\n          permission, bypassing any :term:`authorization policy` that may be\n          in effect.\n\n        attr\n\n          This knob is most useful when the view definition is a class.\n\n          The view machinery defaults to using the ``__call__`` method\n          of the :term:`view callable` (or the function itself, if the\n          view callable is a function) to obtain a response.  The\n          ``attr`` value allows you to vary the method attribute used\n          to obtain the response.  For example, if your view was a\n          class, and the class has a method named ``index`` and you\n          wanted to use this method instead of the class' ``__call__``\n          method to return the response, you'd say ``attr=\"index\"`` in the\n          view configuration for the view.\n\n        renderer\n\n          This is either a single string term (e.g. ``json``) or a\n          string implying a path or :term:`asset specification`\n          (e.g. ``templates/views.pt``) naming a :term:`renderer`\n          implementation.  If the ``renderer`` value does not contain\n          a dot ``.``, the specified string will be used to look up a\n          renderer implementation, and that renderer implementation\n          will be used to construct a response from the view return\n          value.  If the ``renderer`` value contains a dot (``.``),\n          the specified term will be treated as a path, and the\n          filename extension of the last element in the path will be\n          used to look up the renderer implementation, which will be\n          passed the full path.  The renderer implementation will be\n          used to construct a :term:`response` from the view return\n          value.\n\n          Note that if the view itself returns a :term:`response` (see\n          :ref:`the_response`), the specified renderer implementation\n          is never called.\n\n          When the renderer is a path, although a path is usually just\n          a simple relative pathname (e.g. ``templates/foo.pt``,\n          implying that a template named \"foo.pt\" is in the\n          \"templates\" directory relative to the directory of the\n          current :term:`package` of the Configurator), a path can be\n          absolute, starting with a slash on UNIX or a drive letter\n          prefix on Windows.  The path can alternately be a\n          :term:`asset specification` in the form\n          ``some.dotted.package_name:relative/path``, making it\n          possible to address template assets which live in a\n          separate package.\n\n          The ``renderer`` attribute is optional.  If it is not\n          defined, the \"null\" renderer is assumed (no rendering is\n          performed and the value is passed back to the upstream\n          :app:`Pyramid` machinery unmodified).\n\n        http_cache\n\n          .. versionadded:: 1.1\n\n          When you supply an ``http_cache`` value to a view configuration,\n          the ``Expires`` and ``Cache-Control`` headers of a response\n          generated by the associated view callable are modified.  The value\n          for ``http_cache`` may be one of the following:\n\n          - A nonzero integer.  If it's a nonzero integer, it's treated as a\n            number of seconds.  This number of seconds will be used to\n            compute the ``Expires`` header and the ``Cache-Control:\n            max-age`` parameter of responses to requests which call this view.\n            For example: ``http_cache=3600`` instructs the requesting browser\n            to 'cache this response for an hour, please'.\n\n          - A ``datetime.timedelta`` instance.  If it's a\n            ``datetime.timedelta`` instance, it will be converted into a\n            number of seconds, and that number of seconds will be used to\n            compute the ``Expires`` header and the ``Cache-Control:\n            max-age`` parameter of responses to requests which call this view.\n            For example: ``http_cache=datetime.timedelta(days=1)`` instructs\n            the requesting browser to 'cache this response for a day, please'.\n\n          - Zero (``0``).  If the value is zero, the ``Cache-Control`` and\n            ``Expires`` headers present in all responses from this view will\n            be composed such that client browser cache (and any intermediate\n            caches) are instructed to never cache the response.\n\n          - A two-tuple.  If it's a two tuple (e.g. ``http_cache=(1,\n            {'public':True})``), the first value in the tuple may be a\n            nonzero integer or a ``datetime.timedelta`` instance; in either\n            case this value will be used as the number of seconds to cache\n            the response.  The second value in the tuple must be a\n            dictionary.  The values present in the dictionary will be used as\n            input to the ``Cache-Control`` response header.  For example:\n            ``http_cache=(3600, {'public':True})`` means 'cache for an hour,\n            and add ``public`` to the Cache-Control header of the response'.\n            All keys and values supported by the\n            ``webob.cachecontrol.CacheControl`` interface may be added to the\n            dictionary.  Supplying ``{'public':True}`` is equivalent to\n            calling ``response.cache_control.public = True``.\n\n          Providing a non-tuple value as ``http_cache`` is equivalent to\n          calling ``response.cache_expires(value)`` within your view's body.\n\n          Providing a two-tuple value as ``http_cache`` is equivalent to\n          calling ``response.cache_expires(value[0], **value[1])`` within your\n          view's body.\n\n          If you wish to avoid influencing, the ``Expires`` header, and\n          instead wish to only influence ``Cache-Control`` headers, pass a\n          tuple as ``http_cache`` with the first element of ``None``, e.g.:\n          ``(None, {'public':True})``.\n\n          If you wish to prevent a view that uses ``http_cache`` in its\n          configuration from having its caching response headers changed by\n          this machinery, set ``response.cache_control.prevent_auto = True``\n          before returning the response from the view.  This effectively\n          disables any HTTP caching done by ``http_cache`` for that response.\n\n        wrapper\n\n          The :term:`view name` of a different :term:`view\n          configuration` which will receive the response body of this\n          view as the ``request.wrapped_body`` attribute of its own\n          :term:`request`, and the :term:`response` returned by this\n          view as the ``request.wrapped_response`` attribute of its\n          own request.  Using a wrapper makes it possible to \"chain\"\n          views together to form a composite response.  The response\n          of the outermost wrapper view will be returned to the user.\n          The wrapper view will be found as any view is found: see\n          :ref:`view_lookup`.  The \"best\" wrapper view will be found\n          based on the lookup ordering: \"under the hood\" this wrapper\n          view is looked up via\n          ``pyramid.view.render_view_to_response(context, request,\n          'wrapper_viewname')``. The context and request of a wrapper\n          view is the same context and request of the inner view.  If\n          this attribute is unspecified, no view wrapping is done.\n\n        decorator\n\n          A :term:`dotted Python name` to function (or the function itself,\n          or an iterable of the aforementioned) which will be used to\n          decorate the registered :term:`view callable`.  The decorator\n          function(s) will be called with the view callable as a single\n          argument.  The view callable it is passed will accept\n          ``(context, request)``.  The decorator(s) must return a\n          replacement view callable which also accepts ``(context,\n          request)``.\n\n          If decorator is an iterable, the callables will be combined and\n          used in the order provided as a decorator.\n          For example::\n\n            @view_config(...,\n                decorator=(decorator2,\n                           decorator1))\n            def myview(request):\n                ....\n\n          Is similar to doing::\n\n            @view_config(...)\n            @decorator2\n            @decorator1\n            def myview(request):\n                ...\n\n          Except with the existing benefits of ``decorator=`` (having a common\n          decorator syntax for all view calling conventions and not having to\n          think about preserving function attributes such as ``__name__`` and\n          ``__module__`` within decorator logic).\n\n          .. versionchanged:: 1.4a4\n             Passing an iterable.\n\n        mapper\n\n          A Python object or :term:`dotted Python name` which refers to a\n          :term:`view mapper`, or ``None``.  By default it is ``None``, which\n          indicates that the view should use the default view mapper.  This\n          plug-point is useful for Pyramid extension developers, but it's not\n          very useful for 'civilians' who are just developing stock Pyramid\n          applications. Pay no attention to the man behind the curtain.\n\n        Predicate Arguments\n\n        name\n\n          The :term:`view name`.  Read :ref:`traversal_chapter` to\n          understand the concept of a view name.\n\n        context\n\n          An object or a :term:`dotted Python name` referring to an\n          interface or class object that the :term:`context` must be\n          an instance of, *or* the :term:`interface` that the\n          :term:`context` must provide in order for this view to be\n          found and called.  This predicate is true when the\n          :term:`context` is an instance of the represented class or\n          if the :term:`context` provides the represented interface;\n          it is otherwise false.  This argument may also be provided\n          to ``add_view`` as ``for_`` (an older, still-supported\n          spelling).\n\n        route_name\n\n          This value must match the ``name`` of a :term:`route\n          configuration` declaration (see :ref:`urldispatch_chapter`)\n          that must match before this view will be called.\n\n        request_type\n\n          This value should be an :term:`interface` that the\n          :term:`request` must provide in order for this view to be\n          found and called.  This value exists only for backwards\n          compatibility purposes.\n\n        request_method\n\n          This value can be one of the strings ``GET``, ``POST``, ``PUT``,\n          ``DELETE``, or ``HEAD`` representing an HTTP ``REQUEST_METHOD``, or\n          a tuple containing one or more of these strings.  A view\n          declaration with this argument ensures that the view will only be\n          called when the request's ``method`` attribute (aka the\n          ``REQUEST_METHOD`` of the WSGI environment) string matches a\n          supplied value.  Note that use of ``GET`` also implies that the\n          view will respond to ``HEAD`` as of Pyramid 1.4.\n\n          .. versionchanged:: 1.2\n             The ability to pass a tuple of items as ``request_method``.\n             Previous versions allowed only a string.\n\n        request_param\n\n          This value can be any string or any sequence of strings.  A view \n          declaration with this argument ensures that the view will only be \n          called when the :term:`request` has a key in the ``request.params``\n          dictionary (an HTTP ``GET`` or ``POST`` variable) that has a\n          name which matches the supplied value (if the value is a string)\n          or values (if the value is a tuple).  If any value\n          supplied has a ``=`` sign in it,\n          e.g. ``request_param=\"foo=123\"``, then the key (``foo``)\n          must both exist in the ``request.params`` dictionary, *and*\n          the value must match the right hand side of the expression\n          (``123``) for the view to \"match\" the current request.\n\n        match_param\n\n          .. versionadded:: 1.2\n\n          This value can be a string of the format \"key=value\" or a tuple\n          containing one or more of these strings.\n\n          A view declaration with this argument ensures that the view will\n          only be called when the :term:`request` has key/value pairs in its\n          :term:`matchdict` that equal those supplied in the predicate.\n          e.g. ``match_param=\"action=edit\" would require the ``action``\n          parameter in the :term:`matchdict` match the right hand side of\n          the expression (``edit``) for the view to \"match\" the current\n          request.\n\n          If the ``match_param`` is a tuple, every key/value pair must match\n          for the predicate to pass.\n\n        containment\n\n          This value should be a Python class or :term:`interface` (or a\n          :term:`dotted Python name`) that an object in the\n          :term:`lineage` of the context must provide in order for this view\n          to be found and called.  The nodes in your object graph must be\n          \"location-aware\" to use this feature.  See\n          :ref:`location_aware` for more information about\n          location-awareness.\n\n        xhr\n\n          This value should be either ``True`` or ``False``.  If this\n          value is specified and is ``True``, the :term:`request`\n          must possess an ``HTTP_X_REQUESTED_WITH`` (aka\n          ``X-Requested-With``) header that has the value\n          ``XMLHttpRequest`` for this view to be found and called.\n          This is useful for detecting AJAX requests issued from\n          jQuery, Prototype and other Javascript libraries.\n\n        accept\n\n          The value of this argument represents a match query for one\n          or more mimetypes in the ``Accept`` HTTP request header.  If\n          this value is specified, it must be in one of the following\n          forms: a mimetype match token in the form ``text/plain``, a\n          wildcard mimetype match token in the form ``text/*`` or a\n          match-all wildcard mimetype match token in the form ``*/*``.\n          If any of the forms matches the ``Accept`` header of the\n          request, this predicate will be true.\n\n        header\n\n          This value represents an HTTP header name or a header\n          name/value pair.  If the value contains a ``:`` (colon), it\n          will be considered a name/value pair\n          (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``).  The\n          value portion should be a regular expression.  If the value\n          does not contain a colon, the entire value will be\n          considered to be the header name\n          (e.g. ``If-Modified-Since``).  If the value evaluates to a\n          header name only without a value, the header specified by\n          the name must be present in the request for this predicate\n          to be true.  If the value evaluates to a header name/value\n          pair, the header specified by the name must be present in\n          the request *and* the regular expression specified as the\n          value must match the header value.  Whether or not the value\n          represents a header name or a header name/value pair, the\n          case of the header name is not significant.\n\n        path_info\n\n          This value represents a regular expression pattern that will\n          be tested against the ``PATH_INFO`` WSGI environment\n          variable.  If the regex matches, this predicate will be\n          ``True``.\n\n        check_csrf\n\n          If specified, this value should be one of ``None``, ``True``,\n          ``False``, or a string representing the 'check name'.  If the value\n          is ``True`` or a string, CSRF checking will be performed.  If the\n          value is ``False`` or ``None``, CSRF checking will not be performed.\n\n          If the value provided is a string, that string will be used as the\n          'check name'.  If the value provided is ``True``, ``csrf_token`` will\n          be used as the check name.\n\n          If CSRF checking is performed, the checked value will be the value\n          of ``request.params[check_name]``.  This value will be compared\n          against the value of ``request.session.get_csrf_token()``, and the\n          check will pass if these two values are the same.  If the check\n          passes, the associated view will be permitted to execute.  If the\n          check fails, the associated view will not be permitted to execute.\n\n          Note that using this feature requires a :term:`session factory` to\n          have been configured.\n         \n          .. versionadded:: 1.4a2\n\n        physical_path\n\n          If specified, this value should be a string or a tuple representing\n          the :term:`physical path` of the context found via traversal for this\n          predicate to match as true.  For example: ``physical_path='/'`` or\n          ``physical_path='/a/b/c'`` or ``physical_path=('', 'a', 'b', 'c')``.\n          This is not a path prefix match or a regex, it's a whole-path match.\n          It's useful when you want to always potentially show a view when some\n          object is traversed to, but you can't be sure about what kind of\n          object it will be, so you can't use the ``context`` predicate.  The\n          individual path elements inbetween slash characters or in tuple\n          elements should be the Unicode representation of the name of the\n          resource and should not be encoded in any way.\n\n          .. versionadded:: 1.4a3\n\n        effective_principals\n\n          If specified, this value should be a :term:`principal` identifier or\n          a sequence of principal identifiers.  If the\n          :func:`pyramid.security.effective_principals` method indicates that\n          every principal named in the argument list is present in the current\n          request, this predicate will return True; otherwise it will return\n          False.  For example:\n          ``effective_principals=pyramid.security.Authenticated`` or\n          ``effective_principals=('fred', 'group:admins')``.\n\n          .. versionadded:: 1.4a4\n\n        custom_predicates\n\n          .. deprecated:: 1.5\n\n          This value should be a sequence of references to custom predicate\n          callables.  Use custom predicates when no set of predefined\n          predicates do what you need.  Custom predicates can be combined with\n          predefined predicates as necessary.  Each custom predicate callable\n          should accept two arguments: ``context`` and ``request`` and should\n          return either ``True`` or ``False`` after doing arbitrary evaluation\n          of the context and/or the request.  The ``predicates`` argument to\n          this method and the ability to register third-party view predicates\n          via :meth:`pyramid.config.Configurator.add_view_predicate` obsoletes\n          this argument, but it is kept around for backwards compatibility.\n\n        predicates\n\n          Pass a key/value pair here to use a third-party predicate\n          registered via\n          :meth:`pyramid.config.Configurator.add_view_predicate`.  More than\n          one key/value pair can be used at the same time.  See\n          :ref:`view_and_route_predicates` for more information about\n          third-party predicates.\n\n          .. versionadded: 1.4a1\n\n        \"\"\"\n        if custom_predicates:\n            warnings.warn(\n                ('The \"custom_predicates\" argument to Configurator.add_view '\n                 'is deprecated as of Pyramid 1.5.  Use '\n                 '\"config.add_view_predicate\" and use the registered '\n                 'view predicate as a predicate argument to add_view instead. '\n                 'See \"Adding A Third Party View, Route, or Subscriber '\n                 'Predicate\" in the \"Hooks\" chapter of the documentation '\n                 'for more information.'),\n                DeprecationWarning,\n                stacklevel=4\n                )\n        \n        view = self.maybe_dotted(view)\n        context = self.maybe_dotted(context)\n        for_ = self.maybe_dotted(for_)\n        containment = self.maybe_dotted(containment)\n        mapper = self.maybe_dotted(mapper)\n\n        def combine(*decorators):\n            def decorated(view_callable):\n                # reversed() is allows a more natural ordering in the api\n                for decorator in reversed(decorators):\n                    view_callable = decorator(view_callable)\n                return view_callable\n            return decorated\n\n        if is_nonstr_iter(decorator):\n            decorator = combine(*map(self.maybe_dotted, decorator))\n        else:\n            decorator = self.maybe_dotted(decorator)\n\n        if not view:\n            if renderer:\n                def view(context, request):\n                    return {}\n            else:\n                raise ConfigurationError('\"view\" was not specified and '\n                                         'no \"renderer\" specified')\n\n        if request_type is not None:\n            request_type = self.maybe_dotted(request_type)\n            if not IInterface.providedBy(request_type):\n                raise ConfigurationError(\n                    'request_type must be an interface, not %s' % request_type)\n\n        if context is None:\n            context = for_\n\n        r_context = context\n        if r_context is None:\n            r_context = Interface\n        if not IInterface.providedBy(r_context):\n            r_context = implementedBy(r_context)\n\n        if isinstance(renderer, string_types):\n            renderer = renderers.RendererHelper(\n                name=renderer, package=self.package,\n                registry = self.registry)\n\n        if accept is not None:\n            accept = accept.lower()\n\n        introspectables = []\n        pvals = predicates.copy()\n        pvals.update(\n            dict(\n                xhr=xhr,\n                request_method=request_method,\n                path_info=path_info,\n                request_param=request_param,\n                header=header,\n                accept=accept,\n                containment=containment,\n                request_type=request_type,\n                match_param=match_param,\n                check_csrf=check_csrf,\n                custom=predvalseq(custom_predicates),\n                )\n            )\n\n        def discrim_func():\n            # We need to defer the discriminator until we know what the phash\n            # is.  It can't be computed any sooner because thirdparty\n            # predicates may not yet exist when add_view is called.\n            order, preds, phash = predlist.make(self, **pvals)\n            view_intr.update({'phash':phash, 'order':order, 'predicates':preds})\n            return ('view', context, name, route_name, phash)\n\n        discriminator = Deferred(discrim_func)\n\n        if inspect.isclass(view) and attr:\n            view_desc = 'method %r of %s' % (\n                attr, self.object_description(view))\n        else:\n            view_desc = self.object_description(view)\n\n        tmpl_intr = None\n            \n        view_intr = self.introspectable('views',\n                                        discriminator,\n                                        view_desc,\n                                        'view')\n        view_intr.update(\n            dict(name=name,\n                 context=context,\n                 containment=containment,\n                 request_param=request_param,\n                 request_methods=request_method,\n                 route_name=route_name,\n                 attr=attr,\n                 xhr=xhr,\n                 accept=accept,\n                 header=header,\n                 path_info=path_info,\n                 match_param=match_param,\n                 check_csrf=check_csrf,\n                 callable=view,\n                 mapper=mapper,\n                 decorator=decorator,\n                 )\n            )\n        view_intr.update(**predicates)\n        introspectables.append(view_intr)\n        predlist = self.get_predlist('view')\n\n        def register(permission=permission, renderer=renderer):\n            # the discrim_func above is guaranteed to have been called already\n            order = view_intr['order']\n            preds = view_intr['predicates']\n            phash = view_intr['phash']\n            request_iface = IRequest\n            if route_name is not None:\n                request_iface = self.registry.queryUtility(IRouteRequest,\n                                                           name=route_name)\n                if request_iface is None:\n                    # route configuration should have already happened in\n                    # phase 2\n                    raise ConfigurationError(\n                        'No route named %s found for view registration' %\n                        route_name)\n\n            if renderer is None:\n                # use default renderer if one exists (reg'd in phase 1)\n                if self.registry.queryUtility(IRendererFactory) is not None:\n                    renderer = renderers.RendererHelper(\n                        name=None,\n                        package=self.package,\n                        registry=self.registry\n                        )\n\n            if permission is None:\n                # intent: will be None if no default permission is registered\n                # (reg'd in phase 1)\n                permission = self.registry.queryUtility(IDefaultPermission)\n\n            # added by discrim_func above during conflict resolving\n            preds = view_intr['predicates']\n            order = view_intr['order']\n            phash = view_intr['phash']\n\n            # __no_permission_required__ handled by _secure_view\n            deriver = ViewDeriver(\n                registry=self.registry,\n                permission=permission,\n                predicates=preds,\n                attr=attr,\n                renderer=renderer,\n                wrapper_viewname=wrapper,\n                viewname=name,\n                accept=accept,\n                order=order,\n                phash=phash,\n                package=self.package,\n                mapper=mapper,\n                decorator=decorator,\n                http_cache=http_cache,\n                )\n            derived_view = deriver(view)\n            derived_view.__discriminator__ = lambda *arg: discriminator\n            # __discriminator__ is used by superdynamic systems\n            # that require it for introspection after manual view lookup;\n            # see also MultiView.__discriminator__\n            view_intr['derived_callable'] = derived_view\n\n            registered = self.registry.adapters.registered\n\n            # A multiviews is a set of views which are registered for\n            # exactly the same context type/request type/name triad.  Each\n            # consituent view in a multiview differs only by the\n            # predicates which it possesses.\n\n            # To find a previously registered view for a context\n            # type/request type/name triad, we need to use the\n            # ``registered`` method of the adapter registry rather than\n            # ``lookup``.  ``registered`` ignores interface inheritance\n            # for the required and provided arguments, returning only a\n            # view registered previously with the *exact* triad we pass\n            # in.\n\n            # We need to do this three times, because we use three\n            # different interfaces as the ``provided`` interface while\n            # doing registrations, and ``registered`` performs exact\n            # matches on all the arguments it receives.\n\n            old_view = None\n\n            for view_type in (IView, ISecuredView, IMultiView):\n                old_view = registered((IViewClassifier, request_iface,\n                                       r_context), view_type, name)\n                if old_view is not None:\n                    break\n\n            isexc = isexception(context)\n\n            def regclosure():\n                if hasattr(derived_view, '__call_permissive__'):\n                    view_iface = ISecuredView\n                else:\n                    view_iface = IView\n                self.registry.registerAdapter(\n                    derived_view,\n                    (IViewClassifier, request_iface, context), view_iface, name\n                    )\n                if isexc:\n                    self.registry.registerAdapter(\n                        derived_view,\n                        (IExceptionViewClassifier, request_iface, context),\n                        view_iface, name)\n\n            is_multiview = IMultiView.providedBy(old_view)\n            old_phash = getattr(old_view, '__phash__', DEFAULT_PHASH)\n\n            if old_view is None:\n                # - No component was yet registered for any of our I*View\n                #   interfaces exactly; this is the first view for this\n                #   triad.\n                regclosure()\n\n            elif (not is_multiview) and (old_phash == phash):\n                # - A single view component was previously registered with\n                #   the same predicate hash as this view; this registration\n                #   is therefore an override.\n                regclosure()\n\n            else:\n                # - A view or multiview was already registered for this\n                #   triad, and the new view is not an override.\n\n                # XXX we could try to be more efficient here and register\n                # a non-secured view for a multiview if none of the\n                # multiview's consituent views have a permission\n                # associated with them, but this code is getting pretty\n                # rough already\n                if is_multiview:\n                    multiview = old_view\n                else:\n                    multiview = MultiView(name)\n                    old_accept = getattr(old_view, '__accept__', None)\n                    old_order = getattr(old_view, '__order__', MAX_ORDER)\n                    multiview.add(old_view, old_order, old_accept, old_phash)\n                multiview.add(derived_view, order, accept, phash)\n                for view_type in (IView, ISecuredView):\n                    # unregister any existing views\n                    self.registry.adapters.unregister(\n                        (IViewClassifier, request_iface, r_context),\n                        view_type, name=name)\n                    if isexc:\n                        self.registry.adapters.unregister(\n                            (IExceptionViewClassifier, request_iface,\n                             r_context), view_type, name=name)\n                self.registry.registerAdapter(\n                    multiview,\n                    (IViewClassifier, request_iface, context),\n                    IMultiView, name=name)\n                if isexc:\n                    self.registry.registerAdapter(\n                        multiview,\n                        (IExceptionViewClassifier, request_iface, context),\n                        IMultiView, name=name)\n            renderer_type = getattr(renderer, 'type', None) # gard against None\n            intrspc = self.introspector\n            if (\n                renderer_type is not None and\n                tmpl_intr is not None and\n                intrspc is not None and\n                intrspc.get('renderer factories', renderer_type) is not None\n                ):\n                # allow failure of registered template factories to be deferred\n                # until view execution, like other bad renderer factories; if\n                # we tried to relate this to an existing renderer factory\n                # without checking if it the factory actually existed, we'd end\n                # up with a KeyError at startup time, which is inconsistent\n                # with how other bad renderer registrations behave (they throw\n                # a ValueError at view execution time)\n                tmpl_intr.relate('renderer factories', renderer.type)\n\n        if mapper:\n            mapper_intr = self.introspectable(\n                'view mappers',\n                discriminator,\n                'view mapper for %s' % view_desc,\n                'view mapper'\n                )\n            mapper_intr['mapper'] = mapper\n            mapper_intr.relate('views', discriminator)\n            introspectables.append(mapper_intr)\n        if route_name:\n            view_intr.relate('routes', route_name) # see add_route\n        if renderer is not None and renderer.name and '.' in renderer.name:\n            # the renderer is a template\n            tmpl_intr = self.introspectable(\n                'templates',\n                discriminator,\n                renderer.name,\n                'template'\n                )\n            tmpl_intr.relate('views', discriminator)\n            tmpl_intr['name'] = renderer.name\n            tmpl_intr['type'] = renderer.type\n            tmpl_intr['renderer'] = renderer\n            introspectables.append(tmpl_intr)\n        if permission is not None:\n            # if a permission exists, register a permission introspectable\n            perm_intr = self.introspectable(\n                'permissions',\n                permission,\n                permission,\n                'permission'\n                )\n            perm_intr['value'] = permission\n            perm_intr.relate('views', discriminator)\n            introspectables.append(perm_intr)\n        self.action(discriminator, register, introspectables=introspectables)\n\n    @action_method\n    def add_view_predicate(self, name, factory, weighs_more_than=None,\n                           weighs_less_than=None):\n        \"\"\"\n        .. versionadded:: 1.4\n\n        Adds a view predicate factory.  The associated view predicate can\n        later be named as a keyword argument to\n        :meth:`pyramid.config.Configurator.add_view` in the\n        ``predicates`` anonyous keyword argument dictionary.\n\n        ``name`` should be the name of the predicate.  It must be a valid\n        Python identifier (it will be used as a keyword argument to\n        ``add_view`` by others).\n\n        ``factory`` should be a :term:`predicate factory` or :term:`dotted\n        Python name` which refers to a predicate factory.\n\n        See :ref:`view_and_route_predicates` for more information.\n        \"\"\"\n        self._add_predicate(\n            'view',\n            name,\n            factory,\n            weighs_more_than=weighs_more_than,\n            weighs_less_than=weighs_less_than\n            )\n\n    def add_default_view_predicates(self):\n        p = pyramid.config.predicates\n        for (name, factory) in (\n            ('xhr', p.XHRPredicate),\n            ('request_method', p.RequestMethodPredicate),\n            ('path_info', p.PathInfoPredicate),\n            ('request_param', p.RequestParamPredicate),\n            ('header', p.HeaderPredicate),\n            ('accept', p.AcceptPredicate),\n            ('containment', p.ContainmentPredicate),\n            ('request_type', p.RequestTypePredicate),\n            ('match_param', p.MatchParamPredicate),\n            ('check_csrf', p.CheckCSRFTokenPredicate),\n            ('physical_path', p.PhysicalPathPredicate),\n            ('effective_principals', p.EffectivePrincipalsPredicate),\n            ('custom', p.CustomPredicate),\n            ):\n            self.add_view_predicate(name, factory)\n\n    def derive_view(self, view, attr=None, renderer=None):\n        \"\"\"\n        Create a :term:`view callable` using the function, instance,\n        or class (or :term:`dotted Python name` referring to the same)\n        provided as ``view`` object.\n\n        .. warning::\n\n           This method is typically only used by :app:`Pyramid` framework\n           extension authors, not by :app:`Pyramid` application developers.\n\n        This is API is useful to framework extenders who create\n        pluggable systems which need to register 'proxy' view\n        callables for functions, instances, or classes which meet the\n        requirements of being a :app:`Pyramid` view callable.  For\n        example, a ``some_other_framework`` function in another\n        framework may want to allow a user to supply a view callable,\n        but he may want to wrap the view callable in his own before\n        registering the wrapper as a :app:`Pyramid` view callable.\n        Because a :app:`Pyramid` view callable can be any of a\n        number of valid objects, the framework extender will not know\n        how to call the user-supplied object.  Running it through\n        ``derive_view`` normalizes it to a callable which accepts two\n        arguments: ``context`` and ``request``.\n\n        For example:\n\n        .. code-block:: python\n\n           def some_other_framework(user_supplied_view):\n               config = Configurator(reg)\n               proxy_view = config.derive_view(user_supplied_view)\n               def my_wrapper(context, request):\n                   do_something_that_mutates(request)\n                   return proxy_view(context, request)\n               config.add_view(my_wrapper)\n\n        The ``view`` object provided should be one of the following:\n\n        - A function or another non-class callable object that accepts\n          a :term:`request` as a single positional argument and which\n          returns a :term:`response` object.\n\n        - A function or other non-class callable object that accepts\n          two positional arguments, ``context, request`` and which\n          returns a :term:`response` object.\n\n        - A class which accepts a single positional argument in its\n          constructor named ``request``, and which has a ``__call__``\n          method that accepts no arguments that returns a\n          :term:`response` object.\n\n        - A class which accepts two positional arguments named\n          ``context, request``, and which has a ``__call__`` method\n          that accepts no arguments that returns a :term:`response`\n          object.\n\n        - A :term:`dotted Python name` which refers to any of the\n          kinds of objects above.\n\n        This API returns a callable which accepts the arguments\n        ``context, request`` and which returns the result of calling\n        the provided ``view`` object.\n\n        The ``attr`` keyword argument is most useful when the view\n        object is a class.  It names the method that should be used as\n        the callable.  If ``attr`` is not provided, the attribute\n        effectively defaults to ``__call__``.  See\n        :ref:`class_as_view` for more information.\n\n        The ``renderer`` keyword argument should be a renderer\n        name. If supplied, it will cause the returned callable to use\n        a :term:`renderer` to convert the user-supplied view result to\n        a :term:`response` object.  If a ``renderer`` argument is not\n        supplied, the user-supplied view must itself return a\n        :term:`response` object.  \"\"\"\n        return self._derive_view(view, attr=attr, renderer=renderer)\n\n    # b/w compat\n    def _derive_view(self, view, permission=None, predicates=(),\n                     attr=None, renderer=None, wrapper_viewname=None,\n                     viewname=None, accept=None, order=MAX_ORDER,\n                     phash=DEFAULT_PHASH, decorator=None,\n                     mapper=None, http_cache=None):\n        view = self.maybe_dotted(view)\n        mapper = self.maybe_dotted(mapper)\n        if isinstance(renderer, string_types):\n            renderer = renderers.RendererHelper(\n                name=renderer, package=self.package,\n                registry = self.registry)\n        if renderer is None:\n            # use default renderer if one exists\n            if self.registry.queryUtility(IRendererFactory) is not None:\n                renderer = renderers.RendererHelper(\n                    name=None,\n                    package=self.package,\n                    registry=self.registry)\n\n        deriver = ViewDeriver(registry=self.registry,\n                              permission=permission,\n                              predicates=predicates,\n                              attr=attr,\n                              renderer=renderer,\n                              wrapper_viewname=wrapper_viewname,\n                              viewname=viewname,\n                              accept=accept,\n                              order=order,\n                              phash=phash,\n                              package=self.package,\n                              mapper=mapper,\n                              decorator=decorator,\n                              http_cache=http_cache)\n\n        return deriver(view)\n\n    @viewdefaults\n    @action_method\n    def add_forbidden_view(\n        self,\n        view=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        route_name=None,\n        request_type=None,\n        request_method=None, \n        request_param=None,\n        containment=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        decorator=None,\n        mapper=None,\n        match_param=None,\n        **predicates\n        ):\n        \"\"\" Add a forbidden view to the current configuration state.  The\n        view will be called when Pyramid or application code raises a\n        :exc:`pyramid.httpexceptions.HTTPForbidden` exception and the set of\n        circumstances implied by the predicates provided are matched.  The\n        simplest example is:\n\n          .. code-block:: python\n\n            def forbidden(request):\n                return Response('Forbidden', status='403 Forbidden')\n\n            config.add_forbidden_view(forbidden)\n\n        All arguments have the same meaning as\n        :meth:`pyramid.config.Configurator.add_view` and each predicate\n        argument restricts the set of circumstances under which this notfound\n        view will be invoked.  Unlike\n        :meth:`pyramid.config.Configurator.add_view`, this method will raise\n        an exception if passed ``name``, ``permission``, ``context``,\n        ``for_``, or ``http_cache`` keyword arguments.  These argument values\n        make no sense in the context of a forbidden view.\n\n        .. versionadded:: 1.3\n        \"\"\"\n        for arg in ('name', 'permission', 'context', 'for_', 'http_cache'):\n            if arg in predicates:\n                raise ConfigurationError(\n                    '%s may not be used as an argument to add_forbidden_view'\n                    % arg\n                    )\n        \n        settings = dict(\n            view=view,\n            context=HTTPForbidden,\n            wrapper=wrapper,\n            request_type=request_type,\n            request_method=request_method,\n            request_param=request_param,\n            containment=containment,\n            xhr=xhr,\n            accept=accept,\n            header=header, \n            path_info=path_info,\n            custom_predicates=custom_predicates,\n            decorator=decorator,\n            mapper=mapper,\n            match_param=match_param,\n            route_name=route_name,\n            permission=NO_PERMISSION_REQUIRED,\n            attr=attr,\n            renderer=renderer,\n            )\n        settings.update(predicates)\n        return self.add_view(**settings)\n\n    set_forbidden_view = add_forbidden_view # deprecated sorta-bw-compat alias\n    \n    @viewdefaults\n    @action_method\n    def add_notfound_view(\n        self,\n        view=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        route_name=None,\n        request_type=None,\n        request_method=None, \n        request_param=None,\n        containment=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        decorator=None,\n        mapper=None,\n        match_param=None,\n        append_slash=False,\n        **predicates\n        ):\n        \"\"\" Add a default Not Found View to the current configuration state.\n        The view will be called when Pyramid or application code raises an\n        :exc:`pyramid.httpexceptions.HTTPNotFound` exception (e.g. when a\n        view cannot be found for the request).  The simplest example is:\n\n          .. code-block:: python\n\n            def notfound(request):\n                return Response('Not Found', status='404 Not Found')\n\n            config.add_notfound_view(notfound)\n\n        All arguments except ``append_slash`` have the same meaning as\n        :meth:`pyramid.config.Configurator.add_view` and each predicate\n        argument restricts the set of circumstances under which this notfound\n        view will be invoked.  Unlike\n        :meth:`pyramid.config.Configurator.add_view`, this method will raise\n        an exception if passed ``name``, ``permission``, ``context``,\n        ``for_``, or ``http_cache`` keyword arguments.  These argument values\n        make no sense in the context of a Not Found View.\n\n        If ``append_slash`` is ``True``, when this Not Found View is invoked,\n        and the current path info does not end in a slash, the notfound logic\n        will attempt to find a :term:`route` that matches the request's path\n        info suffixed with a slash.  If such a route exists, Pyramid will\n        issue a redirect to the URL implied by the route; if it does not,\n        Pyramid will return the result of the view callable provided as\n        ``view``, as normal.\n\n        .. versionadded:: 1.3\n        \"\"\"\n        for arg in ('name', 'permission', 'context', 'for_', 'http_cache'):\n            if arg in predicates:\n                raise ConfigurationError(\n                    '%s may not be used as an argument to add_notfound_view'\n                    % arg\n                    )\n                    \n        settings = dict(\n            view=view,\n            context=HTTPNotFound,\n            wrapper=wrapper,\n            request_type=request_type,\n            request_method=request_method,\n            request_param=request_param,\n            containment=containment,\n            xhr=xhr,\n            accept=accept,\n            header=header, \n            path_info=path_info,\n            custom_predicates=custom_predicates,\n            decorator=decorator,\n            mapper=mapper,\n            match_param=match_param,\n            route_name=route_name,\n            permission=NO_PERMISSION_REQUIRED,\n            )\n        settings.update(predicates)\n        if append_slash:\n            view = self._derive_view(view, attr=attr, renderer=renderer)\n            view = AppendSlashNotFoundViewFactory(view)\n            settings['view'] = view\n        else:\n            settings['attr'] = attr\n            settings['renderer'] = renderer\n        return self.add_view(**settings)\n\n    set_notfound_view = add_notfound_view # deprecated sorta-bw-compat alias\n\n    @action_method\n    def set_view_mapper(self, mapper):\n        \"\"\"\n        Setting a :term:`view mapper` makes it possible to make use of\n        :term:`view callable` objects which implement different call\n        signatures than the ones supported by :app:`Pyramid` as described in\n        its narrative documentation.\n\n        The ``mapper`` should argument be an object implementing\n        :class:`pyramid.interfaces.IViewMapperFactory` or a :term:`dotted\n        Python name` to such an object.  The provided ``mapper`` will become\n        the default view mapper to be used by all subsequent :term:`view\n        configuration` registrations.\n\n        See also :ref:`using_a_view_mapper`.\n\n        .. note::\n\n           Using the ``default_view_mapper`` argument to the\n           :class:`pyramid.config.Configurator` constructor\n           can be used to achieve the same purpose.\n        \"\"\"\n        mapper = self.maybe_dotted(mapper)\n        def register():\n            self.registry.registerUtility(mapper, IViewMapperFactory)\n        # IViewMapperFactory is looked up as the result of view config\n        # in phase 3\n        intr = self.introspectable('view mappers',\n                                   IViewMapperFactory,\n                                   self.object_description(mapper),\n                                   'default view mapper')\n        intr['mapper'] = mapper\n        self.action(IViewMapperFactory, register, order=PHASE1_CONFIG,\n                    introspectables=(intr,))\n\n    @action_method\n    def add_static_view(self, name, path, **kw):\n        \"\"\" Add a view used to render static assets such as images\n        and CSS files.\n\n        The ``name`` argument is a string representing an\n        application-relative local URL prefix.  It may alternately be a full\n        URL.\n\n        The ``path`` argument is the path on disk where the static files\n        reside.  This can be an absolute path, a package-relative path, or a\n        :term:`asset specification`.\n\n        The ``cache_max_age`` keyword argument is input to set the\n        ``Expires`` and ``Cache-Control`` headers for static assets served.\n        Note that this argument has no effect when the ``name`` is a *url\n        prefix*.  By default, this argument is ``None``, meaning that no\n        particular Expires or Cache-Control headers are set in the response.\n\n        The ``permission`` keyword argument is used to specify the\n        :term:`permission` required by a user to execute the static view.  By\n        default, it is the string\n        :data:`pyramid.security.NO_PERMISSION_REQUIRED`, a special sentinel\n        which indicates that, even if a :term:`default permission` exists for\n        the current application, the static view should be renderered to\n        completely anonymous users.  This default value is permissive\n        because, in most web apps, static assets seldom need protection from\n        viewing.  If ``permission`` is specified, the security checking will\n        be performed against the default root factory ACL.\n\n        Any other keyword arguments sent to ``add_static_view`` are passed on\n        to :meth:`pyramid.config.Configurator.add_route` (e.g. ``factory``,\n        perhaps to define a custom factory with a custom ACL for this static\n        view).\n\n        *Usage*\n\n        The ``add_static_view`` function is typically used in conjunction\n        with the :meth:`pyramid.request.Request.static_url` method.\n        ``add_static_view`` adds a view which renders a static asset when\n        some URL is visited; :meth:`pyramid.request.Request.static_url`\n        generates a URL to that asset.\n\n        The ``name`` argument to ``add_static_view`` is usually a simple URL\n        prefix (e.g. ``'images'``).  When this is the case, the\n        :meth:`pyramid.request.Request.static_url` API will generate a URL\n        which points to a Pyramid view, which will serve up a set of assets\n        that live in the package itself. For example:\n\n        .. code-block:: python\n\n           add_static_view('images', 'mypackage:images/')\n\n        Code that registers such a view can generate URLs to the view via\n        :meth:`pyramid.request.Request.static_url`:\n\n        .. code-block:: python\n\n           request.static_url('mypackage:images/logo.png')\n\n        When ``add_static_view`` is called with a ``name`` argument that\n        represents a URL prefix, as it is above, subsequent calls to\n        :meth:`pyramid.request.Request.static_url` with paths that start with\n        the ``path`` argument passed to ``add_static_view`` will generate a\n        URL something like ``http://<Pyramid app URL>/images/logo.png``,\n        which will cause the ``logo.png`` file in the ``images`` subdirectory\n        of the ``mypackage`` package to be served.\n\n        ``add_static_view`` can alternately be used with a ``name`` argument\n        which is a *URL*, causing static assets to be served from an external\n        webserver.  This happens when the ``name`` argument is a fully\n        qualified URL (e.g. starts with ``http://`` or similar).  In this\n        mode, the ``name`` is used as the prefix of the full URL when\n        generating a URL using :meth:`pyramid.request.Request.static_url`.\n        Furthermore, if a protocol-relative URL (e.g. ``//example.com/images``)\n        is used as the ``name`` argument, the generated URL will use the\n        protocol of the request (http or https, respectively).\n\n        For example, if ``add_static_view`` is called like so:\n\n        .. code-block:: python\n\n           add_static_view('http://example.com/images', 'mypackage:images/')\n\n        Subsequently, the URLs generated by\n        :meth:`pyramid.request.Request.static_url` for that static view will\n        be prefixed with ``http://example.com/images`` (the external webserver\n        listening on ``example.com`` must be itself configured to respond\n        properly to such a request.):\n\n        .. code-block:: python\n\n           static_url('mypackage:images/logo.png', request)\n\n        See :ref:`static_assets_section` for more information.\n        \"\"\"\n        spec = self._make_spec(path)\n        info = self.registry.queryUtility(IStaticURLInfo)\n        if info is None:\n            info = StaticURLInfo()\n            self.registry.registerUtility(info, IStaticURLInfo)\n        info.add(self, name, spec, **kw)\n\ndef isexception(o):\n    if IInterface.providedBy(o):\n        if IException.isEqualOrExtendedBy(o):\n            return True\n    return (\n        isinstance(o, Exception) or\n        (inspect.isclass(o) and (issubclass(o, Exception)))\n        )\n\n\n@implementer(IStaticURLInfo)\nclass StaticURLInfo(object):\n\n    def _get_registrations(self, registry):\n        try:\n            reg = registry._static_url_registrations\n        except AttributeError:\n            reg = registry._static_url_registrations = []\n        return reg\n\n    def generate(self, path, request, **kw):\n        try:\n            registry = request.registry\n        except AttributeError: # bw compat (for tests)\n            registry = get_current_registry()\n        for (url, spec, route_name) in self._get_registrations(registry):\n            if path.startswith(spec):\n                subpath = path[len(spec):]\n                if WIN: # pragma: no cover\n                    subpath = subpath.replace('\\\\', '/') # windows\n                if url is None:\n                    kw['subpath'] = subpath\n                    return request.route_url(route_name, **kw)\n                else:\n                    parsed = url_parse(url)\n                    if not parsed.scheme:\n                        # parsed.scheme is readonly, so we have to parse again\n                        # to change the scheme, sigh.\n                        url = urlparse.urlunparse(url_parse(\n                            url, scheme=request.environ['wsgi.url_scheme']))\n                    subpath = url_quote(subpath)\n                    return urljoin(url, subpath)\n\n        raise ValueError('No static URL definition matching %s' % path)\n\n    def add(self, config, name, spec, **extra):\n        # This feature only allows for the serving of a directory and\n        # the files contained within, not of a single asset;\n        # appending a slash here if the spec doesn't have one is\n        # required for proper prefix matching done in ``generate``\n        # (``subpath = path[len(spec):]``).\n        if os.path.isabs(spec): # FBO windows\n            sep = os.sep\n        else:\n            sep = '/'\n        if not spec.endswith(sep):\n            spec = spec + sep\n\n        # we also make sure the name ends with a slash, purely as a\n        # convenience: a name that is a url is required to end in a\n        # slash, so that ``urljoin(name, subpath))`` will work above\n        # when the name is a URL, and it doesn't hurt things for it to\n        # have a name that ends in a slash if it's used as a route\n        # name instead of a URL.\n        if not name.endswith('/'):\n            # make sure it ends with a slash\n            name = name + '/'\n\n        if url_parse(name).netloc:\n            # it's a URL\n            # url, spec, route_name\n            url = name\n            route_name = None\n        else:\n            # it's a view name\n            url = None\n            cache_max_age = extra.pop('cache_max_age', None)\n            # create a view\n            view = static_view(spec, cache_max_age=cache_max_age,\n                               use_subpath=True)\n\n            # Mutate extra to allow factory, etc to be passed through here.\n            # Treat permission specially because we'd like to default to\n            # permissiveness (see docs of config.add_static_view).\n            permission = extra.pop('permission', None)\n            if permission is None:\n                permission = NO_PERMISSION_REQUIRED\n\n            context = extra.pop('context', None)\n            if context is None:\n                context = extra.pop('for_', None)\n\n            renderer = extra.pop('renderer', None)\n\n            # register a route using the computed view, permission, and\n            # pattern, plus any extras passed to us via add_static_view\n            pattern = \"%s*subpath\" % name # name already ends with slash\n            if config.route_prefix:\n                route_name = '__%s/%s' % (config.route_prefix, name)\n            else:\n                route_name = '__%s' % name\n            config.add_route(route_name, pattern, **extra)\n            config.add_view(\n                route_name=route_name,\n                view=view,\n                permission=permission,\n                context=context,\n                renderer=renderer,\n                )\n\n        def register():\n            registrations = self._get_registrations(config.registry)\n\n            names = [ t[0] for t in  registrations ]\n\n            if name in names:\n                idx = names.index(name)\n                registrations.pop(idx)\n\n            # url, spec, route_name\n            registrations.append((url, spec, route_name))\n\n        intr = config.introspectable('static views',\n                                     name,\n                                     'static view for %r' % name,\n                                     'static view')\n        intr['name'] = name\n        intr['spec'] = spec\n\n        config.action(None, callable=register, introspectables=(intr,))\n\n\n",
            "header": {
                "file": {
                    "path": "pyramid/config/views.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "233bbac12",
                "new_commit_hash": "69f68e422",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/pyramid/config/views.py"
            },
            "plus_file": {
                "path": "b/pyramid/config/views.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 1550,
                            "length": 6
                        },
                        "new_range": {
                            "start": 1550,
                            "length": 7
                        },
                        "section": "class ViewsConfiguratorMixin(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        return deriver(view)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    @viewdefaults",
                                "type": "added"
                            },
                            {
                                "content": "    @action_method",
                                "type": "context"
                            },
                            {
                                "content": "    def add_forbidden_view(",
                                "type": "context"
                            },
                            {
                                "content": "        self,",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "pyramid/config/views.py",
                            "type": "class",
                            "name": "ViewsConfiguratorMixin",
                            "content": "class ViewsConfiguratorMixin(object):\n    @viewdefaults\n    @action_method\n    def add_view(\n        self,\n        view=None,\n        name=\"\",\n        for_=None,\n        permission=None,\n        request_type=None,\n        route_name=None,\n        request_method=None,\n        request_param=None,\n        containment=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        context=None,\n        decorator=None,\n        mapper=None,\n        http_cache=None,\n        match_param=None,\n        check_csrf=None,\n        **predicates):\n        \"\"\" Add a :term:`view configuration` to the current\n        configuration state.  Arguments to ``add_view`` are broken\n        down below into *predicate* arguments and *non-predicate*\n        arguments.  Predicate arguments narrow the circumstances in\n        which the view callable will be invoked when a request is\n        presented to :app:`Pyramid`; non-predicate arguments are\n        informational.\n\n        Non-Predicate Arguments\n\n        view\n\n          A :term:`view callable` or a :term:`dotted Python name`\n          which refers to a view callable.  This argument is required\n          unless a ``renderer`` argument also exists.  If a\n          ``renderer`` argument is passed, and a ``view`` argument is\n          not provided, the view callable defaults to a callable that\n          returns an empty dictionary (see\n          :ref:`views_which_use_a_renderer`).\n\n        permission\n\n          A :term:`permission` that the user must possess in order to invoke\n          the :term:`view callable`.  See :ref:`view_security_section` for\n          more information about view security and permissions.  This is\n          often a string like ``view`` or ``edit``.\n\n          If ``permission`` is omitted, a *default* permission may be used\n          for this view registration if one was named as the\n          :class:`pyramid.config.Configurator` constructor's\n          ``default_permission`` argument, or if\n          :meth:`pyramid.config.Configurator.set_default_permission` was used\n          prior to this view registration.  Pass the value\n          :data:`pyramid.security.NO_PERMISSION_REQUIRED` as the permission\n          argument to explicitly indicate that the view should always be\n          executable by entirely anonymous users, regardless of the default\n          permission, bypassing any :term:`authorization policy` that may be\n          in effect.\n\n        attr\n\n          This knob is most useful when the view definition is a class.\n\n          The view machinery defaults to using the ``__call__`` method\n          of the :term:`view callable` (or the function itself, if the\n          view callable is a function) to obtain a response.  The\n          ``attr`` value allows you to vary the method attribute used\n          to obtain the response.  For example, if your view was a\n          class, and the class has a method named ``index`` and you\n          wanted to use this method instead of the class' ``__call__``\n          method to return the response, you'd say ``attr=\"index\"`` in the\n          view configuration for the view.\n\n        renderer\n\n          This is either a single string term (e.g. ``json``) or a\n          string implying a path or :term:`asset specification`\n          (e.g. ``templates/views.pt``) naming a :term:`renderer`\n          implementation.  If the ``renderer`` value does not contain\n          a dot ``.``, the specified string will be used to look up a\n          renderer implementation, and that renderer implementation\n          will be used to construct a response from the view return\n          value.  If the ``renderer`` value contains a dot (``.``),\n          the specified term will be treated as a path, and the\n          filename extension of the last element in the path will be\n          used to look up the renderer implementation, which will be\n          passed the full path.  The renderer implementation will be\n          used to construct a :term:`response` from the view return\n          value.\n\n          Note that if the view itself returns a :term:`response` (see\n          :ref:`the_response`), the specified renderer implementation\n          is never called.\n\n          When the renderer is a path, although a path is usually just\n          a simple relative pathname (e.g. ``templates/foo.pt``,\n          implying that a template named \"foo.pt\" is in the\n          \"templates\" directory relative to the directory of the\n          current :term:`package` of the Configurator), a path can be\n          absolute, starting with a slash on UNIX or a drive letter\n          prefix on Windows.  The path can alternately be a\n          :term:`asset specification` in the form\n          ``some.dotted.package_name:relative/path``, making it\n          possible to address template assets which live in a\n          separate package.\n\n          The ``renderer`` attribute is optional.  If it is not\n          defined, the \"null\" renderer is assumed (no rendering is\n          performed and the value is passed back to the upstream\n          :app:`Pyramid` machinery unmodified).\n\n        http_cache\n\n          .. versionadded:: 1.1\n\n          When you supply an ``http_cache`` value to a view configuration,\n          the ``Expires`` and ``Cache-Control`` headers of a response\n          generated by the associated view callable are modified.  The value\n          for ``http_cache`` may be one of the following:\n\n          - A nonzero integer.  If it's a nonzero integer, it's treated as a\n            number of seconds.  This number of seconds will be used to\n            compute the ``Expires`` header and the ``Cache-Control:\n            max-age`` parameter of responses to requests which call this view.\n            For example: ``http_cache=3600`` instructs the requesting browser\n            to 'cache this response for an hour, please'.\n\n          - A ``datetime.timedelta`` instance.  If it's a\n            ``datetime.timedelta`` instance, it will be converted into a\n            number of seconds, and that number of seconds will be used to\n            compute the ``Expires`` header and the ``Cache-Control:\n            max-age`` parameter of responses to requests which call this view.\n            For example: ``http_cache=datetime.timedelta(days=1)`` instructs\n            the requesting browser to 'cache this response for a day, please'.\n\n          - Zero (``0``).  If the value is zero, the ``Cache-Control`` and\n            ``Expires`` headers present in all responses from this view will\n            be composed such that client browser cache (and any intermediate\n            caches) are instructed to never cache the response.\n\n          - A two-tuple.  If it's a two tuple (e.g. ``http_cache=(1,\n            {'public':True})``), the first value in the tuple may be a\n            nonzero integer or a ``datetime.timedelta`` instance; in either\n            case this value will be used as the number of seconds to cache\n            the response.  The second value in the tuple must be a\n            dictionary.  The values present in the dictionary will be used as\n            input to the ``Cache-Control`` response header.  For example:\n            ``http_cache=(3600, {'public':True})`` means 'cache for an hour,\n            and add ``public`` to the Cache-Control header of the response'.\n            All keys and values supported by the\n            ``webob.cachecontrol.CacheControl`` interface may be added to the\n            dictionary.  Supplying ``{'public':True}`` is equivalent to\n            calling ``response.cache_control.public = True``.\n\n          Providing a non-tuple value as ``http_cache`` is equivalent to\n          calling ``response.cache_expires(value)`` within your view's body.\n\n          Providing a two-tuple value as ``http_cache`` is equivalent to\n          calling ``response.cache_expires(value[0], **value[1])`` within your\n          view's body.\n\n          If you wish to avoid influencing, the ``Expires`` header, and\n          instead wish to only influence ``Cache-Control`` headers, pass a\n          tuple as ``http_cache`` with the first element of ``None``, e.g.:\n          ``(None, {'public':True})``.\n\n          If you wish to prevent a view that uses ``http_cache`` in its\n          configuration from having its caching response headers changed by\n          this machinery, set ``response.cache_control.prevent_auto = True``\n          before returning the response from the view.  This effectively\n          disables any HTTP caching done by ``http_cache`` for that response.\n\n        wrapper\n\n          The :term:`view name` of a different :term:`view\n          configuration` which will receive the response body of this\n          view as the ``request.wrapped_body`` attribute of its own\n          :term:`request`, and the :term:`response` returned by this\n          view as the ``request.wrapped_response`` attribute of its\n          own request.  Using a wrapper makes it possible to \"chain\"\n          views together to form a composite response.  The response\n          of the outermost wrapper view will be returned to the user.\n          The wrapper view will be found as any view is found: see\n          :ref:`view_lookup`.  The \"best\" wrapper view will be found\n          based on the lookup ordering: \"under the hood\" this wrapper\n          view is looked up via\n          ``pyramid.view.render_view_to_response(context, request,\n          'wrapper_viewname')``. The context and request of a wrapper\n          view is the same context and request of the inner view.  If\n          this attribute is unspecified, no view wrapping is done.\n\n        decorator\n\n          A :term:`dotted Python name` to function (or the function itself,\n          or an iterable of the aforementioned) which will be used to\n          decorate the registered :term:`view callable`.  The decorator\n          function(s) will be called with the view callable as a single\n          argument.  The view callable it is passed will accept\n          ``(context, request)``.  The decorator(s) must return a\n          replacement view callable which also accepts ``(context,\n          request)``.\n\n          If decorator is an iterable, the callables will be combined and\n          used in the order provided as a decorator.\n          For example::\n\n            @view_config(...,\n                decorator=(decorator2,\n                           decorator1))\n            def myview(request):\n                ....\n\n          Is similar to doing::\n\n            @view_config(...)\n            @decorator2\n            @decorator1\n            def myview(request):\n                ...\n\n          Except with the existing benefits of ``decorator=`` (having a common\n          decorator syntax for all view calling conventions and not having to\n          think about preserving function attributes such as ``__name__`` and\n          ``__module__`` within decorator logic).\n\n          .. versionchanged:: 1.4a4\n             Passing an iterable.\n\n        mapper\n\n          A Python object or :term:`dotted Python name` which refers to a\n          :term:`view mapper`, or ``None``.  By default it is ``None``, which\n          indicates that the view should use the default view mapper.  This\n          plug-point is useful for Pyramid extension developers, but it's not\n          very useful for 'civilians' who are just developing stock Pyramid\n          applications. Pay no attention to the man behind the curtain.\n\n        Predicate Arguments\n\n        name\n\n          The :term:`view name`.  Read :ref:`traversal_chapter` to\n          understand the concept of a view name.\n\n        context\n\n          An object or a :term:`dotted Python name` referring to an\n          interface or class object that the :term:`context` must be\n          an instance of, *or* the :term:`interface` that the\n          :term:`context` must provide in order for this view to be\n          found and called.  This predicate is true when the\n          :term:`context` is an instance of the represented class or\n          if the :term:`context` provides the represented interface;\n          it is otherwise false.  This argument may also be provided\n          to ``add_view`` as ``for_`` (an older, still-supported\n          spelling).\n\n        route_name\n\n          This value must match the ``name`` of a :term:`route\n          configuration` declaration (see :ref:`urldispatch_chapter`)\n          that must match before this view will be called.\n\n        request_type\n\n          This value should be an :term:`interface` that the\n          :term:`request` must provide in order for this view to be\n          found and called.  This value exists only for backwards\n          compatibility purposes.\n\n        request_method\n\n          This value can be one of the strings ``GET``, ``POST``, ``PUT``,\n          ``DELETE``, or ``HEAD`` representing an HTTP ``REQUEST_METHOD``, or\n          a tuple containing one or more of these strings.  A view\n          declaration with this argument ensures that the view will only be\n          called when the request's ``method`` attribute (aka the\n          ``REQUEST_METHOD`` of the WSGI environment) string matches a\n          supplied value.  Note that use of ``GET`` also implies that the\n          view will respond to ``HEAD`` as of Pyramid 1.4.\n\n          .. versionchanged:: 1.2\n             The ability to pass a tuple of items as ``request_method``.\n             Previous versions allowed only a string.\n\n        request_param\n\n          This value can be any string or any sequence of strings.  A view \n          declaration with this argument ensures that the view will only be \n          called when the :term:`request` has a key in the ``request.params``\n          dictionary (an HTTP ``GET`` or ``POST`` variable) that has a\n          name which matches the supplied value (if the value is a string)\n          or values (if the value is a tuple).  If any value\n          supplied has a ``=`` sign in it,\n          e.g. ``request_param=\"foo=123\"``, then the key (``foo``)\n          must both exist in the ``request.params`` dictionary, *and*\n          the value must match the right hand side of the expression\n          (``123``) for the view to \"match\" the current request.\n\n        match_param\n\n          .. versionadded:: 1.2\n\n          This value can be a string of the format \"key=value\" or a tuple\n          containing one or more of these strings.\n\n          A view declaration with this argument ensures that the view will\n          only be called when the :term:`request` has key/value pairs in its\n          :term:`matchdict` that equal those supplied in the predicate.\n          e.g. ``match_param=\"action=edit\" would require the ``action``\n          parameter in the :term:`matchdict` match the right hand side of\n          the expression (``edit``) for the view to \"match\" the current\n          request.\n\n          If the ``match_param`` is a tuple, every key/value pair must match\n          for the predicate to pass.\n\n        containment\n\n          This value should be a Python class or :term:`interface` (or a\n          :term:`dotted Python name`) that an object in the\n          :term:`lineage` of the context must provide in order for this view\n          to be found and called.  The nodes in your object graph must be\n          \"location-aware\" to use this feature.  See\n          :ref:`location_aware` for more information about\n          location-awareness.\n\n        xhr\n\n          This value should be either ``True`` or ``False``.  If this\n          value is specified and is ``True``, the :term:`request`\n          must possess an ``HTTP_X_REQUESTED_WITH`` (aka\n          ``X-Requested-With``) header that has the value\n          ``XMLHttpRequest`` for this view to be found and called.\n          This is useful for detecting AJAX requests issued from\n          jQuery, Prototype and other Javascript libraries.\n\n        accept\n\n          The value of this argument represents a match query for one\n          or more mimetypes in the ``Accept`` HTTP request header.  If\n          this value is specified, it must be in one of the following\n          forms: a mimetype match token in the form ``text/plain``, a\n          wildcard mimetype match token in the form ``text/*`` or a\n          match-all wildcard mimetype match token in the form ``*/*``.\n          If any of the forms matches the ``Accept`` header of the\n          request, this predicate will be true.\n\n        header\n\n          This value represents an HTTP header name or a header\n          name/value pair.  If the value contains a ``:`` (colon), it\n          will be considered a name/value pair\n          (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``).  The\n          value portion should be a regular expression.  If the value\n          does not contain a colon, the entire value will be\n          considered to be the header name\n          (e.g. ``If-Modified-Since``).  If the value evaluates to a\n          header name only without a value, the header specified by\n          the name must be present in the request for this predicate\n          to be true.  If the value evaluates to a header name/value\n          pair, the header specified by the name must be present in\n          the request *and* the regular expression specified as the\n          value must match the header value.  Whether or not the value\n          represents a header name or a header name/value pair, the\n          case of the header name is not significant.\n\n        path_info\n\n          This value represents a regular expression pattern that will\n          be tested against the ``PATH_INFO`` WSGI environment\n          variable.  If the regex matches, this predicate will be\n          ``True``.\n\n        check_csrf\n\n          If specified, this value should be one of ``None``, ``True``,\n          ``False``, or a string representing the 'check name'.  If the value\n          is ``True`` or a string, CSRF checking will be performed.  If the\n          value is ``False`` or ``None``, CSRF checking will not be performed.\n\n          If the value provided is a string, that string will be used as the\n          'check name'.  If the value provided is ``True``, ``csrf_token`` will\n          be used as the check name.\n\n          If CSRF checking is performed, the checked value will be the value\n          of ``request.params[check_name]``.  This value will be compared\n          against the value of ``request.session.get_csrf_token()``, and the\n          check will pass if these two values are the same.  If the check\n          passes, the associated view will be permitted to execute.  If the\n          check fails, the associated view will not be permitted to execute.\n\n          Note that using this feature requires a :term:`session factory` to\n          have been configured.\n         \n          .. versionadded:: 1.4a2\n\n        physical_path\n\n          If specified, this value should be a string or a tuple representing\n          the :term:`physical path` of the context found via traversal for this\n          predicate to match as true.  For example: ``physical_path='/'`` or\n          ``physical_path='/a/b/c'`` or ``physical_path=('', 'a', 'b', 'c')``.\n          This is not a path prefix match or a regex, it's a whole-path match.\n          It's useful when you want to always potentially show a view when some\n          object is traversed to, but you can't be sure about what kind of\n          object it will be, so you can't use the ``context`` predicate.  The\n          individual path elements inbetween slash characters or in tuple\n          elements should be the Unicode representation of the name of the\n          resource and should not be encoded in any way.\n\n          .. versionadded:: 1.4a3\n\n        effective_principals\n\n          If specified, this value should be a :term:`principal` identifier or\n          a sequence of principal identifiers.  If the\n          :func:`pyramid.security.effective_principals` method indicates that\n          every principal named in the argument list is present in the current\n          request, this predicate will return True; otherwise it will return\n          False.  For example:\n          ``effective_principals=pyramid.security.Authenticated`` or\n          ``effective_principals=('fred', 'group:admins')``.\n\n          .. versionadded:: 1.4a4\n\n        custom_predicates\n\n          .. deprecated:: 1.5\n\n          This value should be a sequence of references to custom predicate\n          callables.  Use custom predicates when no set of predefined\n          predicates do what you need.  Custom predicates can be combined with\n          predefined predicates as necessary.  Each custom predicate callable\n          should accept two arguments: ``context`` and ``request`` and should\n          return either ``True`` or ``False`` after doing arbitrary evaluation\n          of the context and/or the request.  The ``predicates`` argument to\n          this method and the ability to register third-party view predicates\n          via :meth:`pyramid.config.Configurator.add_view_predicate` obsoletes\n          this argument, but it is kept around for backwards compatibility.\n\n        predicates\n\n          Pass a key/value pair here to use a third-party predicate\n          registered via\n          :meth:`pyramid.config.Configurator.add_view_predicate`.  More than\n          one key/value pair can be used at the same time.  See\n          :ref:`view_and_route_predicates` for more information about\n          third-party predicates.\n\n          .. versionadded: 1.4a1\n\n        \"\"\"\n        if custom_predicates:\n            warnings.warn(\n                ('The \"custom_predicates\" argument to Configurator.add_view '\n                 'is deprecated as of Pyramid 1.5.  Use '\n                 '\"config.add_view_predicate\" and use the registered '\n                 'view predicate as a predicate argument to add_view instead. '\n                 'See \"Adding A Third Party View, Route, or Subscriber '\n                 'Predicate\" in the \"Hooks\" chapter of the documentation '\n                 'for more information.'),\n                DeprecationWarning,\n                stacklevel=4\n                )\n        \n        view = self.maybe_dotted(view)\n        context = self.maybe_dotted(context)\n        for_ = self.maybe_dotted(for_)\n        containment = self.maybe_dotted(containment)\n        mapper = self.maybe_dotted(mapper)\n\n        def combine(*decorators):\n            def decorated(view_callable):\n                # reversed() is allows a more natural ordering in the api\n                for decorator in reversed(decorators):\n                    view_callable = decorator(view_callable)\n                return view_callable\n            return decorated\n\n        if is_nonstr_iter(decorator):\n            decorator = combine(*map(self.maybe_dotted, decorator))\n        else:\n            decorator = self.maybe_dotted(decorator)\n\n        if not view:\n            if renderer:\n                def view(context, request):\n                    return {}\n            else:\n                raise ConfigurationError('\"view\" was not specified and '\n                                         'no \"renderer\" specified')\n\n        if request_type is not None:\n            request_type = self.maybe_dotted(request_type)\n            if not IInterface.providedBy(request_type):\n                raise ConfigurationError(\n                    'request_type must be an interface, not %s' % request_type)\n\n        if context is None:\n            context = for_\n\n        r_context = context\n        if r_context is None:\n            r_context = Interface\n        if not IInterface.providedBy(r_context):\n            r_context = implementedBy(r_context)\n\n        if isinstance(renderer, string_types):\n            renderer = renderers.RendererHelper(\n                name=renderer, package=self.package,\n                registry = self.registry)\n\n        if accept is not None:\n            accept = accept.lower()\n\n        introspectables = []\n        pvals = predicates.copy()\n        pvals.update(\n            dict(\n                xhr=xhr,\n                request_method=request_method,\n                path_info=path_info,\n                request_param=request_param,\n                header=header,\n                accept=accept,\n                containment=containment,\n                request_type=request_type,\n                match_param=match_param,\n                check_csrf=check_csrf,\n                custom=predvalseq(custom_predicates),\n                )\n            )\n\n        def discrim_func():\n            # We need to defer the discriminator until we know what the phash\n            # is.  It can't be computed any sooner because thirdparty\n            # predicates may not yet exist when add_view is called.\n            order, preds, phash = predlist.make(self, **pvals)\n            view_intr.update({'phash':phash, 'order':order, 'predicates':preds})\n            return ('view', context, name, route_name, phash)\n\n        discriminator = Deferred(discrim_func)\n\n        if inspect.isclass(view) and attr:\n            view_desc = 'method %r of %s' % (\n                attr, self.object_description(view))\n        else:\n            view_desc = self.object_description(view)\n\n        tmpl_intr = None\n            \n        view_intr = self.introspectable('views',\n                                        discriminator,\n                                        view_desc,\n                                        'view')\n        view_intr.update(\n            dict(name=name,\n                 context=context,\n                 containment=containment,\n                 request_param=request_param,\n                 request_methods=request_method,\n                 route_name=route_name,\n                 attr=attr,\n                 xhr=xhr,\n                 accept=accept,\n                 header=header,\n                 path_info=path_info,\n                 match_param=match_param,\n                 check_csrf=check_csrf,\n                 callable=view,\n                 mapper=mapper,\n                 decorator=decorator,\n                 )\n            )\n        view_intr.update(**predicates)\n        introspectables.append(view_intr)\n        predlist = self.get_predlist('view')\n\n        def register(permission=permission, renderer=renderer):\n            # the discrim_func above is guaranteed to have been called already\n            order = view_intr['order']\n            preds = view_intr['predicates']\n            phash = view_intr['phash']\n            request_iface = IRequest\n            if route_name is not None:\n                request_iface = self.registry.queryUtility(IRouteRequest,\n                                                           name=route_name)\n                if request_iface is None:\n                    # route configuration should have already happened in\n                    # phase 2\n                    raise ConfigurationError(\n                        'No route named %s found for view registration' %\n                        route_name)\n\n            if renderer is None:\n                # use default renderer if one exists (reg'd in phase 1)\n                if self.registry.queryUtility(IRendererFactory) is not None:\n                    renderer = renderers.RendererHelper(\n                        name=None,\n                        package=self.package,\n                        registry=self.registry\n                        )\n\n            if permission is None:\n                # intent: will be None if no default permission is registered\n                # (reg'd in phase 1)\n                permission = self.registry.queryUtility(IDefaultPermission)\n\n            # added by discrim_func above during conflict resolving\n            preds = view_intr['predicates']\n            order = view_intr['order']\n            phash = view_intr['phash']\n\n            # __no_permission_required__ handled by _secure_view\n            deriver = ViewDeriver(\n                registry=self.registry,\n                permission=permission,\n                predicates=preds,\n                attr=attr,\n                renderer=renderer,\n                wrapper_viewname=wrapper,\n                viewname=name,\n                accept=accept,\n                order=order,\n                phash=phash,\n                package=self.package,\n                mapper=mapper,\n                decorator=decorator,\n                http_cache=http_cache,\n                )\n            derived_view = deriver(view)\n            derived_view.__discriminator__ = lambda *arg: discriminator\n            # __discriminator__ is used by superdynamic systems\n            # that require it for introspection after manual view lookup;\n            # see also MultiView.__discriminator__\n            view_intr['derived_callable'] = derived_view\n\n            registered = self.registry.adapters.registered\n\n            # A multiviews is a set of views which are registered for\n            # exactly the same context type/request type/name triad.  Each\n            # consituent view in a multiview differs only by the\n            # predicates which it possesses.\n\n            # To find a previously registered view for a context\n            # type/request type/name triad, we need to use the\n            # ``registered`` method of the adapter registry rather than\n            # ``lookup``.  ``registered`` ignores interface inheritance\n            # for the required and provided arguments, returning only a\n            # view registered previously with the *exact* triad we pass\n            # in.\n\n            # We need to do this three times, because we use three\n            # different interfaces as the ``provided`` interface while\n            # doing registrations, and ``registered`` performs exact\n            # matches on all the arguments it receives.\n\n            old_view = None\n\n            for view_type in (IView, ISecuredView, IMultiView):\n                old_view = registered((IViewClassifier, request_iface,\n                                       r_context), view_type, name)\n                if old_view is not None:\n                    break\n\n            isexc = isexception(context)\n\n            def regclosure():\n                if hasattr(derived_view, '__call_permissive__'):\n                    view_iface = ISecuredView\n                else:\n                    view_iface = IView\n                self.registry.registerAdapter(\n                    derived_view,\n                    (IViewClassifier, request_iface, context), view_iface, name\n                    )\n                if isexc:\n                    self.registry.registerAdapter(\n                        derived_view,\n                        (IExceptionViewClassifier, request_iface, context),\n                        view_iface, name)\n\n            is_multiview = IMultiView.providedBy(old_view)\n            old_phash = getattr(old_view, '__phash__', DEFAULT_PHASH)\n\n            if old_view is None:\n                # - No component was yet registered for any of our I*View\n                #   interfaces exactly; this is the first view for this\n                #   triad.\n                regclosure()\n\n            elif (not is_multiview) and (old_phash == phash):\n                # - A single view component was previously registered with\n                #   the same predicate hash as this view; this registration\n                #   is therefore an override.\n                regclosure()\n\n            else:\n                # - A view or multiview was already registered for this\n                #   triad, and the new view is not an override.\n\n                # XXX we could try to be more efficient here and register\n                # a non-secured view for a multiview if none of the\n                # multiview's consituent views have a permission\n                # associated with them, but this code is getting pretty\n                # rough already\n                if is_multiview:\n                    multiview = old_view\n                else:\n                    multiview = MultiView(name)\n                    old_accept = getattr(old_view, '__accept__', None)\n                    old_order = getattr(old_view, '__order__', MAX_ORDER)\n                    multiview.add(old_view, old_order, old_accept, old_phash)\n                multiview.add(derived_view, order, accept, phash)\n                for view_type in (IView, ISecuredView):\n                    # unregister any existing views\n                    self.registry.adapters.unregister(\n                        (IViewClassifier, request_iface, r_context),\n                        view_type, name=name)\n                    if isexc:\n                        self.registry.adapters.unregister(\n                            (IExceptionViewClassifier, request_iface,\n                             r_context), view_type, name=name)\n                self.registry.registerAdapter(\n                    multiview,\n                    (IViewClassifier, request_iface, context),\n                    IMultiView, name=name)\n                if isexc:\n                    self.registry.registerAdapter(\n                        multiview,\n                        (IExceptionViewClassifier, request_iface, context),\n                        IMultiView, name=name)\n            renderer_type = getattr(renderer, 'type', None) # gard against None\n            intrspc = self.introspector\n            if (\n                renderer_type is not None and\n                tmpl_intr is not None and\n                intrspc is not None and\n                intrspc.get('renderer factories', renderer_type) is not None\n                ):\n                # allow failure of registered template factories to be deferred\n                # until view execution, like other bad renderer factories; if\n                # we tried to relate this to an existing renderer factory\n                # without checking if it the factory actually existed, we'd end\n                # up with a KeyError at startup time, which is inconsistent\n                # with how other bad renderer registrations behave (they throw\n                # a ValueError at view execution time)\n                tmpl_intr.relate('renderer factories', renderer.type)\n\n        if mapper:\n            mapper_intr = self.introspectable(\n                'view mappers',\n                discriminator,\n                'view mapper for %s' % view_desc,\n                'view mapper'\n                )\n            mapper_intr['mapper'] = mapper\n            mapper_intr.relate('views', discriminator)\n            introspectables.append(mapper_intr)\n        if route_name:\n            view_intr.relate('routes', route_name) # see add_route\n        if renderer is not None and renderer.name and '.' in renderer.name:\n            # the renderer is a template\n            tmpl_intr = self.introspectable(\n                'templates',\n                discriminator,\n                renderer.name,\n                'template'\n                )\n            tmpl_intr.relate('views', discriminator)\n            tmpl_intr['name'] = renderer.name\n            tmpl_intr['type'] = renderer.type\n            tmpl_intr['renderer'] = renderer\n            introspectables.append(tmpl_intr)\n        if permission is not None:\n            # if a permission exists, register a permission introspectable\n            perm_intr = self.introspectable(\n                'permissions',\n                permission,\n                permission,\n                'permission'\n                )\n            perm_intr['value'] = permission\n            perm_intr.relate('views', discriminator)\n            introspectables.append(perm_intr)\n        self.action(discriminator, register, introspectables=introspectables)\n\n    @action_method\n    def add_view_predicate(self, name, factory, weighs_more_than=None,\n                           weighs_less_than=None):\n        \"\"\"\n        .. versionadded:: 1.4\n\n        Adds a view predicate factory.  The associated view predicate can\n        later be named as a keyword argument to\n        :meth:`pyramid.config.Configurator.add_view` in the\n        ``predicates`` anonyous keyword argument dictionary.\n\n        ``name`` should be the name of the predicate.  It must be a valid\n        Python identifier (it will be used as a keyword argument to\n        ``add_view`` by others).\n\n        ``factory`` should be a :term:`predicate factory` or :term:`dotted\n        Python name` which refers to a predicate factory.\n\n        See :ref:`view_and_route_predicates` for more information.\n        \"\"\"\n        self._add_predicate(\n            'view',\n            name,\n            factory,\n            weighs_more_than=weighs_more_than,\n            weighs_less_than=weighs_less_than\n            )\n\n    def add_default_view_predicates(self):\n        p = pyramid.config.predicates\n        for (name, factory) in (\n            ('xhr', p.XHRPredicate),\n            ('request_method', p.RequestMethodPredicate),\n            ('path_info', p.PathInfoPredicate),\n            ('request_param', p.RequestParamPredicate),\n            ('header', p.HeaderPredicate),\n            ('accept', p.AcceptPredicate),\n            ('containment', p.ContainmentPredicate),\n            ('request_type', p.RequestTypePredicate),\n            ('match_param', p.MatchParamPredicate),\n            ('check_csrf', p.CheckCSRFTokenPredicate),\n            ('physical_path', p.PhysicalPathPredicate),\n            ('effective_principals', p.EffectivePrincipalsPredicate),\n            ('custom', p.CustomPredicate),\n            ):\n            self.add_view_predicate(name, factory)\n\n    def derive_view(self, view, attr=None, renderer=None):\n        \"\"\"\n        Create a :term:`view callable` using the function, instance,\n        or class (or :term:`dotted Python name` referring to the same)\n        provided as ``view`` object.\n\n        .. warning::\n\n           This method is typically only used by :app:`Pyramid` framework\n           extension authors, not by :app:`Pyramid` application developers.\n\n        This is API is useful to framework extenders who create\n        pluggable systems which need to register 'proxy' view\n        callables for functions, instances, or classes which meet the\n        requirements of being a :app:`Pyramid` view callable.  For\n        example, a ``some_other_framework`` function in another\n        framework may want to allow a user to supply a view callable,\n        but he may want to wrap the view callable in his own before\n        registering the wrapper as a :app:`Pyramid` view callable.\n        Because a :app:`Pyramid` view callable can be any of a\n        number of valid objects, the framework extender will not know\n        how to call the user-supplied object.  Running it through\n        ``derive_view`` normalizes it to a callable which accepts two\n        arguments: ``context`` and ``request``.\n\n        For example:\n\n        .. code-block:: python\n\n           def some_other_framework(user_supplied_view):\n               config = Configurator(reg)\n               proxy_view = config.derive_view(user_supplied_view)\n               def my_wrapper(context, request):\n                   do_something_that_mutates(request)\n                   return proxy_view(context, request)\n               config.add_view(my_wrapper)\n\n        The ``view`` object provided should be one of the following:\n\n        - A function or another non-class callable object that accepts\n          a :term:`request` as a single positional argument and which\n          returns a :term:`response` object.\n\n        - A function or other non-class callable object that accepts\n          two positional arguments, ``context, request`` and which\n          returns a :term:`response` object.\n\n        - A class which accepts a single positional argument in its\n          constructor named ``request``, and which has a ``__call__``\n          method that accepts no arguments that returns a\n          :term:`response` object.\n\n        - A class which accepts two positional arguments named\n          ``context, request``, and which has a ``__call__`` method\n          that accepts no arguments that returns a :term:`response`\n          object.\n\n        - A :term:`dotted Python name` which refers to any of the\n          kinds of objects above.\n\n        This API returns a callable which accepts the arguments\n        ``context, request`` and which returns the result of calling\n        the provided ``view`` object.\n\n        The ``attr`` keyword argument is most useful when the view\n        object is a class.  It names the method that should be used as\n        the callable.  If ``attr`` is not provided, the attribute\n        effectively defaults to ``__call__``.  See\n        :ref:`class_as_view` for more information.\n\n        The ``renderer`` keyword argument should be a renderer\n        name. If supplied, it will cause the returned callable to use\n        a :term:`renderer` to convert the user-supplied view result to\n        a :term:`response` object.  If a ``renderer`` argument is not\n        supplied, the user-supplied view must itself return a\n        :term:`response` object.  \"\"\"\n        return self._derive_view(view, attr=attr, renderer=renderer)\n\n    # b/w compat\n    def _derive_view(self, view, permission=None, predicates=(),\n                     attr=None, renderer=None, wrapper_viewname=None,\n                     viewname=None, accept=None, order=MAX_ORDER,\n                     phash=DEFAULT_PHASH, decorator=None,\n                     mapper=None, http_cache=None):\n        view = self.maybe_dotted(view)\n        mapper = self.maybe_dotted(mapper)\n        if isinstance(renderer, string_types):\n            renderer = renderers.RendererHelper(\n                name=renderer, package=self.package,\n                registry = self.registry)\n        if renderer is None:\n            # use default renderer if one exists\n            if self.registry.queryUtility(IRendererFactory) is not None:\n                renderer = renderers.RendererHelper(\n                    name=None,\n                    package=self.package,\n                    registry=self.registry)\n\n        deriver = ViewDeriver(registry=self.registry,\n                              permission=permission,\n                              predicates=predicates,\n                              attr=attr,\n                              renderer=renderer,\n                              wrapper_viewname=wrapper_viewname,\n                              viewname=viewname,\n                              accept=accept,\n                              order=order,\n                              phash=phash,\n                              package=self.package,\n                              mapper=mapper,\n                              decorator=decorator,\n                              http_cache=http_cache)\n\n        return deriver(view)\n\n    @viewdefaults\n    @action_method\n    def add_forbidden_view(\n        self,\n        view=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        route_name=None,\n        request_type=None,\n        request_method=None, \n        request_param=None,\n        containment=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        decorator=None,\n        mapper=None,\n        match_param=None,\n        **predicates\n        ):\n        \"\"\" Add a forbidden view to the current configuration state.  The\n        view will be called when Pyramid or application code raises a\n        :exc:`pyramid.httpexceptions.HTTPForbidden` exception and the set of\n        circumstances implied by the predicates provided are matched.  The\n        simplest example is:\n\n          .. code-block:: python\n\n            def forbidden(request):\n                return Response('Forbidden', status='403 Forbidden')\n\n            config.add_forbidden_view(forbidden)\n\n        All arguments have the same meaning as\n        :meth:`pyramid.config.Configurator.add_view` and each predicate\n        argument restricts the set of circumstances under which this notfound\n        view will be invoked.  Unlike\n        :meth:`pyramid.config.Configurator.add_view`, this method will raise\n        an exception if passed ``name``, ``permission``, ``context``,\n        ``for_``, or ``http_cache`` keyword arguments.  These argument values\n        make no sense in the context of a forbidden view.\n\n        .. versionadded:: 1.3\n        \"\"\"\n        for arg in ('name', 'permission', 'context', 'for_', 'http_cache'):\n            if arg in predicates:\n                raise ConfigurationError(\n                    '%s may not be used as an argument to add_forbidden_view'\n                    % arg\n                    )\n        \n        settings = dict(\n            view=view,\n            context=HTTPForbidden,\n            wrapper=wrapper,\n            request_type=request_type,\n            request_method=request_method,\n            request_param=request_param,\n            containment=containment,\n            xhr=xhr,\n            accept=accept,\n            header=header, \n            path_info=path_info,\n            custom_predicates=custom_predicates,\n            decorator=decorator,\n            mapper=mapper,\n            match_param=match_param,\n            route_name=route_name,\n            permission=NO_PERMISSION_REQUIRED,\n            attr=attr,\n            renderer=renderer,\n            )\n        settings.update(predicates)\n        return self.add_view(**settings)\n\n    set_forbidden_view = add_forbidden_view # deprecated sorta-bw-compat alias\n    \n    @viewdefaults\n    @action_method\n    def add_notfound_view(\n        self,\n        view=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        route_name=None,\n        request_type=None,\n        request_method=None, \n        request_param=None,\n        containment=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        decorator=None,\n        mapper=None,\n        match_param=None,\n        append_slash=False,\n        **predicates\n        ):\n        \"\"\" Add a default Not Found View to the current configuration state.\n        The view will be called when Pyramid or application code raises an\n        :exc:`pyramid.httpexceptions.HTTPNotFound` exception (e.g. when a\n        view cannot be found for the request).  The simplest example is:\n\n          .. code-block:: python\n\n            def notfound(request):\n                return Response('Not Found', status='404 Not Found')\n\n            config.add_notfound_view(notfound)\n\n        All arguments except ``append_slash`` have the same meaning as\n        :meth:`pyramid.config.Configurator.add_view` and each predicate\n        argument restricts the set of circumstances under which this notfound\n        view will be invoked.  Unlike\n        :meth:`pyramid.config.Configurator.add_view`, this method will raise\n        an exception if passed ``name``, ``permission``, ``context``,\n        ``for_``, or ``http_cache`` keyword arguments.  These argument values\n        make no sense in the context of a Not Found View.\n\n        If ``append_slash`` is ``True``, when this Not Found View is invoked,\n        and the current path info does not end in a slash, the notfound logic\n        will attempt to find a :term:`route` that matches the request's path\n        info suffixed with a slash.  If such a route exists, Pyramid will\n        issue a redirect to the URL implied by the route; if it does not,\n        Pyramid will return the result of the view callable provided as\n        ``view``, as normal.\n\n        .. versionadded:: 1.3\n        \"\"\"\n        for arg in ('name', 'permission', 'context', 'for_', 'http_cache'):\n            if arg in predicates:\n                raise ConfigurationError(\n                    '%s may not be used as an argument to add_notfound_view'\n                    % arg\n                    )\n                    \n        settings = dict(\n            view=view,\n            context=HTTPNotFound,\n            wrapper=wrapper,\n            request_type=request_type,\n            request_method=request_method,\n            request_param=request_param,\n            containment=containment,\n            xhr=xhr,\n            accept=accept,\n            header=header, \n            path_info=path_info,\n            custom_predicates=custom_predicates,\n            decorator=decorator,\n            mapper=mapper,\n            match_param=match_param,\n            route_name=route_name,\n            permission=NO_PERMISSION_REQUIRED,\n            )\n        settings.update(predicates)\n        if append_slash:\n            view = self._derive_view(view, attr=attr, renderer=renderer)\n            view = AppendSlashNotFoundViewFactory(view)\n            settings['view'] = view\n        else:\n            settings['attr'] = attr\n            settings['renderer'] = renderer\n        return self.add_view(**settings)\n\n    set_notfound_view = add_notfound_view # deprecated sorta-bw-compat alias\n\n    @action_method\n    def set_view_mapper(self, mapper):\n        \"\"\"\n        Setting a :term:`view mapper` makes it possible to make use of\n        :term:`view callable` objects which implement different call\n        signatures than the ones supported by :app:`Pyramid` as described in\n        its narrative documentation.\n\n        The ``mapper`` should argument be an object implementing\n        :class:`pyramid.interfaces.IViewMapperFactory` or a :term:`dotted\n        Python name` to such an object.  The provided ``mapper`` will become\n        the default view mapper to be used by all subsequent :term:`view\n        configuration` registrations.\n\n        See also :ref:`using_a_view_mapper`.\n\n        .. note::\n\n           Using the ``default_view_mapper`` argument to the\n           :class:`pyramid.config.Configurator` constructor\n           can be used to achieve the same purpose.\n        \"\"\"\n        mapper = self.maybe_dotted(mapper)\n        def register():\n            self.registry.registerUtility(mapper, IViewMapperFactory)\n        # IViewMapperFactory is looked up as the result of view config\n        # in phase 3\n        intr = self.introspectable('view mappers',\n                                   IViewMapperFactory,\n                                   self.object_description(mapper),\n                                   'default view mapper')\n        intr['mapper'] = mapper\n        self.action(IViewMapperFactory, register, order=PHASE1_CONFIG,\n                    introspectables=(intr,))\n\n    @action_method\n    def add_static_view(self, name, path, **kw):\n        \"\"\" Add a view used to render static assets such as images\n        and CSS files.\n\n        The ``name`` argument is a string representing an\n        application-relative local URL prefix.  It may alternately be a full\n        URL.\n\n        The ``path`` argument is the path on disk where the static files\n        reside.  This can be an absolute path, a package-relative path, or a\n        :term:`asset specification`.\n\n        The ``cache_max_age`` keyword argument is input to set the\n        ``Expires`` and ``Cache-Control`` headers for static assets served.\n        Note that this argument has no effect when the ``name`` is a *url\n        prefix*.  By default, this argument is ``None``, meaning that no\n        particular Expires or Cache-Control headers are set in the response.\n\n        The ``permission`` keyword argument is used to specify the\n        :term:`permission` required by a user to execute the static view.  By\n        default, it is the string\n        :data:`pyramid.security.NO_PERMISSION_REQUIRED`, a special sentinel\n        which indicates that, even if a :term:`default permission` exists for\n        the current application, the static view should be renderered to\n        completely anonymous users.  This default value is permissive\n        because, in most web apps, static assets seldom need protection from\n        viewing.  If ``permission`` is specified, the security checking will\n        be performed against the default root factory ACL.\n\n        Any other keyword arguments sent to ``add_static_view`` are passed on\n        to :meth:`pyramid.config.Configurator.add_route` (e.g. ``factory``,\n        perhaps to define a custom factory with a custom ACL for this static\n        view).\n\n        *Usage*\n\n        The ``add_static_view`` function is typically used in conjunction\n        with the :meth:`pyramid.request.Request.static_url` method.\n        ``add_static_view`` adds a view which renders a static asset when\n        some URL is visited; :meth:`pyramid.request.Request.static_url`\n        generates a URL to that asset.\n\n        The ``name`` argument to ``add_static_view`` is usually a simple URL\n        prefix (e.g. ``'images'``).  When this is the case, the\n        :meth:`pyramid.request.Request.static_url` API will generate a URL\n        which points to a Pyramid view, which will serve up a set of assets\n        that live in the package itself. For example:\n\n        .. code-block:: python\n\n           add_static_view('images', 'mypackage:images/')\n\n        Code that registers such a view can generate URLs to the view via\n        :meth:`pyramid.request.Request.static_url`:\n\n        .. code-block:: python\n\n           request.static_url('mypackage:images/logo.png')\n\n        When ``add_static_view`` is called with a ``name`` argument that\n        represents a URL prefix, as it is above, subsequent calls to\n        :meth:`pyramid.request.Request.static_url` with paths that start with\n        the ``path`` argument passed to ``add_static_view`` will generate a\n        URL something like ``http://<Pyramid app URL>/images/logo.png``,\n        which will cause the ``logo.png`` file in the ``images`` subdirectory\n        of the ``mypackage`` package to be served.\n\n        ``add_static_view`` can alternately be used with a ``name`` argument\n        which is a *URL*, causing static assets to be served from an external\n        webserver.  This happens when the ``name`` argument is a fully\n        qualified URL (e.g. starts with ``http://`` or similar).  In this\n        mode, the ``name`` is used as the prefix of the full URL when\n        generating a URL using :meth:`pyramid.request.Request.static_url`.\n        Furthermore, if a protocol-relative URL (e.g. ``//example.com/images``)\n        is used as the ``name`` argument, the generated URL will use the\n        protocol of the request (http or https, respectively).\n\n        For example, if ``add_static_view`` is called like so:\n\n        .. code-block:: python\n\n           add_static_view('http://example.com/images', 'mypackage:images/')\n\n        Subsequently, the URLs generated by\n        :meth:`pyramid.request.Request.static_url` for that static view will\n        be prefixed with ``http://example.com/images`` (the external webserver\n        listening on ``example.com`` must be itself configured to respond\n        properly to such a request.):\n\n        .. code-block:: python\n\n           static_url('mypackage:images/logo.png', request)\n\n        See :ref:`static_assets_section` for more information.\n        \"\"\"\n        spec = self._make_spec(path)\n        info = self.registry.queryUtility(IStaticURLInfo)\n        if info is None:\n            info = StaticURLInfo()\n            self.registry.registerUtility(info, IStaticURLInfo)\n        info.add(self, name, spec, **kw)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 594,
                            "end_lineno": 1862,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 1629,
                            "length": 6
                        },
                        "new_range": {
                            "start": 1630,
                            "length": 7
                        },
                        "section": "class ViewsConfiguratorMixin(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    set_forbidden_view = add_forbidden_view # deprecated sorta-bw-compat alias",
                                "type": "context"
                            },
                            {
                                "content": "    ",
                                "type": "context"
                            },
                            {
                                "content": "    @viewdefaults",
                                "type": "added"
                            },
                            {
                                "content": "    @action_method",
                                "type": "context"
                            },
                            {
                                "content": "    def add_notfound_view(",
                                "type": "context"
                            },
                            {
                                "content": "        self,",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "pyramid/config/views.py",
                            "type": "class",
                            "name": "ViewsConfiguratorMixin",
                            "content": "class ViewsConfiguratorMixin(object):\n    @viewdefaults\n    @action_method\n    def add_view(\n        self,\n        view=None,\n        name=\"\",\n        for_=None,\n        permission=None,\n        request_type=None,\n        route_name=None,\n        request_method=None,\n        request_param=None,\n        containment=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        context=None,\n        decorator=None,\n        mapper=None,\n        http_cache=None,\n        match_param=None,\n        check_csrf=None,\n        **predicates):\n        \"\"\" Add a :term:`view configuration` to the current\n        configuration state.  Arguments to ``add_view`` are broken\n        down below into *predicate* arguments and *non-predicate*\n        arguments.  Predicate arguments narrow the circumstances in\n        which the view callable will be invoked when a request is\n        presented to :app:`Pyramid`; non-predicate arguments are\n        informational.\n\n        Non-Predicate Arguments\n\n        view\n\n          A :term:`view callable` or a :term:`dotted Python name`\n          which refers to a view callable.  This argument is required\n          unless a ``renderer`` argument also exists.  If a\n          ``renderer`` argument is passed, and a ``view`` argument is\n          not provided, the view callable defaults to a callable that\n          returns an empty dictionary (see\n          :ref:`views_which_use_a_renderer`).\n\n        permission\n\n          A :term:`permission` that the user must possess in order to invoke\n          the :term:`view callable`.  See :ref:`view_security_section` for\n          more information about view security and permissions.  This is\n          often a string like ``view`` or ``edit``.\n\n          If ``permission`` is omitted, a *default* permission may be used\n          for this view registration if one was named as the\n          :class:`pyramid.config.Configurator` constructor's\n          ``default_permission`` argument, or if\n          :meth:`pyramid.config.Configurator.set_default_permission` was used\n          prior to this view registration.  Pass the value\n          :data:`pyramid.security.NO_PERMISSION_REQUIRED` as the permission\n          argument to explicitly indicate that the view should always be\n          executable by entirely anonymous users, regardless of the default\n          permission, bypassing any :term:`authorization policy` that may be\n          in effect.\n\n        attr\n\n          This knob is most useful when the view definition is a class.\n\n          The view machinery defaults to using the ``__call__`` method\n          of the :term:`view callable` (or the function itself, if the\n          view callable is a function) to obtain a response.  The\n          ``attr`` value allows you to vary the method attribute used\n          to obtain the response.  For example, if your view was a\n          class, and the class has a method named ``index`` and you\n          wanted to use this method instead of the class' ``__call__``\n          method to return the response, you'd say ``attr=\"index\"`` in the\n          view configuration for the view.\n\n        renderer\n\n          This is either a single string term (e.g. ``json``) or a\n          string implying a path or :term:`asset specification`\n          (e.g. ``templates/views.pt``) naming a :term:`renderer`\n          implementation.  If the ``renderer`` value does not contain\n          a dot ``.``, the specified string will be used to look up a\n          renderer implementation, and that renderer implementation\n          will be used to construct a response from the view return\n          value.  If the ``renderer`` value contains a dot (``.``),\n          the specified term will be treated as a path, and the\n          filename extension of the last element in the path will be\n          used to look up the renderer implementation, which will be\n          passed the full path.  The renderer implementation will be\n          used to construct a :term:`response` from the view return\n          value.\n\n          Note that if the view itself returns a :term:`response` (see\n          :ref:`the_response`), the specified renderer implementation\n          is never called.\n\n          When the renderer is a path, although a path is usually just\n          a simple relative pathname (e.g. ``templates/foo.pt``,\n          implying that a template named \"foo.pt\" is in the\n          \"templates\" directory relative to the directory of the\n          current :term:`package` of the Configurator), a path can be\n          absolute, starting with a slash on UNIX or a drive letter\n          prefix on Windows.  The path can alternately be a\n          :term:`asset specification` in the form\n          ``some.dotted.package_name:relative/path``, making it\n          possible to address template assets which live in a\n          separate package.\n\n          The ``renderer`` attribute is optional.  If it is not\n          defined, the \"null\" renderer is assumed (no rendering is\n          performed and the value is passed back to the upstream\n          :app:`Pyramid` machinery unmodified).\n\n        http_cache\n\n          .. versionadded:: 1.1\n\n          When you supply an ``http_cache`` value to a view configuration,\n          the ``Expires`` and ``Cache-Control`` headers of a response\n          generated by the associated view callable are modified.  The value\n          for ``http_cache`` may be one of the following:\n\n          - A nonzero integer.  If it's a nonzero integer, it's treated as a\n            number of seconds.  This number of seconds will be used to\n            compute the ``Expires`` header and the ``Cache-Control:\n            max-age`` parameter of responses to requests which call this view.\n            For example: ``http_cache=3600`` instructs the requesting browser\n            to 'cache this response for an hour, please'.\n\n          - A ``datetime.timedelta`` instance.  If it's a\n            ``datetime.timedelta`` instance, it will be converted into a\n            number of seconds, and that number of seconds will be used to\n            compute the ``Expires`` header and the ``Cache-Control:\n            max-age`` parameter of responses to requests which call this view.\n            For example: ``http_cache=datetime.timedelta(days=1)`` instructs\n            the requesting browser to 'cache this response for a day, please'.\n\n          - Zero (``0``).  If the value is zero, the ``Cache-Control`` and\n            ``Expires`` headers present in all responses from this view will\n            be composed such that client browser cache (and any intermediate\n            caches) are instructed to never cache the response.\n\n          - A two-tuple.  If it's a two tuple (e.g. ``http_cache=(1,\n            {'public':True})``), the first value in the tuple may be a\n            nonzero integer or a ``datetime.timedelta`` instance; in either\n            case this value will be used as the number of seconds to cache\n            the response.  The second value in the tuple must be a\n            dictionary.  The values present in the dictionary will be used as\n            input to the ``Cache-Control`` response header.  For example:\n            ``http_cache=(3600, {'public':True})`` means 'cache for an hour,\n            and add ``public`` to the Cache-Control header of the response'.\n            All keys and values supported by the\n            ``webob.cachecontrol.CacheControl`` interface may be added to the\n            dictionary.  Supplying ``{'public':True}`` is equivalent to\n            calling ``response.cache_control.public = True``.\n\n          Providing a non-tuple value as ``http_cache`` is equivalent to\n          calling ``response.cache_expires(value)`` within your view's body.\n\n          Providing a two-tuple value as ``http_cache`` is equivalent to\n          calling ``response.cache_expires(value[0], **value[1])`` within your\n          view's body.\n\n          If you wish to avoid influencing, the ``Expires`` header, and\n          instead wish to only influence ``Cache-Control`` headers, pass a\n          tuple as ``http_cache`` with the first element of ``None``, e.g.:\n          ``(None, {'public':True})``.\n\n          If you wish to prevent a view that uses ``http_cache`` in its\n          configuration from having its caching response headers changed by\n          this machinery, set ``response.cache_control.prevent_auto = True``\n          before returning the response from the view.  This effectively\n          disables any HTTP caching done by ``http_cache`` for that response.\n\n        wrapper\n\n          The :term:`view name` of a different :term:`view\n          configuration` which will receive the response body of this\n          view as the ``request.wrapped_body`` attribute of its own\n          :term:`request`, and the :term:`response` returned by this\n          view as the ``request.wrapped_response`` attribute of its\n          own request.  Using a wrapper makes it possible to \"chain\"\n          views together to form a composite response.  The response\n          of the outermost wrapper view will be returned to the user.\n          The wrapper view will be found as any view is found: see\n          :ref:`view_lookup`.  The \"best\" wrapper view will be found\n          based on the lookup ordering: \"under the hood\" this wrapper\n          view is looked up via\n          ``pyramid.view.render_view_to_response(context, request,\n          'wrapper_viewname')``. The context and request of a wrapper\n          view is the same context and request of the inner view.  If\n          this attribute is unspecified, no view wrapping is done.\n\n        decorator\n\n          A :term:`dotted Python name` to function (or the function itself,\n          or an iterable of the aforementioned) which will be used to\n          decorate the registered :term:`view callable`.  The decorator\n          function(s) will be called with the view callable as a single\n          argument.  The view callable it is passed will accept\n          ``(context, request)``.  The decorator(s) must return a\n          replacement view callable which also accepts ``(context,\n          request)``.\n\n          If decorator is an iterable, the callables will be combined and\n          used in the order provided as a decorator.\n          For example::\n\n            @view_config(...,\n                decorator=(decorator2,\n                           decorator1))\n            def myview(request):\n                ....\n\n          Is similar to doing::\n\n            @view_config(...)\n            @decorator2\n            @decorator1\n            def myview(request):\n                ...\n\n          Except with the existing benefits of ``decorator=`` (having a common\n          decorator syntax for all view calling conventions and not having to\n          think about preserving function attributes such as ``__name__`` and\n          ``__module__`` within decorator logic).\n\n          .. versionchanged:: 1.4a4\n             Passing an iterable.\n\n        mapper\n\n          A Python object or :term:`dotted Python name` which refers to a\n          :term:`view mapper`, or ``None``.  By default it is ``None``, which\n          indicates that the view should use the default view mapper.  This\n          plug-point is useful for Pyramid extension developers, but it's not\n          very useful for 'civilians' who are just developing stock Pyramid\n          applications. Pay no attention to the man behind the curtain.\n\n        Predicate Arguments\n\n        name\n\n          The :term:`view name`.  Read :ref:`traversal_chapter` to\n          understand the concept of a view name.\n\n        context\n\n          An object or a :term:`dotted Python name` referring to an\n          interface or class object that the :term:`context` must be\n          an instance of, *or* the :term:`interface` that the\n          :term:`context` must provide in order for this view to be\n          found and called.  This predicate is true when the\n          :term:`context` is an instance of the represented class or\n          if the :term:`context` provides the represented interface;\n          it is otherwise false.  This argument may also be provided\n          to ``add_view`` as ``for_`` (an older, still-supported\n          spelling).\n\n        route_name\n\n          This value must match the ``name`` of a :term:`route\n          configuration` declaration (see :ref:`urldispatch_chapter`)\n          that must match before this view will be called.\n\n        request_type\n\n          This value should be an :term:`interface` that the\n          :term:`request` must provide in order for this view to be\n          found and called.  This value exists only for backwards\n          compatibility purposes.\n\n        request_method\n\n          This value can be one of the strings ``GET``, ``POST``, ``PUT``,\n          ``DELETE``, or ``HEAD`` representing an HTTP ``REQUEST_METHOD``, or\n          a tuple containing one or more of these strings.  A view\n          declaration with this argument ensures that the view will only be\n          called when the request's ``method`` attribute (aka the\n          ``REQUEST_METHOD`` of the WSGI environment) string matches a\n          supplied value.  Note that use of ``GET`` also implies that the\n          view will respond to ``HEAD`` as of Pyramid 1.4.\n\n          .. versionchanged:: 1.2\n             The ability to pass a tuple of items as ``request_method``.\n             Previous versions allowed only a string.\n\n        request_param\n\n          This value can be any string or any sequence of strings.  A view \n          declaration with this argument ensures that the view will only be \n          called when the :term:`request` has a key in the ``request.params``\n          dictionary (an HTTP ``GET`` or ``POST`` variable) that has a\n          name which matches the supplied value (if the value is a string)\n          or values (if the value is a tuple).  If any value\n          supplied has a ``=`` sign in it,\n          e.g. ``request_param=\"foo=123\"``, then the key (``foo``)\n          must both exist in the ``request.params`` dictionary, *and*\n          the value must match the right hand side of the expression\n          (``123``) for the view to \"match\" the current request.\n\n        match_param\n\n          .. versionadded:: 1.2\n\n          This value can be a string of the format \"key=value\" or a tuple\n          containing one or more of these strings.\n\n          A view declaration with this argument ensures that the view will\n          only be called when the :term:`request` has key/value pairs in its\n          :term:`matchdict` that equal those supplied in the predicate.\n          e.g. ``match_param=\"action=edit\" would require the ``action``\n          parameter in the :term:`matchdict` match the right hand side of\n          the expression (``edit``) for the view to \"match\" the current\n          request.\n\n          If the ``match_param`` is a tuple, every key/value pair must match\n          for the predicate to pass.\n\n        containment\n\n          This value should be a Python class or :term:`interface` (or a\n          :term:`dotted Python name`) that an object in the\n          :term:`lineage` of the context must provide in order for this view\n          to be found and called.  The nodes in your object graph must be\n          \"location-aware\" to use this feature.  See\n          :ref:`location_aware` for more information about\n          location-awareness.\n\n        xhr\n\n          This value should be either ``True`` or ``False``.  If this\n          value is specified and is ``True``, the :term:`request`\n          must possess an ``HTTP_X_REQUESTED_WITH`` (aka\n          ``X-Requested-With``) header that has the value\n          ``XMLHttpRequest`` for this view to be found and called.\n          This is useful for detecting AJAX requests issued from\n          jQuery, Prototype and other Javascript libraries.\n\n        accept\n\n          The value of this argument represents a match query for one\n          or more mimetypes in the ``Accept`` HTTP request header.  If\n          this value is specified, it must be in one of the following\n          forms: a mimetype match token in the form ``text/plain``, a\n          wildcard mimetype match token in the form ``text/*`` or a\n          match-all wildcard mimetype match token in the form ``*/*``.\n          If any of the forms matches the ``Accept`` header of the\n          request, this predicate will be true.\n\n        header\n\n          This value represents an HTTP header name or a header\n          name/value pair.  If the value contains a ``:`` (colon), it\n          will be considered a name/value pair\n          (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``).  The\n          value portion should be a regular expression.  If the value\n          does not contain a colon, the entire value will be\n          considered to be the header name\n          (e.g. ``If-Modified-Since``).  If the value evaluates to a\n          header name only without a value, the header specified by\n          the name must be present in the request for this predicate\n          to be true.  If the value evaluates to a header name/value\n          pair, the header specified by the name must be present in\n          the request *and* the regular expression specified as the\n          value must match the header value.  Whether or not the value\n          represents a header name or a header name/value pair, the\n          case of the header name is not significant.\n\n        path_info\n\n          This value represents a regular expression pattern that will\n          be tested against the ``PATH_INFO`` WSGI environment\n          variable.  If the regex matches, this predicate will be\n          ``True``.\n\n        check_csrf\n\n          If specified, this value should be one of ``None``, ``True``,\n          ``False``, or a string representing the 'check name'.  If the value\n          is ``True`` or a string, CSRF checking will be performed.  If the\n          value is ``False`` or ``None``, CSRF checking will not be performed.\n\n          If the value provided is a string, that string will be used as the\n          'check name'.  If the value provided is ``True``, ``csrf_token`` will\n          be used as the check name.\n\n          If CSRF checking is performed, the checked value will be the value\n          of ``request.params[check_name]``.  This value will be compared\n          against the value of ``request.session.get_csrf_token()``, and the\n          check will pass if these two values are the same.  If the check\n          passes, the associated view will be permitted to execute.  If the\n          check fails, the associated view will not be permitted to execute.\n\n          Note that using this feature requires a :term:`session factory` to\n          have been configured.\n         \n          .. versionadded:: 1.4a2\n\n        physical_path\n\n          If specified, this value should be a string or a tuple representing\n          the :term:`physical path` of the context found via traversal for this\n          predicate to match as true.  For example: ``physical_path='/'`` or\n          ``physical_path='/a/b/c'`` or ``physical_path=('', 'a', 'b', 'c')``.\n          This is not a path prefix match or a regex, it's a whole-path match.\n          It's useful when you want to always potentially show a view when some\n          object is traversed to, but you can't be sure about what kind of\n          object it will be, so you can't use the ``context`` predicate.  The\n          individual path elements inbetween slash characters or in tuple\n          elements should be the Unicode representation of the name of the\n          resource and should not be encoded in any way.\n\n          .. versionadded:: 1.4a3\n\n        effective_principals\n\n          If specified, this value should be a :term:`principal` identifier or\n          a sequence of principal identifiers.  If the\n          :func:`pyramid.security.effective_principals` method indicates that\n          every principal named in the argument list is present in the current\n          request, this predicate will return True; otherwise it will return\n          False.  For example:\n          ``effective_principals=pyramid.security.Authenticated`` or\n          ``effective_principals=('fred', 'group:admins')``.\n\n          .. versionadded:: 1.4a4\n\n        custom_predicates\n\n          .. deprecated:: 1.5\n\n          This value should be a sequence of references to custom predicate\n          callables.  Use custom predicates when no set of predefined\n          predicates do what you need.  Custom predicates can be combined with\n          predefined predicates as necessary.  Each custom predicate callable\n          should accept two arguments: ``context`` and ``request`` and should\n          return either ``True`` or ``False`` after doing arbitrary evaluation\n          of the context and/or the request.  The ``predicates`` argument to\n          this method and the ability to register third-party view predicates\n          via :meth:`pyramid.config.Configurator.add_view_predicate` obsoletes\n          this argument, but it is kept around for backwards compatibility.\n\n        predicates\n\n          Pass a key/value pair here to use a third-party predicate\n          registered via\n          :meth:`pyramid.config.Configurator.add_view_predicate`.  More than\n          one key/value pair can be used at the same time.  See\n          :ref:`view_and_route_predicates` for more information about\n          third-party predicates.\n\n          .. versionadded: 1.4a1\n\n        \"\"\"\n        if custom_predicates:\n            warnings.warn(\n                ('The \"custom_predicates\" argument to Configurator.add_view '\n                 'is deprecated as of Pyramid 1.5.  Use '\n                 '\"config.add_view_predicate\" and use the registered '\n                 'view predicate as a predicate argument to add_view instead. '\n                 'See \"Adding A Third Party View, Route, or Subscriber '\n                 'Predicate\" in the \"Hooks\" chapter of the documentation '\n                 'for more information.'),\n                DeprecationWarning,\n                stacklevel=4\n                )\n        \n        view = self.maybe_dotted(view)\n        context = self.maybe_dotted(context)\n        for_ = self.maybe_dotted(for_)\n        containment = self.maybe_dotted(containment)\n        mapper = self.maybe_dotted(mapper)\n\n        def combine(*decorators):\n            def decorated(view_callable):\n                # reversed() is allows a more natural ordering in the api\n                for decorator in reversed(decorators):\n                    view_callable = decorator(view_callable)\n                return view_callable\n            return decorated\n\n        if is_nonstr_iter(decorator):\n            decorator = combine(*map(self.maybe_dotted, decorator))\n        else:\n            decorator = self.maybe_dotted(decorator)\n\n        if not view:\n            if renderer:\n                def view(context, request):\n                    return {}\n            else:\n                raise ConfigurationError('\"view\" was not specified and '\n                                         'no \"renderer\" specified')\n\n        if request_type is not None:\n            request_type = self.maybe_dotted(request_type)\n            if not IInterface.providedBy(request_type):\n                raise ConfigurationError(\n                    'request_type must be an interface, not %s' % request_type)\n\n        if context is None:\n            context = for_\n\n        r_context = context\n        if r_context is None:\n            r_context = Interface\n        if not IInterface.providedBy(r_context):\n            r_context = implementedBy(r_context)\n\n        if isinstance(renderer, string_types):\n            renderer = renderers.RendererHelper(\n                name=renderer, package=self.package,\n                registry = self.registry)\n\n        if accept is not None:\n            accept = accept.lower()\n\n        introspectables = []\n        pvals = predicates.copy()\n        pvals.update(\n            dict(\n                xhr=xhr,\n                request_method=request_method,\n                path_info=path_info,\n                request_param=request_param,\n                header=header,\n                accept=accept,\n                containment=containment,\n                request_type=request_type,\n                match_param=match_param,\n                check_csrf=check_csrf,\n                custom=predvalseq(custom_predicates),\n                )\n            )\n\n        def discrim_func():\n            # We need to defer the discriminator until we know what the phash\n            # is.  It can't be computed any sooner because thirdparty\n            # predicates may not yet exist when add_view is called.\n            order, preds, phash = predlist.make(self, **pvals)\n            view_intr.update({'phash':phash, 'order':order, 'predicates':preds})\n            return ('view', context, name, route_name, phash)\n\n        discriminator = Deferred(discrim_func)\n\n        if inspect.isclass(view) and attr:\n            view_desc = 'method %r of %s' % (\n                attr, self.object_description(view))\n        else:\n            view_desc = self.object_description(view)\n\n        tmpl_intr = None\n            \n        view_intr = self.introspectable('views',\n                                        discriminator,\n                                        view_desc,\n                                        'view')\n        view_intr.update(\n            dict(name=name,\n                 context=context,\n                 containment=containment,\n                 request_param=request_param,\n                 request_methods=request_method,\n                 route_name=route_name,\n                 attr=attr,\n                 xhr=xhr,\n                 accept=accept,\n                 header=header,\n                 path_info=path_info,\n                 match_param=match_param,\n                 check_csrf=check_csrf,\n                 callable=view,\n                 mapper=mapper,\n                 decorator=decorator,\n                 )\n            )\n        view_intr.update(**predicates)\n        introspectables.append(view_intr)\n        predlist = self.get_predlist('view')\n\n        def register(permission=permission, renderer=renderer):\n            # the discrim_func above is guaranteed to have been called already\n            order = view_intr['order']\n            preds = view_intr['predicates']\n            phash = view_intr['phash']\n            request_iface = IRequest\n            if route_name is not None:\n                request_iface = self.registry.queryUtility(IRouteRequest,\n                                                           name=route_name)\n                if request_iface is None:\n                    # route configuration should have already happened in\n                    # phase 2\n                    raise ConfigurationError(\n                        'No route named %s found for view registration' %\n                        route_name)\n\n            if renderer is None:\n                # use default renderer if one exists (reg'd in phase 1)\n                if self.registry.queryUtility(IRendererFactory) is not None:\n                    renderer = renderers.RendererHelper(\n                        name=None,\n                        package=self.package,\n                        registry=self.registry\n                        )\n\n            if permission is None:\n                # intent: will be None if no default permission is registered\n                # (reg'd in phase 1)\n                permission = self.registry.queryUtility(IDefaultPermission)\n\n            # added by discrim_func above during conflict resolving\n            preds = view_intr['predicates']\n            order = view_intr['order']\n            phash = view_intr['phash']\n\n            # __no_permission_required__ handled by _secure_view\n            deriver = ViewDeriver(\n                registry=self.registry,\n                permission=permission,\n                predicates=preds,\n                attr=attr,\n                renderer=renderer,\n                wrapper_viewname=wrapper,\n                viewname=name,\n                accept=accept,\n                order=order,\n                phash=phash,\n                package=self.package,\n                mapper=mapper,\n                decorator=decorator,\n                http_cache=http_cache,\n                )\n            derived_view = deriver(view)\n            derived_view.__discriminator__ = lambda *arg: discriminator\n            # __discriminator__ is used by superdynamic systems\n            # that require it for introspection after manual view lookup;\n            # see also MultiView.__discriminator__\n            view_intr['derived_callable'] = derived_view\n\n            registered = self.registry.adapters.registered\n\n            # A multiviews is a set of views which are registered for\n            # exactly the same context type/request type/name triad.  Each\n            # consituent view in a multiview differs only by the\n            # predicates which it possesses.\n\n            # To find a previously registered view for a context\n            # type/request type/name triad, we need to use the\n            # ``registered`` method of the adapter registry rather than\n            # ``lookup``.  ``registered`` ignores interface inheritance\n            # for the required and provided arguments, returning only a\n            # view registered previously with the *exact* triad we pass\n            # in.\n\n            # We need to do this three times, because we use three\n            # different interfaces as the ``provided`` interface while\n            # doing registrations, and ``registered`` performs exact\n            # matches on all the arguments it receives.\n\n            old_view = None\n\n            for view_type in (IView, ISecuredView, IMultiView):\n                old_view = registered((IViewClassifier, request_iface,\n                                       r_context), view_type, name)\n                if old_view is not None:\n                    break\n\n            isexc = isexception(context)\n\n            def regclosure():\n                if hasattr(derived_view, '__call_permissive__'):\n                    view_iface = ISecuredView\n                else:\n                    view_iface = IView\n                self.registry.registerAdapter(\n                    derived_view,\n                    (IViewClassifier, request_iface, context), view_iface, name\n                    )\n                if isexc:\n                    self.registry.registerAdapter(\n                        derived_view,\n                        (IExceptionViewClassifier, request_iface, context),\n                        view_iface, name)\n\n            is_multiview = IMultiView.providedBy(old_view)\n            old_phash = getattr(old_view, '__phash__', DEFAULT_PHASH)\n\n            if old_view is None:\n                # - No component was yet registered for any of our I*View\n                #   interfaces exactly; this is the first view for this\n                #   triad.\n                regclosure()\n\n            elif (not is_multiview) and (old_phash == phash):\n                # - A single view component was previously registered with\n                #   the same predicate hash as this view; this registration\n                #   is therefore an override.\n                regclosure()\n\n            else:\n                # - A view or multiview was already registered for this\n                #   triad, and the new view is not an override.\n\n                # XXX we could try to be more efficient here and register\n                # a non-secured view for a multiview if none of the\n                # multiview's consituent views have a permission\n                # associated with them, but this code is getting pretty\n                # rough already\n                if is_multiview:\n                    multiview = old_view\n                else:\n                    multiview = MultiView(name)\n                    old_accept = getattr(old_view, '__accept__', None)\n                    old_order = getattr(old_view, '__order__', MAX_ORDER)\n                    multiview.add(old_view, old_order, old_accept, old_phash)\n                multiview.add(derived_view, order, accept, phash)\n                for view_type in (IView, ISecuredView):\n                    # unregister any existing views\n                    self.registry.adapters.unregister(\n                        (IViewClassifier, request_iface, r_context),\n                        view_type, name=name)\n                    if isexc:\n                        self.registry.adapters.unregister(\n                            (IExceptionViewClassifier, request_iface,\n                             r_context), view_type, name=name)\n                self.registry.registerAdapter(\n                    multiview,\n                    (IViewClassifier, request_iface, context),\n                    IMultiView, name=name)\n                if isexc:\n                    self.registry.registerAdapter(\n                        multiview,\n                        (IExceptionViewClassifier, request_iface, context),\n                        IMultiView, name=name)\n            renderer_type = getattr(renderer, 'type', None) # gard against None\n            intrspc = self.introspector\n            if (\n                renderer_type is not None and\n                tmpl_intr is not None and\n                intrspc is not None and\n                intrspc.get('renderer factories', renderer_type) is not None\n                ):\n                # allow failure of registered template factories to be deferred\n                # until view execution, like other bad renderer factories; if\n                # we tried to relate this to an existing renderer factory\n                # without checking if it the factory actually existed, we'd end\n                # up with a KeyError at startup time, which is inconsistent\n                # with how other bad renderer registrations behave (they throw\n                # a ValueError at view execution time)\n                tmpl_intr.relate('renderer factories', renderer.type)\n\n        if mapper:\n            mapper_intr = self.introspectable(\n                'view mappers',\n                discriminator,\n                'view mapper for %s' % view_desc,\n                'view mapper'\n                )\n            mapper_intr['mapper'] = mapper\n            mapper_intr.relate('views', discriminator)\n            introspectables.append(mapper_intr)\n        if route_name:\n            view_intr.relate('routes', route_name) # see add_route\n        if renderer is not None and renderer.name and '.' in renderer.name:\n            # the renderer is a template\n            tmpl_intr = self.introspectable(\n                'templates',\n                discriminator,\n                renderer.name,\n                'template'\n                )\n            tmpl_intr.relate('views', discriminator)\n            tmpl_intr['name'] = renderer.name\n            tmpl_intr['type'] = renderer.type\n            tmpl_intr['renderer'] = renderer\n            introspectables.append(tmpl_intr)\n        if permission is not None:\n            # if a permission exists, register a permission introspectable\n            perm_intr = self.introspectable(\n                'permissions',\n                permission,\n                permission,\n                'permission'\n                )\n            perm_intr['value'] = permission\n            perm_intr.relate('views', discriminator)\n            introspectables.append(perm_intr)\n        self.action(discriminator, register, introspectables=introspectables)\n\n    @action_method\n    def add_view_predicate(self, name, factory, weighs_more_than=None,\n                           weighs_less_than=None):\n        \"\"\"\n        .. versionadded:: 1.4\n\n        Adds a view predicate factory.  The associated view predicate can\n        later be named as a keyword argument to\n        :meth:`pyramid.config.Configurator.add_view` in the\n        ``predicates`` anonyous keyword argument dictionary.\n\n        ``name`` should be the name of the predicate.  It must be a valid\n        Python identifier (it will be used as a keyword argument to\n        ``add_view`` by others).\n\n        ``factory`` should be a :term:`predicate factory` or :term:`dotted\n        Python name` which refers to a predicate factory.\n\n        See :ref:`view_and_route_predicates` for more information.\n        \"\"\"\n        self._add_predicate(\n            'view',\n            name,\n            factory,\n            weighs_more_than=weighs_more_than,\n            weighs_less_than=weighs_less_than\n            )\n\n    def add_default_view_predicates(self):\n        p = pyramid.config.predicates\n        for (name, factory) in (\n            ('xhr', p.XHRPredicate),\n            ('request_method', p.RequestMethodPredicate),\n            ('path_info', p.PathInfoPredicate),\n            ('request_param', p.RequestParamPredicate),\n            ('header', p.HeaderPredicate),\n            ('accept', p.AcceptPredicate),\n            ('containment', p.ContainmentPredicate),\n            ('request_type', p.RequestTypePredicate),\n            ('match_param', p.MatchParamPredicate),\n            ('check_csrf', p.CheckCSRFTokenPredicate),\n            ('physical_path', p.PhysicalPathPredicate),\n            ('effective_principals', p.EffectivePrincipalsPredicate),\n            ('custom', p.CustomPredicate),\n            ):\n            self.add_view_predicate(name, factory)\n\n    def derive_view(self, view, attr=None, renderer=None):\n        \"\"\"\n        Create a :term:`view callable` using the function, instance,\n        or class (or :term:`dotted Python name` referring to the same)\n        provided as ``view`` object.\n\n        .. warning::\n\n           This method is typically only used by :app:`Pyramid` framework\n           extension authors, not by :app:`Pyramid` application developers.\n\n        This is API is useful to framework extenders who create\n        pluggable systems which need to register 'proxy' view\n        callables for functions, instances, or classes which meet the\n        requirements of being a :app:`Pyramid` view callable.  For\n        example, a ``some_other_framework`` function in another\n        framework may want to allow a user to supply a view callable,\n        but he may want to wrap the view callable in his own before\n        registering the wrapper as a :app:`Pyramid` view callable.\n        Because a :app:`Pyramid` view callable can be any of a\n        number of valid objects, the framework extender will not know\n        how to call the user-supplied object.  Running it through\n        ``derive_view`` normalizes it to a callable which accepts two\n        arguments: ``context`` and ``request``.\n\n        For example:\n\n        .. code-block:: python\n\n           def some_other_framework(user_supplied_view):\n               config = Configurator(reg)\n               proxy_view = config.derive_view(user_supplied_view)\n               def my_wrapper(context, request):\n                   do_something_that_mutates(request)\n                   return proxy_view(context, request)\n               config.add_view(my_wrapper)\n\n        The ``view`` object provided should be one of the following:\n\n        - A function or another non-class callable object that accepts\n          a :term:`request` as a single positional argument and which\n          returns a :term:`response` object.\n\n        - A function or other non-class callable object that accepts\n          two positional arguments, ``context, request`` and which\n          returns a :term:`response` object.\n\n        - A class which accepts a single positional argument in its\n          constructor named ``request``, and which has a ``__call__``\n          method that accepts no arguments that returns a\n          :term:`response` object.\n\n        - A class which accepts two positional arguments named\n          ``context, request``, and which has a ``__call__`` method\n          that accepts no arguments that returns a :term:`response`\n          object.\n\n        - A :term:`dotted Python name` which refers to any of the\n          kinds of objects above.\n\n        This API returns a callable which accepts the arguments\n        ``context, request`` and which returns the result of calling\n        the provided ``view`` object.\n\n        The ``attr`` keyword argument is most useful when the view\n        object is a class.  It names the method that should be used as\n        the callable.  If ``attr`` is not provided, the attribute\n        effectively defaults to ``__call__``.  See\n        :ref:`class_as_view` for more information.\n\n        The ``renderer`` keyword argument should be a renderer\n        name. If supplied, it will cause the returned callable to use\n        a :term:`renderer` to convert the user-supplied view result to\n        a :term:`response` object.  If a ``renderer`` argument is not\n        supplied, the user-supplied view must itself return a\n        :term:`response` object.  \"\"\"\n        return self._derive_view(view, attr=attr, renderer=renderer)\n\n    # b/w compat\n    def _derive_view(self, view, permission=None, predicates=(),\n                     attr=None, renderer=None, wrapper_viewname=None,\n                     viewname=None, accept=None, order=MAX_ORDER,\n                     phash=DEFAULT_PHASH, decorator=None,\n                     mapper=None, http_cache=None):\n        view = self.maybe_dotted(view)\n        mapper = self.maybe_dotted(mapper)\n        if isinstance(renderer, string_types):\n            renderer = renderers.RendererHelper(\n                name=renderer, package=self.package,\n                registry = self.registry)\n        if renderer is None:\n            # use default renderer if one exists\n            if self.registry.queryUtility(IRendererFactory) is not None:\n                renderer = renderers.RendererHelper(\n                    name=None,\n                    package=self.package,\n                    registry=self.registry)\n\n        deriver = ViewDeriver(registry=self.registry,\n                              permission=permission,\n                              predicates=predicates,\n                              attr=attr,\n                              renderer=renderer,\n                              wrapper_viewname=wrapper_viewname,\n                              viewname=viewname,\n                              accept=accept,\n                              order=order,\n                              phash=phash,\n                              package=self.package,\n                              mapper=mapper,\n                              decorator=decorator,\n                              http_cache=http_cache)\n\n        return deriver(view)\n\n    @viewdefaults\n    @action_method\n    def add_forbidden_view(\n        self,\n        view=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        route_name=None,\n        request_type=None,\n        request_method=None, \n        request_param=None,\n        containment=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        decorator=None,\n        mapper=None,\n        match_param=None,\n        **predicates\n        ):\n        \"\"\" Add a forbidden view to the current configuration state.  The\n        view will be called when Pyramid or application code raises a\n        :exc:`pyramid.httpexceptions.HTTPForbidden` exception and the set of\n        circumstances implied by the predicates provided are matched.  The\n        simplest example is:\n\n          .. code-block:: python\n\n            def forbidden(request):\n                return Response('Forbidden', status='403 Forbidden')\n\n            config.add_forbidden_view(forbidden)\n\n        All arguments have the same meaning as\n        :meth:`pyramid.config.Configurator.add_view` and each predicate\n        argument restricts the set of circumstances under which this notfound\n        view will be invoked.  Unlike\n        :meth:`pyramid.config.Configurator.add_view`, this method will raise\n        an exception if passed ``name``, ``permission``, ``context``,\n        ``for_``, or ``http_cache`` keyword arguments.  These argument values\n        make no sense in the context of a forbidden view.\n\n        .. versionadded:: 1.3\n        \"\"\"\n        for arg in ('name', 'permission', 'context', 'for_', 'http_cache'):\n            if arg in predicates:\n                raise ConfigurationError(\n                    '%s may not be used as an argument to add_forbidden_view'\n                    % arg\n                    )\n        \n        settings = dict(\n            view=view,\n            context=HTTPForbidden,\n            wrapper=wrapper,\n            request_type=request_type,\n            request_method=request_method,\n            request_param=request_param,\n            containment=containment,\n            xhr=xhr,\n            accept=accept,\n            header=header, \n            path_info=path_info,\n            custom_predicates=custom_predicates,\n            decorator=decorator,\n            mapper=mapper,\n            match_param=match_param,\n            route_name=route_name,\n            permission=NO_PERMISSION_REQUIRED,\n            attr=attr,\n            renderer=renderer,\n            )\n        settings.update(predicates)\n        return self.add_view(**settings)\n\n    set_forbidden_view = add_forbidden_view # deprecated sorta-bw-compat alias\n    \n    @viewdefaults\n    @action_method\n    def add_notfound_view(\n        self,\n        view=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        route_name=None,\n        request_type=None,\n        request_method=None, \n        request_param=None,\n        containment=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        decorator=None,\n        mapper=None,\n        match_param=None,\n        append_slash=False,\n        **predicates\n        ):\n        \"\"\" Add a default Not Found View to the current configuration state.\n        The view will be called when Pyramid or application code raises an\n        :exc:`pyramid.httpexceptions.HTTPNotFound` exception (e.g. when a\n        view cannot be found for the request).  The simplest example is:\n\n          .. code-block:: python\n\n            def notfound(request):\n                return Response('Not Found', status='404 Not Found')\n\n            config.add_notfound_view(notfound)\n\n        All arguments except ``append_slash`` have the same meaning as\n        :meth:`pyramid.config.Configurator.add_view` and each predicate\n        argument restricts the set of circumstances under which this notfound\n        view will be invoked.  Unlike\n        :meth:`pyramid.config.Configurator.add_view`, this method will raise\n        an exception if passed ``name``, ``permission``, ``context``,\n        ``for_``, or ``http_cache`` keyword arguments.  These argument values\n        make no sense in the context of a Not Found View.\n\n        If ``append_slash`` is ``True``, when this Not Found View is invoked,\n        and the current path info does not end in a slash, the notfound logic\n        will attempt to find a :term:`route` that matches the request's path\n        info suffixed with a slash.  If such a route exists, Pyramid will\n        issue a redirect to the URL implied by the route; if it does not,\n        Pyramid will return the result of the view callable provided as\n        ``view``, as normal.\n\n        .. versionadded:: 1.3\n        \"\"\"\n        for arg in ('name', 'permission', 'context', 'for_', 'http_cache'):\n            if arg in predicates:\n                raise ConfigurationError(\n                    '%s may not be used as an argument to add_notfound_view'\n                    % arg\n                    )\n                    \n        settings = dict(\n            view=view,\n            context=HTTPNotFound,\n            wrapper=wrapper,\n            request_type=request_type,\n            request_method=request_method,\n            request_param=request_param,\n            containment=containment,\n            xhr=xhr,\n            accept=accept,\n            header=header, \n            path_info=path_info,\n            custom_predicates=custom_predicates,\n            decorator=decorator,\n            mapper=mapper,\n            match_param=match_param,\n            route_name=route_name,\n            permission=NO_PERMISSION_REQUIRED,\n            )\n        settings.update(predicates)\n        if append_slash:\n            view = self._derive_view(view, attr=attr, renderer=renderer)\n            view = AppendSlashNotFoundViewFactory(view)\n            settings['view'] = view\n        else:\n            settings['attr'] = attr\n            settings['renderer'] = renderer\n        return self.add_view(**settings)\n\n    set_notfound_view = add_notfound_view # deprecated sorta-bw-compat alias\n\n    @action_method\n    def set_view_mapper(self, mapper):\n        \"\"\"\n        Setting a :term:`view mapper` makes it possible to make use of\n        :term:`view callable` objects which implement different call\n        signatures than the ones supported by :app:`Pyramid` as described in\n        its narrative documentation.\n\n        The ``mapper`` should argument be an object implementing\n        :class:`pyramid.interfaces.IViewMapperFactory` or a :term:`dotted\n        Python name` to such an object.  The provided ``mapper`` will become\n        the default view mapper to be used by all subsequent :term:`view\n        configuration` registrations.\n\n        See also :ref:`using_a_view_mapper`.\n\n        .. note::\n\n           Using the ``default_view_mapper`` argument to the\n           :class:`pyramid.config.Configurator` constructor\n           can be used to achieve the same purpose.\n        \"\"\"\n        mapper = self.maybe_dotted(mapper)\n        def register():\n            self.registry.registerUtility(mapper, IViewMapperFactory)\n        # IViewMapperFactory is looked up as the result of view config\n        # in phase 3\n        intr = self.introspectable('view mappers',\n                                   IViewMapperFactory,\n                                   self.object_description(mapper),\n                                   'default view mapper')\n        intr['mapper'] = mapper\n        self.action(IViewMapperFactory, register, order=PHASE1_CONFIG,\n                    introspectables=(intr,))\n\n    @action_method\n    def add_static_view(self, name, path, **kw):\n        \"\"\" Add a view used to render static assets such as images\n        and CSS files.\n\n        The ``name`` argument is a string representing an\n        application-relative local URL prefix.  It may alternately be a full\n        URL.\n\n        The ``path`` argument is the path on disk where the static files\n        reside.  This can be an absolute path, a package-relative path, or a\n        :term:`asset specification`.\n\n        The ``cache_max_age`` keyword argument is input to set the\n        ``Expires`` and ``Cache-Control`` headers for static assets served.\n        Note that this argument has no effect when the ``name`` is a *url\n        prefix*.  By default, this argument is ``None``, meaning that no\n        particular Expires or Cache-Control headers are set in the response.\n\n        The ``permission`` keyword argument is used to specify the\n        :term:`permission` required by a user to execute the static view.  By\n        default, it is the string\n        :data:`pyramid.security.NO_PERMISSION_REQUIRED`, a special sentinel\n        which indicates that, even if a :term:`default permission` exists for\n        the current application, the static view should be renderered to\n        completely anonymous users.  This default value is permissive\n        because, in most web apps, static assets seldom need protection from\n        viewing.  If ``permission`` is specified, the security checking will\n        be performed against the default root factory ACL.\n\n        Any other keyword arguments sent to ``add_static_view`` are passed on\n        to :meth:`pyramid.config.Configurator.add_route` (e.g. ``factory``,\n        perhaps to define a custom factory with a custom ACL for this static\n        view).\n\n        *Usage*\n\n        The ``add_static_view`` function is typically used in conjunction\n        with the :meth:`pyramid.request.Request.static_url` method.\n        ``add_static_view`` adds a view which renders a static asset when\n        some URL is visited; :meth:`pyramid.request.Request.static_url`\n        generates a URL to that asset.\n\n        The ``name`` argument to ``add_static_view`` is usually a simple URL\n        prefix (e.g. ``'images'``).  When this is the case, the\n        :meth:`pyramid.request.Request.static_url` API will generate a URL\n        which points to a Pyramid view, which will serve up a set of assets\n        that live in the package itself. For example:\n\n        .. code-block:: python\n\n           add_static_view('images', 'mypackage:images/')\n\n        Code that registers such a view can generate URLs to the view via\n        :meth:`pyramid.request.Request.static_url`:\n\n        .. code-block:: python\n\n           request.static_url('mypackage:images/logo.png')\n\n        When ``add_static_view`` is called with a ``name`` argument that\n        represents a URL prefix, as it is above, subsequent calls to\n        :meth:`pyramid.request.Request.static_url` with paths that start with\n        the ``path`` argument passed to ``add_static_view`` will generate a\n        URL something like ``http://<Pyramid app URL>/images/logo.png``,\n        which will cause the ``logo.png`` file in the ``images`` subdirectory\n        of the ``mypackage`` package to be served.\n\n        ``add_static_view`` can alternately be used with a ``name`` argument\n        which is a *URL*, causing static assets to be served from an external\n        webserver.  This happens when the ``name`` argument is a fully\n        qualified URL (e.g. starts with ``http://`` or similar).  In this\n        mode, the ``name`` is used as the prefix of the full URL when\n        generating a URL using :meth:`pyramid.request.Request.static_url`.\n        Furthermore, if a protocol-relative URL (e.g. ``//example.com/images``)\n        is used as the ``name`` argument, the generated URL will use the\n        protocol of the request (http or https, respectively).\n\n        For example, if ``add_static_view`` is called like so:\n\n        .. code-block:: python\n\n           add_static_view('http://example.com/images', 'mypackage:images/')\n\n        Subsequently, the URLs generated by\n        :meth:`pyramid.request.Request.static_url` for that static view will\n        be prefixed with ``http://example.com/images`` (the external webserver\n        listening on ``example.com`` must be itself configured to respond\n        properly to such a request.):\n\n        .. code-block:: python\n\n           static_url('mypackage:images/logo.png', request)\n\n        See :ref:`static_assets_section` for more information.\n        \"\"\"\n        spec = self._make_spec(path)\n        info = self.registry.queryUtility(IStaticURLInfo)\n        if info is None:\n            info = StaticURLInfo()\n            self.registry.registerUtility(info, IStaticURLInfo)\n        info.add(self, name, spec, **kw)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 594,
                            "end_lineno": 1862,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "import unittest\nfrom pyramid import testing\n\nfrom pyramid.tests.test_config import IDummy\n\nfrom pyramid.tests.test_config import dummy_view\n\nfrom pyramid.compat import (\n    im_func,\n    text_,\n    )\nfrom pyramid.exceptions import ConfigurationError\nfrom pyramid.exceptions import ConfigurationExecutionError\nfrom pyramid.exceptions import ConfigurationConflictError\n\nclass TestViewsConfigurationMixin(unittest.TestCase):\n    def _makeOne(self, *arg, **kw):\n        from pyramid.config import Configurator\n        config = Configurator(*arg, **kw)\n        return config\n\n    def _getViewCallable(self, config, ctx_iface=None, request_iface=None,\n                         name='', exception_view=False):\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        if exception_view:\n            classifier = IExceptionViewClassifier\n        else:\n            classifier = IViewClassifier\n        if ctx_iface is None:\n            ctx_iface = Interface\n        if request_iface is None:\n            request_iface = IRequest\n        return config.registry.adapters.lookup(\n            (classifier, request_iface, ctx_iface), IView, name=name,\n            default=None)\n\n    def _registerRenderer(self, config, name='.txt'):\n        from pyramid.interfaces import IRendererFactory\n        class Renderer:\n            def __init__(self, info):\n                self.__class__.info = info\n            def __call__(self, *arg):\n                return b'Hello!'\n        config.registry.registerUtility(Renderer, IRendererFactory, name=name)\n        return Renderer\n\n    def _makeRequest(self, config):\n        request = DummyRequest()\n        request.registry = config.registry\n        return request\n\n    def _assertNotFound(self, wrapper, *arg):\n        from pyramid.httpexceptions import HTTPNotFound\n        self.assertRaises(HTTPNotFound, wrapper, *arg)\n\n    def _getRouteRequestIface(self, config, name):\n        from pyramid.interfaces import IRouteRequest\n        iface = config.registry.getUtility(IRouteRequest, name)\n        return iface\n\n    def _assertRoute(self, config, name, path, num_predicates=0):\n        from pyramid.interfaces import IRoutesMapper\n        mapper = config.registry.getUtility(IRoutesMapper)\n        routes = mapper.get_routes()\n        route = routes[0]\n        self.assertEqual(len(routes), 1)\n        self.assertEqual(route.name, name)\n        self.assertEqual(route.path, path)\n        self.assertEqual(len(routes[0].predicates), num_predicates)\n        return route\n\n    def test_add_view_view_callable_None_no_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError, config.add_view)\n\n    def test_add_view_with_request_type_and_route_name(self):\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        self.assertRaises(ConfigurationError, config.add_view, view, '', None,\n                          None, True, True)\n\n    def test_add_view_with_request_type(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        from pyramid.interfaces import IRequest\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view,\n                        request_type='pyramid.interfaces.IRequest',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = DummyRequest()\n        self._assertNotFound(wrapper, None, request)\n        directlyProvides(request, IRequest)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_view_callable_None_with_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self._registerRenderer(config, name='dummy')\n        config.add_view(renderer='dummy')\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n\n    def test_add_view_with_tmpl_renderer_factory_introspector_missing(self):\n        config = self._makeOne(autocommit=True)\n        config.introspection = False\n        config.introspector = None\n        config.add_view(renderer='dummy.pt')\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n        \n    def test_add_view_with_tmpl_renderer_factory_no_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector()\n        config.introspector = introspector\n        config.add_view(renderer='dummy.pt')\n        self.assertFalse(('renderer factories', '.pt') in\n                         introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n\n    def test_add_view_with_tmpl_renderer_factory_with_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector(True)\n        config.introspector = introspector\n        def dummy_factory(helper):\n            return lambda val, system_vals: 'Hello!'\n        config.add_renderer('.pt', dummy_factory)\n        config.add_view(renderer='dummy.pt')\n        self.assertTrue(\n            ('renderer factories', '.pt') in introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n        \n    def test_add_view_wrapped_view_is_decorated(self):\n        def view(request): # request-only wrapper\n            \"\"\" \"\"\"\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper.__module__, view.__module__)\n        self.assertEqual(wrapper.__name__, view.__name__)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        self.assertEqual(wrapper.__discriminator__(None, None).resolve()[0],\n                         'view')\n\n    def test_add_view_view_callable_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        config.add_view(view='pyramid.tests.test_config.dummy_view',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_function_callable(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_function_callable_requestonly(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, name='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name='abc')\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name_unicode(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        name = text_(b'La Pe\\xc3\\xb1a', 'utf-8')\n        config.add_view(view=view, name=name, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name=name)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper(fn):\n            def inner(context, request):\n                return fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=view_wrapper,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator_tuple(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper1(fn):\n            def inner(context, request):\n                return 'wrapped1' + fn(context, request)\n            return inner\n        def view_wrapper2(fn):\n            def inner(context, request):\n                return 'wrapped2' + fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=(view_wrapper2, view_wrapper1),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'wrapped2wrapped1OK')\n\n    def test_add_view_with_http_cache(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return response\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, http_cache=(86400, {'public':True}))\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        request = testing.DummyRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(days=1)\n        result = wrapper(None, request)\n        self.assertEqual(result, response)\n        headers = dict(response.headerlist)\n        self.assertEqual(headers['Cache-Control'], 'max-age=86400, public')\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n\n    def test_add_view_as_instance(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, context, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instance_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_oldstyle_class(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, context, request):\n                self.context = context\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_as_oldstyle_class_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, request):\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_context_as_class(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_iface(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context='pyramid.tests.test_config.IDummy',\n                        view=view,  renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for__as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_='pyramid.tests.test_config.IDummy',\n                        view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_class(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_iface(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_trumps_for(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        class Foo:\n            pass\n        config.add_view(context=IDummy, for_=Foo, view=view,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_exception_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_mixed_case_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/HTML', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.media_views.items()),1)\n        self.assertFalse('text/HTML' in wrapper.media_views)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_views_with_accept_multiview_replaces_existing(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(len(wrapper.media_views['text/html']), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_view_exc_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, accept='text/html', context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_multiview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_mulview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_exc_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_multiview_context_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        class ISuper(Interface):\n            pass\n        class ISub(ISuper):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, ISuper), IView, name='')\n        config.add_view(view=view2, for_=ISub, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, ISuper, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n        wrapper = self._getViewCallable(config, ISub, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK2')\n\n    def test_add_view_multiview_exception_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        class Super(Exception):\n            pass\n        class Sub(Super):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Super), IView, name='')\n        config.registry.registerAdapter(\n            view, (IExceptionViewClassifier, IRequest, Super), IView, name='')\n        config.add_view(view=view2, for_=Sub, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, implementedBy(Super), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Super), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n        wrapper = self._getViewCallable(\n            config, implementedBy(Sub), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Sub), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK2')\n\n    def test_add_view_multiview_call_ordering(self):\n        from pyramid.renderers import null_renderer as nr\n        from zope.interface import directlyProvides\n        def view1(context, request): return 'view1'\n        def view2(context, request): return 'view2'\n        def view3(context, request): return 'view3'\n        def view4(context, request): return 'view4'\n        def view5(context, request): return 'view5'\n        def view6(context, request): return 'view6'\n        def view7(context, request): return 'view7'\n        def view8(context, request): return 'view8'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view1, renderer=nr)\n        config.add_view(view=view2, request_method='POST', renderer=nr)\n        config.add_view(view=view3,request_param='param', renderer=nr)\n        config.add_view(view=view4, containment=IDummy, renderer=nr)\n        config.add_view(view=view5, request_method='POST',\n                        request_param='param',  renderer=nr)\n        config.add_view(view=view6, request_method='POST', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view7, request_param='param', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view8, request_method='POST',request_param='param',\n                        containment=IDummy, renderer=nr)\n\n\n        wrapper = self._getViewCallable(config)\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view1')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view2')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {'param':'1'}\n        request.method = 'GET'\n        self.assertEqual(wrapper(ctx, request), 'view3')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view4')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view5')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view6')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view7')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view8')\n\n    def test_add_view_multiview___discriminator__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        class IFoo(Interface):\n            pass\n        class IBar(Interface):\n            pass\n        @implementer(IFoo)\n        class Foo(object):\n            pass\n        @implementer(IBar)\n        class Bar(object):\n            pass\n        foo = Foo()\n        bar = Bar()\n\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IFoo)\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IBar)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        request = self._makeRequest(config)\n        self.assertNotEqual(\n            wrapper.__discriminator__(foo, request),\n            wrapper.__discriminator__(bar, request),\n            )\n\n    def test_add_view_with_template_renderer(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=view, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_default_renderer(self):\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        class moo(object):\n            def __init__(self, *arg, **kw):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'moo'\n        config.add_renderer(None, moo)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'moo')\n\n    def test_add_view_with_template_renderer_no_callable(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=None, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_request_type_as_iface(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        def view(context, request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(request_type=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, None)\n        request = self._makeRequest(config)\n        directlyProvides(request, IDummy)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_request_type_as_noniface(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        self.assertRaises(ConfigurationError,\n                          config.add_view, view, '', None, None, object)\n\n    def test_add_view_with_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        self.assertNotEqual(request_iface, None)\n        wrapper = self._getViewCallable(config, request_iface=request_iface)\n        self.assertNotEqual(wrapper, None)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_nonexistant_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        self.assertRaises(ConfigurationExecutionError, config.commit)\n\n    def test_add_view_with_route_name_exception(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', context=RuntimeError,\n                        renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        wrapper_exc_view = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface, exception_view=True)\n        self.assertNotEqual(wrapper_exc_view, None)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n\n    def test_add_view_with_request_method_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_sequence_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_sequence_conflict(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        config.add_view(view=view, request_method=('GET', 'POST'),\n                        renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_request_method_sequence_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'HEAD'))\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_get_implies_head(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'HEAD'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_param_val_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':'123'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_val_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_xhr_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_xhr_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = False\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, header='Host:a\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_header_noval_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'whatever'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_noval_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NotHost':'whatever'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'1'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_val_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'abc'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_missing(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NoHost':'1'}\n        self.assertRaises(HTTPNotFound, wrapper, None, request)\n\n    def test_add_view_with_accept_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/xml']\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_accept_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/html']\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_containment_true(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_containment_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        self._assertNotFound(wrapper, context, None)\n\n    def test_add_view_with_containment_dottedname(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            containment='pyramid.tests.test_config.IDummy',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_path_info_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, path_info='\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_path_info_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_(b'/foo')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_path_info_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_('/')\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_custom_predicates_match(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return True\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates,\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_custom_predicates_nomatch(self):\n        import warnings\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return False\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_custom_predicate_bests_standard_predicate(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=(pred1,),\n                        renderer=null_renderer)\n            config.add_view(view=view2, request_method='GET',\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_custom_more_preds_first_bests_fewer_preds_last(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', xhr=True,\n                        renderer=null_renderer)\n        config.add_view(view=view2, request_method='GET',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_same_predicates(self):\n        view2 = lambda *arg: 'second'\n        view1 = lambda *arg: 'first'\n        config = self._makeOne()\n        config.add_view(view=view1)\n        config.add_view(view=view2)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, permission='view', renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               default_permission='view',\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_no_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        class DummyPolicy(object): pass # wont be called\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_mapper(self):\n        from pyramid.renderers import null_renderer\n        class Mapper(object):\n            def __init__(self, **kw):\n                self.__class__.kw = kw\n            def __call__(self, view):\n                return view\n        config = self._makeOne(autocommit=True)\n        def view(context, request): return 'OK'\n        config.add_view(view=view, mapper=Mapper, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        self.assertEqual(view(None, None), 'OK')\n        self.assertEqual(Mapper.kw['mapper'], Mapper)\n\n    def test_add_view_with_view_defaults(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_kwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view='pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            'pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_config_and_view_defaults_doesnt_conflict(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IFactory'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        config.commit() # does not raise\n\n    def test_add_view_with_view_config_and_view_defaults_conflicts(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_derive_view_function(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        result = config.derive_view(view, renderer=null_renderer)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne()\n        result = config.derive_view(\n            'pyramid.tests.test_config.dummy_view',\n            renderer=null_renderer)\n        self.assertFalse(result is dummy_view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_with_default_renderer_no_explicit_renderer(self):\n        config = self._makeOne()\n        class moo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return 'moo'\n        config.add_renderer(None, moo)\n        config.commit()\n        def view(request):\n            return 'OK'\n        result = config.derive_view(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None).body, b'moo')\n\n    def test_derive_view_with_default_renderer_with_explicit_renderer(self):\n        class moo(object): pass\n        class foo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'foo'\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        config.add_renderer(None, moo)\n        config.add_renderer('foo', foo)\n        config.commit()\n        result = config.derive_view(view, renderer='foo')\n        self.assertFalse(result is view)\n        request = self._makeRequest(config)\n        self.assertEqual(result(None, request).body, b'foo')\n\n    def test_add_static_view_here_no_utility_registered(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        config = self._makeOne(autocommit=True)\n        config.add_static_view('static', 'files', renderer=null_renderer)\n        request_type = self._getRouteRequestIface(config, '__static/')\n        self._assertRoute(config, '__static/', 'static/*subpath')\n        wrapped = config.registry.adapters.lookup(\n            (IViewClassifier, request_type, Interface), IView, name='')\n        from pyramid.request import Request\n        request = Request.blank('/static/minimal.txt')\n        request.subpath = ('minimal.txt', )\n        result = wrapped(None, request)\n        self.assertEqual(result.status, '200 OK')\n        self.assertTrue(result.body.startswith(b'<div'))\n\n    def test_add_static_view_package_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static',\n                               'pyramid.tests.test_config:files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_package_here_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static', 'files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_absolute(self):\n        import os\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        here = os.path.dirname(__file__)\n        static_path = os.path.join(here, 'files')\n        config.add_static_view('static', static_path)\n        self.assertEqual(info.added,\n                         [(config, 'static', static_path, {})])\n\n    def test_add_forbidden_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        config.add_forbidden_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_forbidden_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_forbidden_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_forbidden_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, name='foo')\n\n    def test_add_forbidden_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, permission='foo')\n\n    def test_add_forbidden_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, context='foo')\n\n    def test_add_forbidden_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, for_='foo')\n\n    def test_add_forbidden_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, http_cache='foo')\n\n    def test_add_notfound_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: arg\n        config.add_notfound_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, (None, request))\n\n    def test_add_notfound_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_notfound_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_notfound_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, name='foo')\n\n    def test_add_notfound_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, permission='foo')\n\n    def test_add_notfound_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, context='foo')\n\n    def test_add_notfound_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, for_='foo')\n\n    def test_add_notfound_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, http_cache='foo')\n\n    def test_add_notfound_view_append_slash(self):\n        from pyramid.response import Response\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/foo/')\n        def view(request): return Response('OK')\n        config.add_notfound_view(view, renderer=null_renderer,append_slash=True)\n        request = self._makeRequest(config)\n        request.environ['PATH_INFO'] = '/foo'\n        request.query_string = 'a=1&b=2'\n        request.path = '/scriptname/foo'\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result.location, '/scriptname/foo/?a=1&b=2')\n\n    # Since Python 3 has to be all cool and fancy and different...\n    def _assertBody(self, response, value):\n        from pyramid.compat import text_type\n        if isinstance(value, text_type): # pragma: nocover\n            self.assertEqual(response.text, value)\n        else: # pragma: nocover\n            self.assertEqual(response.body, value)\n\n    def test_add_notfound_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_notfound_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_add_forbidden_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_forbidden_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_set_view_mapper(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        mapper = object()\n        config.set_view_mapper(mapper)\n        result = config.registry.getUtility(IViewMapperFactory)\n        self.assertEqual(result, mapper)\n\n    def test_set_view_mapper_dottedname(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        config.set_view_mapper('pyramid.tests.test_config')\n        result = config.registry.getUtility(IViewMapperFactory)\n        from pyramid.tests import test_config\n        self.assertEqual(result, test_config)\n\nclass Test_requestonly(unittest.TestCase):\n    def _callFUT(self, view, attr=None):\n        from pyramid.config.views import requestonly\n        return requestonly(view, attr=attr)\n\n    def test_defaults(self):\n        def aview(request, a=1, b=2): pass\n        self.assertTrue(self._callFUT(aview))\n\n    def test_otherattr(self):\n        class AView(object):\n            def __init__(self, request, a=1, b=2): pass\n            def bleh(self): pass\n        self.assertTrue(self._callFUT(AView, 'bleh'))\n\nclass Test_isexception(unittest.TestCase):\n    def _callFUT(self, ob):\n        from pyramid.config.views import isexception\n        return isexception(ob)\n\n    def test_is_exception_instance(self):\n        class E(Exception):\n            pass\n        e = E()\n        self.assertEqual(self._callFUT(e), True)\n\n    def test_is_exception_class(self):\n        class E(Exception):\n            pass\n        self.assertEqual(self._callFUT(E), True)\n\n    def test_is_IException(self):\n        from pyramid.interfaces import IException\n        self.assertEqual(self._callFUT(IException), True)\n\n    def test_is_IException_subinterface(self):\n        from pyramid.interfaces import IException\n        class ISubException(IException):\n            pass\n        self.assertEqual(self._callFUT(ISubException), True)\n\nclass TestMultiView(unittest.TestCase):\n    def _getTargetClass(self):\n        from pyramid.config.views import MultiView\n        return MultiView\n\n    def _makeOne(self, name='name'):\n        return self._getTargetClass()(name)\n\n    def test_class_implements_ISecuredView(self):\n        from zope.interface.verify import verifyClass\n        from pyramid.interfaces import ISecuredView\n        verifyClass(ISecuredView, self._getTargetClass())\n\n    def test_instance_implements_ISecuredView(self):\n        from zope.interface.verify import verifyObject\n        from pyramid.interfaces import ISecuredView\n        verifyObject(ISecuredView, self._makeOne())\n\n    def test_add(self):\n        mv = self._makeOne()\n        mv.add('view', 100)\n        self.assertEqual(mv.views, [(100, 'view', None)])\n        mv.add('view2', 99)\n        self.assertEqual(mv.views, [(99, 'view2', None), (100, 'view', None)])\n        mv.add('view3', 100, 'text/html')\n        self.assertEqual(mv.media_views['text/html'], [(100, 'view3', None)])\n        mv.add('view4', 99, 'text/html', 'abc')\n        self.assertEqual(mv.media_views['text/html'],\n                         [(99, 'view4', 'abc'), (100, 'view3', None)])\n        mv.add('view5', 100, 'text/xml')\n        self.assertEqual(mv.media_views['text/xml'], [(100, 'view5', None)])\n        self.assertEqual(set(mv.accepts), set(['text/xml', 'text/html']))\n        self.assertEqual(mv.views, [(99, 'view2', None), (100, 'view', None)])\n        mv.add('view6', 98, 'text/*')\n        self.assertEqual(mv.views, [(98, 'view6', None),\n                                    (99, 'view2', None),\n                                    (100, 'view', None)])\n\n    def test_add_with_phash(self):\n        mv = self._makeOne()\n        mv.add('view', 100, phash='abc')\n        self.assertEqual(mv.views, [(100, 'view', 'abc')])\n        mv.add('view', 100, phash='abc')\n        self.assertEqual(mv.views, [(100, 'view', 'abc')])\n        mv.add('view', 100, phash='def')\n        self.assertEqual(mv.views, [(100, 'view', 'abc'),\n                                    (100, 'view', 'def')])\n        mv.add('view', 100, phash='abc')\n        self.assertEqual(mv.views, [(100, 'view', 'abc'),\n                                    (100, 'view', 'def')])\n\n    def test_add_with_phash_override_accept(self):\n        mv = self._makeOne()\n        def view1(): pass\n        def view2(): pass\n        def view3(): pass\n        mv.add(view1, 100, accept='text/html', phash='abc')\n        mv.add(view2, 100, accept='text/html', phash='abc')\n        mv.add(view3, 99, accept='text/html', phash='def')\n        self.assertEqual(mv.media_views['text/html'],\n                         [(99, view3, 'def'), (100, view2, 'abc')])\n\n    def test_add_with_phash_override_accept2(self):\n        mv = self._makeOne()\n        def view1(): pass\n        def view2(): pass\n        def view3(): pass\n        mv.add(view1, 100, accept='text/html', phash='abc')\n        mv.add(view2, 100, accept='text/html', phash='def')\n        mv.add(view3, 99, accept='text/html', phash='ghi')\n        self.assertEqual(mv.media_views['text/html'],\n                         [(99, view3, 'ghi'),\n                          (100, view1, 'abc'),\n                          (100, view2, 'def')]\n                         )\n\n    def test_multiple_with_functions_as_views(self):\n        # this failed on py3 at one point, because functions aren't orderable\n        # and we were sorting the views via a plain sort() rather than\n        # sort(key=itemgetter(0)).\n        def view1(request): pass\n        def view2(request): pass\n        mv = self._makeOne()\n        mv.add(view1, 100, None)\n        self.assertEqual(mv.views, [(100, view1, None)])\n        mv.add(view2, 100, None)\n        self.assertEqual(mv.views, [(100, view1, None), (100, view2, None)])\n\n    def test_get_views_request_has_no_accept(self):\n        request = DummyRequest()\n        mv = self._makeOne()\n        mv.views = [(99, lambda *arg: None)]\n        self.assertEqual(mv.get_views(request), mv.views)\n\n    def test_get_views_no_self_accepts(self):\n        request = DummyRequest()\n        request.accept = True\n        mv = self._makeOne()\n        mv.accepts = []\n        mv.views = [(99, lambda *arg: None)]\n        self.assertEqual(mv.get_views(request), mv.views)\n\n    def test_get_views(self):\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        mv = self._makeOne()\n        mv.accepts = ['text/html']\n        mv.views = [(99, lambda *arg: None)]\n        html_views = [(98, lambda *arg: None)]\n        mv.media_views['text/html'] = html_views\n        self.assertEqual(mv.get_views(request), html_views + mv.views)\n\n    def test_get_views_best_match_returns_None(self):\n        request = DummyRequest()\n        request.accept = DummyAccept(None)\n        mv = self._makeOne()\n        mv.accepts = ['text/html']\n        mv.views = [(99, lambda *arg: None)]\n        self.assertEqual(mv.get_views(request), mv.views)\n\n    def test_match_not_found(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv.match, context, request)\n\n    def test_match_predicate_fails(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        def view(context, request):\n            \"\"\" \"\"\"\n        view.__predicated__ = lambda *arg: False\n        mv.views = [(100, view, None)]\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv.match, context, request)\n\n    def test_match_predicate_succeeds(self):\n        mv = self._makeOne()\n        def view(context, request):\n            \"\"\" \"\"\"\n        view.__predicated__ = lambda *arg: True\n        mv.views = [(100, view, None)]\n        context = DummyContext()\n        request = DummyRequest()\n        result = mv.match(context, request)\n        self.assertEqual(result, view)\n\n    def test_permitted_no_views(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv.__permitted__, context, request)\n\n    def test_permitted_no_match_with__permitted__(self):\n        mv = self._makeOne()\n        def view(context, request):\n            \"\"\" \"\"\"\n        mv.views = [(100, view, None)]\n        self.assertEqual(mv.__permitted__(None, None), True)\n\n    def test_permitted(self):\n        mv = self._makeOne()\n        def view(context, request):\n            \"\"\" \"\"\"\n        def permitted(context, request):\n            return False\n        view.__permitted__ = permitted\n        mv.views = [(100, view, None)]\n        context = DummyContext()\n        request = DummyRequest()\n        result = mv.__permitted__(context, request)\n        self.assertEqual(result, False)\n\n    def test__call__not_found(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv, context, request)\n\n    def test___call__intermediate_not_found(self):\n        from pyramid.exceptions import PredicateMismatch\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        expected_response = DummyResponse()\n        def view1(context, request):\n            raise PredicateMismatch\n        def view2(context, request):\n            return expected_response\n        mv.views = [(100, view1, None), (99, view2, None)]\n        response = mv(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test___call__raise_not_found_isnt_interpreted_as_pred_mismatch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        def view1(context, request):\n            raise  HTTPNotFound\n        def view2(context, request):\n            \"\"\" \"\"\"\n        mv.views = [(100, view1, None), (99, view2, None)]\n        self.assertRaises(HTTPNotFound, mv, context, request)\n\n    def test___call__(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        expected_response = DummyResponse()\n        def view(context, request):\n            return expected_response\n        mv.views = [(100, view, None)]\n        response = mv(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test__call_permissive__not_found(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv, context, request)\n\n    def test___call_permissive_has_call_permissive(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        expected_response = DummyResponse()\n        def view(context, request):\n            \"\"\" \"\"\"\n        def permissive(context, request):\n            return expected_response\n        view.__call_permissive__ = permissive\n        mv.views = [(100, view, None)]\n        response = mv.__call_permissive__(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test___call_permissive_has_no_call_permissive(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        expected_response = DummyResponse()\n        def view(context, request):\n            return expected_response\n        mv.views = [(100, view, None)]\n        response = mv.__call_permissive__(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test__call__with_accept_match(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/xml')\n        expected_response = DummyResponse()\n        def view(context, request):\n            return expected_response\n        mv.views = [(100, None)]\n        mv.media_views['text/xml'] = [(100, view, None)]\n        mv.accepts = ['text/xml']\n        response = mv(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test__call__with_accept_miss(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.accept = DummyAccept('text/plain', 'text/html')\n        expected_response = DummyResponse()\n        def view(context, request):\n            return expected_response\n        mv.views = [(100, view, None)]\n        mv.media_views['text/xml'] = [(100, None, None)]\n        mv.accepts = ['text/xml']\n        response = mv(context, request)\n        self.assertEqual(response, expected_response)\n\nclass TestViewDeriver(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n\n    def tearDown(self):\n        self.config = None\n\n    def _makeOne(self, **kw):\n        kw['registry'] = self.config.registry\n        from pyramid.config.views import ViewDeriver\n        return ViewDeriver(**kw)\n\n    def _makeRequest(self):\n        request = DummyRequest()\n        request.registry = self.config.registry\n        return request\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n        logger = DummyLogger()\n        self.config.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSecurityPolicy(self, permissive):\n        from pyramid.interfaces import IAuthenticationPolicy\n        from pyramid.interfaces import IAuthorizationPolicy\n        policy = DummySecurityPolicy(permissive)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n\n    def test_function_returns_non_adaptable(self):\n        def view(request):\n            return None\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n            self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable function '\n                'pyramid.tests.test_config.test_views.view into a response '\n                'object. The value returned was None. You may have forgotten '\n                'to return a value from the view callable.'\n                )\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_function_returns_non_adaptable_dict(self):\n        def view(request):\n            return {'a':1}\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n            self.assertEqual(\n                e.args[0],\n                \"Could not convert return value of the view callable function \"\n                \"pyramid.tests.test_config.test_views.view into a response \"\n                \"object. The value returned was {'a': 1}. You may have \"\n                \"forgotten to define a renderer in the view configuration.\"\n                )\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_instance_returns_non_adaptable(self):\n        class AView(object):\n            def __call__(self, request):\n                return None\n        view = AView()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n            msg = e.args[0]\n            self.assertTrue(msg.startswith(\n                'Could not convert return value of the view callable object '\n                '<pyramid.tests.test_config.test_views.'))\n            self.assertTrue(msg.endswith(\n                '> into a response object. The value returned was None. You '\n                'may have forgotten to return a value from the view callable.'))\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_function_returns_true_Response_no_renderer(self):\n        from pyramid.response import Response\n        r = Response('Hello')\n        def view(request):\n            return r\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        response = result(None, None)\n        self.assertEqual(response, r)\n\n    def test_function_returns_true_Response_with_renderer(self):\n        from pyramid.response import Response\n        r = Response('Hello')\n        def view(request):\n            return r\n        renderer = object()\n        deriver = self._makeOne(renderer=renderer)\n        result = deriver(view)\n        self.assertFalse(result is view)\n        response = result(None, None)\n        self.assertEqual(response, r)\n\n    def test_requestonly_default_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return None\n        deriver = self._makeOne()\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n            result(None, request)\n        except ValueError as e:\n            self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable '\n                'method __call__ of '\n                'class pyramid.tests.test_config.test_views.AView into a '\n                'response object. The value returned was None. You may have '\n                'forgotten to return a value from the view callable.'\n                )\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_requestonly_nondefault_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def theviewmethod(self):\n                return None\n        deriver = self._makeOne(attr='theviewmethod')\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n            result(None, request)\n        except ValueError as e:\n            self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable '\n                'method theviewmethod of '\n                'class pyramid.tests.test_config.test_views.AView into a '\n                'response object. The value returned was None. You may have '\n                'forgotten to return a value from the view callable.'\n                )\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_requestonly_function(self):\n        response = DummyResponse()\n        def view(request):\n            return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None), response)\n\n    def test_requestonly_function_with_renderer(self):\n        response = DummyResponse()\n        class moo(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, 'OK')\n                self.assertEqual(view_inst, view)\n                self.assertEqual(ctx, context)\n                return response\n        def view(request):\n            return 'OK'\n        deriver = self._makeOne(renderer=moo())\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_requestonly_function_with_renderer_request_override(self):\n        def moo(info):\n            def inner(value, system):\n                self.assertEqual(value, 'OK')\n                self.assertEqual(system['request'], request)\n                self.assertEqual(system['context'], context)\n                return b'moo'\n            return inner\n        def view(request):\n            return 'OK'\n        self.config.add_renderer('moo', moo)\n        deriver = self._makeOne(renderer='string')\n        result = deriver(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        request.override_renderer = 'moo'\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request).body, b'moo')\n\n    def test_requestonly_function_with_renderer_request_has_view(self):\n        response = DummyResponse()\n        class moo(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, 'OK')\n                self.assertEqual(view_inst, 'view')\n                self.assertEqual(ctx, context)\n                return response\n        def view(request):\n            return 'OK'\n        deriver = self._makeOne(renderer=moo())\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        request = self._makeRequest()\n        request.__view__ = 'view'\n        context = testing.DummyResource()\n        r = result(context, request)\n        self.assertEqual(r, response)\n        self.assertFalse(hasattr(request, '__view__'))\n\n    def test_class_without_attr(self):\n        response = DummyResponse()\n        class View(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(View)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, View)\n\n    def test_class_with_attr(self):\n        response = DummyResponse()\n        class View(object):\n            def __init__(self, request):\n                pass\n            def another(self):\n                return response\n        deriver = self._makeOne(attr='another')\n        result = deriver(View)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, View)\n\n    def test_as_function_context_and_request(self):\n        def view(context, request):\n            return 'OK'\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertTrue(result.__wraps__ is view)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        self.assertEqual(view(None, None), 'OK')\n\n    def test_as_function_requestonly(self):\n        response = DummyResponse()\n        def view(request):\n            return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        self.assertEqual(result(None, None), response)\n\n    def test_as_newstyle_class_context_and_request(self):\n        response = DummyResponse()\n        class view(object):\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_as_newstyle_class_requestonly(self):\n        response = DummyResponse()\n        class view(object):\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_as_oldstyle_class_context_and_request(self):\n        response = DummyResponse()\n        class view:\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_as_oldstyle_class_requestonly(self):\n        response = DummyResponse()\n        class view:\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_as_instance_context_and_request(self):\n        response = DummyResponse()\n        class View:\n            def __call__(self, context, request):\n                return response\n        view = View()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertTrue(result.__wraps__ is view)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        self.assertEqual(result(None, None), response)\n\n    def test_as_instance_requestonly(self):\n        response = DummyResponse()\n        class View:\n            def __call__(self, request):\n                return response\n        view = View()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertTrue('test_views' in result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        self.assertEqual(result(None, None), response)\n\n    def test_with_debug_authorization_no_authpol(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): Allowed \"\n                         \"(no authorization policy in use)\")\n\n    def test_with_debug_authorization_authn_policy_no_authz_policy(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(debug_authorization=True)\n        from pyramid.interfaces import IAuthenticationPolicy\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        logger = self._registerLogger()\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): Allowed \"\n                         \"(no authorization policy in use)\")\n\n    def test_with_debug_authorization_authz_policy_no_authn_policy(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(debug_authorization=True)\n        from pyramid.interfaces import IAuthorizationPolicy\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n        logger = self._registerLogger()\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): Allowed \"\n                         \"(no authorization policy in use)\")\n\n    def test_with_debug_authorization_no_permission(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        self._registerSecurityPolicy(True)\n        logger = self._registerLogger()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): Allowed (\"\n                         \"no permission registered)\")\n\n    def test_debug_auth_permission_authpol_permitted(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        self._registerSecurityPolicy(True)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertEqual(result.__call_permissive__.__wraps__, view)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): True\")\n\n    def test_debug_auth_permission_authpol_permitted_no_request(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        self._registerSecurityPolicy(True)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertEqual(result.__call_permissive__.__wraps__, view)\n        self.assertEqual(result(None, None), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url None (view name \"\n                         \"None against context None): True\")\n\n    def test_debug_auth_permission_authpol_denied(self):\n        from pyramid.httpexceptions import HTTPForbidden\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        self._registerSecurityPolicy(False)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertEqual(result.__call_permissive__.__wraps__, view)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertRaises(HTTPForbidden, result, None, request)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): False\")\n\n    def test_debug_auth_permission_authpol_denied2(self):\n        view = lambda *arg: 'OK'\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        self._registerLogger()\n        self._registerSecurityPolicy(False)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        permitted = result.__permitted__(None, None)\n        self.assertEqual(permitted, False)\n\n    def test_debug_auth_permission_authpol_overridden(self):\n        from pyramid.security import NO_PERMISSION_REQUIRED\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        self._registerSecurityPolicy(False)\n        deriver = self._makeOne(permission=NO_PERMISSION_REQUIRED)\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): \"\n                         \"Allowed (NO_PERMISSION_REQUIRED)\")\n\n    def test_secured_view_authn_policy_no_authz_policy(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = {}\n        from pyramid.interfaces import IAuthenticationPolicy\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n\n    def test_secured_view_authz_policy_no_authn_policy(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = {}\n        from pyramid.interfaces import IAuthorizationPolicy\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n\n    def test_secured_view_raises_forbidden_no_name(self):\n        from pyramid.interfaces import IAuthenticationPolicy\n        from pyramid.interfaces import IAuthorizationPolicy\n        from pyramid.httpexceptions import HTTPForbidden\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = {}\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        try:\n            result(None, request)\n        except HTTPForbidden as e:\n            self.assertEqual(e.message,\n                             'Unauthorized: <lambda> failed permission check')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_secured_view_raises_forbidden_with_name(self):\n        from pyramid.interfaces import IAuthenticationPolicy\n        from pyramid.interfaces import IAuthorizationPolicy\n        from pyramid.httpexceptions import HTTPForbidden\n        def myview(request): pass\n        self.config.registry.settings = {}\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n        deriver = self._makeOne(permission='view')\n        result = deriver(myview)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        try:\n            result(None, request)\n        except HTTPForbidden as e:\n            self.assertEqual(e.message,\n                             'Unauthorized: myview failed permission check')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_predicate_mismatch_view_has_no_name(self):\n        from pyramid.exceptions import PredicateMismatch\n        response = DummyResponse()\n        view = lambda *arg: response\n        def predicate1(context, request):\n            return False\n        predicate1.text = lambda *arg: 'text'\n        deriver = self._makeOne(predicates=[predicate1])\n        result = deriver(view)\n        request = self._makeRequest()\n        request.method = 'POST'\n        try:\n            result(None, None)\n        except PredicateMismatch as e:\n            self.assertEqual(e.detail,\n                             'predicate mismatch for view <lambda> (text)')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_predicate_mismatch_view_has_name(self):\n        from pyramid.exceptions import PredicateMismatch\n        def myview(request): pass\n        def predicate1(context, request):\n            return False\n        predicate1.text = lambda *arg: 'text'\n        deriver = self._makeOne(predicates=[predicate1])\n        result = deriver(myview)\n        request = self._makeRequest()\n        request.method = 'POST'\n        try:\n            result(None, None)\n        except PredicateMismatch as e:\n            self.assertEqual(e.detail,\n                             'predicate mismatch for view myview (text)')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_predicate_mismatch_exception_has_text_in_detail(self):\n        from pyramid.exceptions import PredicateMismatch\n        def myview(request): pass\n        def predicate1(context, request):\n            return True\n        predicate1.text = lambda *arg: 'pred1'\n        def predicate2(context, request):\n            return False\n        predicate2.text = lambda *arg: 'pred2'\n        deriver = self._makeOne(predicates=[predicate1, predicate2])\n        result = deriver(myview)\n        request = self._makeRequest()\n        request.method = 'POST'\n        try:\n            result(None, None)\n        except PredicateMismatch as e:\n            self.assertEqual(e.detail,\n                             'predicate mismatch for view myview (pred2)')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_with_predicates_all(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        predicates = []\n        def predicate1(context, request):\n            predicates.append(True)\n            return True\n        def predicate2(context, request):\n            predicates.append(True)\n            return True\n        deriver = self._makeOne(predicates=[predicate1, predicate2])\n        result = deriver(view)\n        request = self._makeRequest()\n        request.method = 'POST'\n        next = result(None, None)\n        self.assertEqual(next, response)\n        self.assertEqual(predicates, [True, True])\n\n    def test_with_predicates_checker(self):\n        view = lambda *arg: 'OK'\n        predicates = []\n        def predicate1(context, request):\n            predicates.append(True)\n            return True\n        def predicate2(context, request):\n            predicates.append(True)\n            return True\n        deriver = self._makeOne(predicates=[predicate1, predicate2])\n        result = deriver(view)\n        request = self._makeRequest()\n        request.method = 'POST'\n        next = result.__predicated__(None, None)\n        self.assertEqual(next, True)\n        self.assertEqual(predicates, [True, True])\n\n    def test_with_predicates_notall(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        view = lambda *arg: 'OK'\n        predicates = []\n        def predicate1(context, request):\n            predicates.append(True)\n            return True\n        predicate1.text = lambda *arg: 'text'\n        def predicate2(context, request):\n            predicates.append(True)\n            return False\n        predicate2.text = lambda *arg: 'text'\n        deriver = self._makeOne(predicates=[predicate1, predicate2])\n        result = deriver(view)\n        request = self._makeRequest()\n        request.method = 'POST'\n        self.assertRaises(HTTPNotFound, result, None, None)\n        self.assertEqual(predicates, [True, True])\n\n    def test_with_wrapper_viewname(self):\n        from pyramid.response import Response\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        inner_response = Response('OK')\n        def inner_view(context, request):\n            return inner_response\n        def outer_view(context, request):\n            self.assertEqual(request.wrapped_response, inner_response)\n            self.assertEqual(request.wrapped_body, inner_response.body)\n            self.assertEqual(request.wrapped_view.__original_view__,\n                             inner_view)\n            return Response(b'outer ' + request.wrapped_body)\n        self.config.registry.registerAdapter(\n            outer_view, (IViewClassifier, None, None), IView, 'owrap')\n        deriver = self._makeOne(viewname='inner',\n                                wrapper_viewname='owrap')\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        response = result(None, request)\n        self.assertEqual(response.body, b'outer OK')\n\n    def test_with_wrapper_viewname_notfound(self):\n        from pyramid.response import Response\n        inner_response = Response('OK')\n        def inner_view(context, request):\n            return inner_response\n        deriver = self._makeOne(viewname='inner', wrapper_viewname='owrap')\n        wrapped = deriver(inner_view)\n        request = self._makeRequest()\n        self.assertRaises(ValueError, wrapped, None, request)\n\n    def test_as_newstyle_class_context_and_request_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst.__class__, View)\n                self.assertEqual(ctx, context)\n                return response\n        class View(object):\n            def __init__(self, context, request):\n                pass\n            def index(self):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        result = deriver(View)\n        self.assertFalse(result is View)\n        self.assertEqual(result.__module__, View.__module__)\n        self.assertEqual(result.__doc__, View.__doc__)\n        self.assertEqual(result.__name__, View.__name__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_newstyle_class_requestonly_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst.__class__, View)\n                self.assertEqual(ctx, context)\n                return response\n        class View(object):\n            def __init__(self, request):\n                pass\n            def index(self):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        result = deriver(View)\n        self.assertFalse(result is View)\n        self.assertEqual(result.__module__, View.__module__)\n        self.assertEqual(result.__doc__, View.__doc__)\n        self.assertEqual(result.__name__, View.__name__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_oldstyle_cls_context_request_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst.__class__, View)\n                self.assertEqual(ctx, context)\n                return response\n        class View:\n            def __init__(self, context, request):\n                pass\n            def index(self):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        result = deriver(View)\n        self.assertFalse(result is View)\n        self.assertEqual(result.__module__, View.__module__)\n        self.assertEqual(result.__doc__, View.__doc__)\n        self.assertEqual(result.__name__, View.__name__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_oldstyle_cls_requestonly_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst.__class__, View)\n                self.assertEqual(ctx, context)\n                return response\n        class View:\n            def __init__(self, request):\n                pass\n            def index(self):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        result = deriver(View)\n        self.assertFalse(result is View)\n        self.assertEqual(result.__module__, View.__module__)\n        self.assertEqual(result.__doc__, View.__doc__)\n        self.assertEqual(result.__name__, View.__name__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_instance_context_and_request_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst, view)\n                self.assertEqual(ctx, context)\n                return response\n        class View:\n            def index(self, context, request):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        view = View()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result.__module__, view.__module__)\n        self.assertEqual(result.__doc__, view.__doc__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_instance_requestonly_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst, view)\n                self.assertEqual(ctx, context)\n                return response\n        class View:\n            def index(self, request):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        view = View()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result.__module__, view.__module__)\n        self.assertEqual(result.__doc__, view.__doc__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_with_view_mapper_config_specified(self):\n        response = DummyResponse()\n        class mapper(object):\n            def __init__(self, **kw):\n                self.kw = kw\n            def __call__(self, view):\n                def wrapped(context, request):\n                    return response\n                return wrapped\n        def view(context, request): return 'NOTOK'\n        deriver = self._makeOne(mapper=mapper)\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        self.assertEqual(result(None, None), response)\n\n    def test_with_view_mapper_view_specified(self):\n        from pyramid.response import Response\n        response = Response()\n        def mapper(**kw):\n            def inner(view):\n                def superinner(context, request):\n                    self.assertEqual(request, None)\n                    return response\n                return superinner\n            return inner\n        def view(context, request): return 'NOTOK'\n        view.__view_mapper__ = mapper\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        self.assertEqual(result(None, None), response)\n\n    def test_with_view_mapper_default_mapper_specified(self):\n        from pyramid.response import Response\n        response = Response()\n        def mapper(**kw):\n            def inner(view):\n                def superinner(context, request):\n                    self.assertEqual(request, None)\n                    return  response\n                return superinner\n            return inner\n        self.config.set_view_mapper(mapper)\n        def view(context, request): return 'NOTOK'\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        self.assertEqual(result(None, None), response)\n\n    def test_attr_wrapped_view_branching_default_phash(self):\n        from pyramid.config.util import DEFAULT_PHASH\n        def view(context, request): pass\n        deriver = self._makeOne(phash=DEFAULT_PHASH)\n        result = deriver(view)\n        self.assertEqual(result.__wraps__, view)\n\n    def test_attr_wrapped_view_branching_nondefault_phash(self):\n        def view(context, request): pass\n        deriver = self._makeOne(phash='nondefault')\n        result = deriver(view)\n        self.assertNotEqual(result, view)\n\n    def test_http_cached_view_integer(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=3600)\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(hours=1)\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n        self.assertEqual(headers['Cache-Control'], 'max-age=3600')\n\n    def test_http_cached_view_timedelta(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=datetime.timedelta(hours=1))\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(hours=1)\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n        self.assertEqual(headers['Cache-Control'], 'max-age=3600')\n\n    def test_http_cached_view_tuple(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=(3600, {'public':True}))\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(hours=1)\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n        self.assertEqual(headers['Cache-Control'], 'max-age=3600, public')\n\n    def test_http_cached_view_tuple_seconds_None(self):\n        from pyramid.response import Response\n        response = Response('OK')\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=(None, {'public':True}))\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        self.assertFalse('Expires' in headers)\n        self.assertEqual(headers['Cache-Control'], 'public')\n\n    def test_http_cached_view_prevent_auto_set(self):\n        from pyramid.response import Response\n        response = Response()\n        response.cache_control.prevent_auto = True\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=3600)\n        result = deriver(inner_view)\n        request = self._makeRequest()\n        result = result(None, request)\n        self.assertEqual(result, response) # doesn't blow up\n        headers = dict(result.headerlist)\n        self.assertFalse('Expires' in headers)\n        self.assertFalse('Cache-Control' in headers)\n\n    def test_http_cached_prevent_http_cache_in_settings(self):\n        self.config.registry.settings['prevent_http_cache'] = True\n        from pyramid.response import Response\n        response = Response()\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=3600)\n        result = deriver(inner_view)\n        request = self._makeRequest()\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        self.assertFalse('Expires' in headers)\n        self.assertFalse('Cache-Control' in headers)\n\n    def test_http_cached_view_bad_tuple(self):\n        deriver = self._makeOne(http_cache=(None,))\n        def view(request): pass\n        self.assertRaises(ConfigurationError, deriver, view)\n\nclass TestDefaultViewMapper(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        del self.registry\n        testing.tearDown()\n\n    def _makeOne(self, **kw):\n        from pyramid.config.views import DefaultViewMapper\n        kw['registry'] = self.registry\n        return DefaultViewMapper(**kw)\n\n    def _makeRequest(self):\n        request = DummyRequest()\n        request.registry = self.registry\n        return request\n\n    def test_view_as_function_context_and_request(self):\n        def view(context, request):\n            return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertTrue(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test__view_as_function_with_attr(self):\n        def view(context, request):\n            \"\"\" \"\"\"\n        mapper = self._makeOne(attr='__name__')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertRaises(TypeError, result, None, request)\n\n    def test_view_as_function_requestonly(self):\n        def view(request):\n            return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_function_requestonly_with_attr(self):\n        def view(request):\n            \"\"\" \"\"\"\n        mapper = self._makeOne(attr='__name__')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertRaises(TypeError, result, None, request)\n\n    def test_view_as_newstyle_class_context_and_request(self):\n        class view(object):\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_newstyle_class_context_and_request_with_attr(self):\n        class view(object):\n            def __init__(self, context, request):\n                pass\n            def index(self):\n                return 'OK'\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_newstyle_class_requestonly(self):\n        class view(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_newstyle_class_requestonly_with_attr(self):\n        class view(object):\n            def __init__(self, request):\n                pass\n            def index(self):\n                return 'OK'\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_oldstyle_class_context_and_request(self):\n        class view:\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_oldstyle_class_context_and_request_with_attr(self):\n        class view:\n            def __init__(self, context, request):\n                pass\n            def index(self):\n                return 'OK'\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_oldstyle_class_requestonly(self):\n        class view:\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_oldstyle_class_requestonly_with_attr(self):\n        class view:\n            def __init__(self, request):\n                pass\n            def index(self):\n                return 'OK'\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_instance_context_and_request(self):\n        class View:\n            def __call__(self, context, request):\n                return 'OK'\n        view = View()\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertTrue(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_instance_context_and_request_and_attr(self):\n        class View:\n            def index(self, context, request):\n                return 'OK'\n        view = View()\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_instance_requestonly(self):\n        class View:\n            def __call__(self, request):\n                return 'OK'\n        view = View()\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_instance_requestonly_with_attr(self):\n        class View:\n            def index(self, request):\n                return 'OK'\n        view = View()\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\nclass Test_preserve_view_attrs(unittest.TestCase):\n    def _callFUT(self, view, wrapped_view):\n        from pyramid.config.views import preserve_view_attrs\n        return preserve_view_attrs(view, wrapped_view)\n\n    def test_it_same(self):\n        def view(context, request):\n            \"\"\" \"\"\"\n        result = self._callFUT(view, view)\n        self.assertTrue(result is view)\n\n    def test_it_view_is_None(self):\n        def view(context, request):\n            \"\"\" \"\"\"\n        result = self._callFUT(None, view)\n        self.assertTrue(result is view)\n\n    def test_it_different_with_existing_original_view(self):\n        def view1(context, request): pass\n        view1.__original_view__ = 'abc'\n        def view2(context, request): pass\n        result = self._callFUT(view1, view2)\n        self.assertEqual(result.__original_view__, 'abc')\n        self.assertFalse(result is view1)\n\n    def test_it_different(self):\n        class DummyView1:\n            \"\"\" 1 \"\"\"\n            __name__ = '1'\n            __module__ = '1'\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n            def __call_permissive__(self, context, request):\n                \"\"\" \"\"\"\n            def __predicated__(self, context, request):\n                \"\"\" \"\"\"\n            def __permitted__(self, context, request):\n                \"\"\" \"\"\"\n        class DummyView2:\n            \"\"\" 2 \"\"\"\n            __name__ = '2'\n            __module__ = '2'\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n            def __call_permissive__(self, context, request):\n                \"\"\" \"\"\"\n            def __predicated__(self, context, request):\n                \"\"\" \"\"\"\n            def __permitted__(self, context, request):\n                \"\"\" \"\"\"\n        view1 = DummyView1()\n        view2 = DummyView2()\n        result = self._callFUT(view2, view1)\n        self.assertEqual(result, view1)\n        self.assertTrue(view1.__original_view__ is view2)\n        self.assertTrue(view1.__doc__ is view2.__doc__)\n        self.assertTrue(view1.__module__ is view2.__module__)\n        self.assertTrue(view1.__name__ is view2.__name__)\n        self.assertTrue(getattr(view1.__call_permissive__, im_func) is\n                        getattr(view2.__call_permissive__, im_func))\n        self.assertTrue(getattr(view1.__permitted__, im_func) is\n                        getattr(view2.__permitted__, im_func))\n        self.assertTrue(getattr(view1.__predicated__, im_func) is\n                        getattr(view2.__predicated__, im_func))\n\n\nclass TestStaticURLInfo(unittest.TestCase):\n    def _getTargetClass(self):\n        from pyramid.config.views import StaticURLInfo\n        return StaticURLInfo\n\n    def _makeOne(self):\n        return self._getTargetClass()()\n\n    def _makeConfig(self, registrations=None):\n        config = DummyConfig()\n        registry = DummyRegistry()\n        if registrations is not None:\n            registry._static_url_registrations = registrations\n        config.registry = registry\n        return config\n\n    def _makeRequest(self):\n        request = DummyRequest()\n        request.registry = DummyRegistry()\n        return request\n\n    def _assertRegistrations(self, config, expected):\n        self.assertEqual(config.registry._static_url_registrations, expected)\n\n    def test_verifyClass(self):\n        from pyramid.interfaces import IStaticURLInfo\n        from zope.interface.verify import verifyClass\n        verifyClass(IStaticURLInfo, self._getTargetClass())\n\n    def test_verifyObject(self):\n        from pyramid.interfaces import IStaticURLInfo\n        from zope.interface.verify import verifyObject\n        verifyObject(IStaticURLInfo, self._makeOne())\n\n    def test_generate_missing(self):\n        inst = self._makeOne()\n        request = self._makeRequest()\n        self.assertRaises(ValueError, inst.generate, 'path', request)\n\n    def test_generate_registration_miss(self):\n        inst = self._makeOne()\n        registrations = [(None, 'spec', 'route_name'),\n                         ('http://example.com/foo/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        result = inst.generate('package:path/abc', request)\n        self.assertEqual(result, 'http://example.com/foo/abc')\n\n    def test_generate_registration_no_registry_on_request(self):\n        inst = self._makeOne()\n        registrations = [('http://example.com/foo/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        del request.registry\n        result = inst.generate('package:path/abc', request)\n        self.assertEqual(result, 'http://example.com/foo/abc')\n\n    def test_generate_slash_in_name1(self):\n        inst = self._makeOne()\n        registrations = [('http://example.com/foo/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        result = inst.generate('package:path/abc', request)\n        self.assertEqual(result, 'http://example.com/foo/abc')\n\n    def test_generate_slash_in_name2(self):\n        inst = self._makeOne()\n        registrations = [('http://example.com/foo/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        result = inst.generate('package:path/', request)\n        self.assertEqual(result, 'http://example.com/foo/')\n\n    def test_generate_quoting(self):\n        config = testing.setUp()\n        try:\n            config.add_static_view('images', path='mypkg:templates')\n            inst = self._makeOne()\n            request = testing.DummyRequest()\n            request.registry = config.registry\n            result = inst.generate('mypkg:templates/foo%2Fbar', request)\n            self.assertEqual(result, 'http://example.com/images/foo%252Fbar')\n        finally:\n            testing.tearDown()\n\n    def test_generate_route_url(self):\n        inst = self._makeOne()\n        registrations = [(None, 'package:path/', '__viewname/')]\n        inst._get_registrations = lambda *x: registrations\n        def route_url(n, **kw):\n            self.assertEqual(n, '__viewname/')\n            self.assertEqual(kw, {'subpath':'abc', 'a':1})\n            return 'url'\n        request = self._makeRequest()\n        request.route_url = route_url\n        result = inst.generate('package:path/abc', request, a=1)\n        self.assertEqual(result, 'url')\n\n    def test_generate_url_unquoted_local(self):\n        inst = self._makeOne()\n        registrations = [(None, 'package:path/', '__viewname/')]\n        inst._get_registrations = lambda *x: registrations\n        def route_url(n, **kw):\n            self.assertEqual(n, '__viewname/')\n            self.assertEqual(kw, {'subpath':'abc def', 'a':1})\n            return 'url'\n        request = self._makeRequest()\n        request.route_url = route_url\n        result = inst.generate('package:path/abc def', request, a=1)\n        self.assertEqual(result, 'url')\n\n    def test_generate_url_quoted_remote(self):\n        inst = self._makeOne()\n        registrations = [('http://example.com/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        result = inst.generate('package:path/abc def', request, a=1)\n        self.assertEqual(result, 'http://example.com/abc%20def')\n\n    def test_add_already_exists(self):\n        inst = self._makeOne()\n        config = self._makeConfig(\n            [('http://example.com/', 'package:path/', None)])\n        inst.add(config, 'http://example.com', 'anotherpackage:path')\n        expected = [('http://example.com/',  'anotherpackage:path/', None)]\n        self._assertRegistrations(config, expected)\n\n    def test_add_url_withendslash(self):\n        inst = self._makeOne()\n        config = self._makeConfig()\n        inst.add(config, 'http://example.com/', 'anotherpackage:path')\n        expected = [('http://example.com/', 'anotherpackage:path/', None)]\n        self._assertRegistrations(config, expected)\n\n    def test_add_url_noendslash(self):\n        inst = self._makeOne()\n        config = self._makeConfig()\n        inst.add(config, 'http://example.com', 'anotherpackage:path')\n        expected = [('http://example.com/', 'anotherpackage:path/', None)]\n        self._assertRegistrations(config, expected)\n\n    def test_add_url_noscheme(self):\n        inst = self._makeOne()\n        config = self._makeConfig()\n        inst.add(config, '//example.com', 'anotherpackage:path')\n        expected = [('//example.com/', 'anotherpackage:path/', None)]\n        self._assertRegistrations(config, expected)\n\n    def test_add_viewname(self):\n        from pyramid.security import NO_PERMISSION_REQUIRED\n        from pyramid.static import static_view\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1)\n        expected = [(None, 'anotherpackage:path/', '__view/')]\n        self._assertRegistrations(config, expected)\n        self.assertEqual(config.route_args, ('__view/', 'view/*subpath'))\n        self.assertEqual(config.view_kw['permission'], NO_PERMISSION_REQUIRED)\n        self.assertEqual(config.view_kw['view'].__class__, static_view)\n\n    def test_add_viewname_with_route_prefix(self):\n        config = self._makeConfig()\n        config.route_prefix = '/abc'\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path',)\n        expected = [(None, 'anotherpackage:path/', '__/abc/view/')]\n        self._assertRegistrations(config, expected)\n        self.assertEqual(config.route_args, ('__/abc/view/', 'view/*subpath'))\n\n    def test_add_viewname_with_permission(self):\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1,\n                 permission='abc')\n        self.assertEqual(config.view_kw['permission'], 'abc')\n\n    def test_add_viewname_with_context(self):\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1,\n                 context=DummyContext)\n        self.assertEqual(config.view_kw['context'], DummyContext)\n        \n    def test_add_viewname_with_for_(self):\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1,\n                 for_=DummyContext)\n        self.assertEqual(config.view_kw['context'], DummyContext)\n\n    def test_add_viewname_with_renderer(self):\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1,\n                 renderer='mypackage:templates/index.pt')\n        self.assertEqual(config.view_kw['renderer'],\n                         'mypackage:templates/index.pt')\n\nclass Test_view_description(unittest.TestCase):\n    def _callFUT(self, view):\n        from pyramid.config.views import view_description\n        return view_description(view)\n\n    def test_with_text(self):\n        def view(): pass\n        view.__text__ = 'some text'\n        result = self._callFUT(view)\n        self.assertEqual(result, 'some text')\n\n    def test_without_text(self):\n        def view(): pass\n        result = self._callFUT(view)\n        self.assertEqual(result,\n                         'function pyramid.tests.test_config.test_views.view')\n\n\nclass DummyRegistry:\n    pass\n\nfrom zope.interface import implementer\nfrom pyramid.interfaces import IResponse\n@implementer(IResponse)\nclass DummyResponse(object):\n    content_type = None\n    default_content_type = None\n    body = None\n\nclass DummyRequest:\n    subpath = ()\n    matchdict = None\n\n    def __init__(self, environ=None):\n        if environ is None:\n            environ = {}\n        self.environ = environ\n        self.params = {}\n        self.cookies = {}\n        self.response = DummyResponse()\n\nclass DummyContext:\n    pass\n\nclass DummyAccept(object):\n    def __init__(self, *matches):\n        self.matches = list(matches)\n\n    def best_match(self, offered):\n        if self.matches:\n            for match in self.matches:\n                if match in offered:\n                    self.matches.remove(match)\n                    return match\n    def __contains__(self, val):\n        return val in self.matches\n\nclass DummyLogger:\n    def __init__(self):\n        self.messages = []\n    def info(self, msg):\n        self.messages.append(msg)\n    warn = info\n    debug = info\n\nclass DummySecurityPolicy:\n    def __init__(self, permitted=True):\n        self.permitted = permitted\n\n    def effective_principals(self, request):\n        return []\n\n    def permits(self, context, principals, permission):\n        return self.permitted\n\nclass DummyConfig:\n    route_prefix = ''\n    def add_route(self, *args, **kw):\n        self.route_args = args\n        self.route_kw = kw\n\n    def add_view(self, *args, **kw):\n        self.view_args = args\n        self.view_kw = kw\n\n    def action(self, discriminator, callable, introspectables=()):\n        callable()\n\n    def introspectable(self, *arg):\n        return {}\n\nfrom zope.interface import implementer\nfrom pyramid.interfaces import IMultiView\n@implementer(IMultiView)\nclass DummyMultiView:\n    def __init__(self):\n        self.views = []\n        self.name = 'name'\n    def add(self, view, order, accept=None, phash=None):\n        self.views.append((view, accept, phash))\n    def __call__(self, context, request):\n        return 'OK1'\n    def __permitted__(self, context, request):\n        \"\"\" \"\"\"\n\ndef parse_httpdate(s):\n    import datetime\n    # cannot use %Z, must use literal GMT; Jython honors timezone\n    # but CPython does not\n    return datetime.datetime.strptime(s, \"%a, %d %b %Y %H:%M:%S GMT\")\n\ndef assert_similar_datetime(one, two):\n    for attr in ('year', 'month', 'day', 'hour', 'minute'):\n        one_attr = getattr(one, attr)\n        two_attr = getattr(two, attr)\n        if not one_attr == two_attr: # pragma: no cover\n            raise AssertionError('%r != %r in %s' % (one_attr, two_attr, attr))\n\nclass DummyStaticURLInfo:\n    def __init__(self):\n        self.added = []\n\n    def add(self, config, name, spec, **kw):\n        self.added.append((config, name, spec, kw))\n\nclass DummyViewDefaultsClass(object):\n    __view_defaults__ = {\n        'containment':'pyramid.tests.test_config.IDummy'\n        }\n    def __init__(self, request):\n        pass\n    def __call__(self):\n        return 'OK'\n\nclass DummyPredicate(object):\n    def __init__(self, val, config):\n        self.val = val\n\n    def text(self):\n        return 'dummy'\n\n    phash = text\n\nclass DummyIntrospector(object):\n    def __init__(self, getval=None):\n        self.related = []\n        self.introspectables = []\n        self.getval = getval\n    def add(self, introspectable):\n        self.introspectables.append(introspectable)\n    def get(self, name, discrim):\n        return self.getval\n    def relate(self, a, b):\n        self.related.append((a, b))\n",
            "new_file_content": "import unittest\nfrom pyramid import testing\n\nfrom pyramid.tests.test_config import IDummy\n\nfrom pyramid.tests.test_config import dummy_view\n\nfrom pyramid.compat import (\n    im_func,\n    text_,\n    )\nfrom pyramid.exceptions import ConfigurationError\nfrom pyramid.exceptions import ConfigurationExecutionError\nfrom pyramid.exceptions import ConfigurationConflictError\n\nclass TestViewsConfigurationMixin(unittest.TestCase):\n    def _makeOne(self, *arg, **kw):\n        from pyramid.config import Configurator\n        config = Configurator(*arg, **kw)\n        return config\n\n    def _getViewCallable(self, config, ctx_iface=None, request_iface=None,\n                         name='', exception_view=False):\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        if exception_view:\n            classifier = IExceptionViewClassifier\n        else:\n            classifier = IViewClassifier\n        if ctx_iface is None:\n            ctx_iface = Interface\n        if request_iface is None:\n            request_iface = IRequest\n        return config.registry.adapters.lookup(\n            (classifier, request_iface, ctx_iface), IView, name=name,\n            default=None)\n\n    def _registerRenderer(self, config, name='.txt'):\n        from pyramid.interfaces import IRendererFactory\n        class Renderer:\n            def __init__(self, info):\n                self.__class__.info = info\n            def __call__(self, *arg):\n                return b'Hello!'\n        config.registry.registerUtility(Renderer, IRendererFactory, name=name)\n        return Renderer\n\n    def _makeRequest(self, config):\n        request = DummyRequest()\n        request.registry = config.registry\n        return request\n\n    def _assertNotFound(self, wrapper, *arg):\n        from pyramid.httpexceptions import HTTPNotFound\n        self.assertRaises(HTTPNotFound, wrapper, *arg)\n\n    def _getRouteRequestIface(self, config, name):\n        from pyramid.interfaces import IRouteRequest\n        iface = config.registry.getUtility(IRouteRequest, name)\n        return iface\n\n    def _assertRoute(self, config, name, path, num_predicates=0):\n        from pyramid.interfaces import IRoutesMapper\n        mapper = config.registry.getUtility(IRoutesMapper)\n        routes = mapper.get_routes()\n        route = routes[0]\n        self.assertEqual(len(routes), 1)\n        self.assertEqual(route.name, name)\n        self.assertEqual(route.path, path)\n        self.assertEqual(len(routes[0].predicates), num_predicates)\n        return route\n\n    def test_add_view_view_callable_None_no_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError, config.add_view)\n\n    def test_add_view_with_request_type_and_route_name(self):\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        self.assertRaises(ConfigurationError, config.add_view, view, '', None,\n                          None, True, True)\n\n    def test_add_view_with_request_type(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        from pyramid.interfaces import IRequest\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view,\n                        request_type='pyramid.interfaces.IRequest',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = DummyRequest()\n        self._assertNotFound(wrapper, None, request)\n        directlyProvides(request, IRequest)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_view_callable_None_with_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self._registerRenderer(config, name='dummy')\n        config.add_view(renderer='dummy')\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n\n    def test_add_view_with_tmpl_renderer_factory_introspector_missing(self):\n        config = self._makeOne(autocommit=True)\n        config.introspection = False\n        config.introspector = None\n        config.add_view(renderer='dummy.pt')\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n        \n    def test_add_view_with_tmpl_renderer_factory_no_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector()\n        config.introspector = introspector\n        config.add_view(renderer='dummy.pt')\n        self.assertFalse(('renderer factories', '.pt') in\n                         introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n\n    def test_add_view_with_tmpl_renderer_factory_with_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector(True)\n        config.introspector = introspector\n        def dummy_factory(helper):\n            return lambda val, system_vals: 'Hello!'\n        config.add_renderer('.pt', dummy_factory)\n        config.add_view(renderer='dummy.pt')\n        self.assertTrue(\n            ('renderer factories', '.pt') in introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n        \n    def test_add_view_wrapped_view_is_decorated(self):\n        def view(request): # request-only wrapper\n            \"\"\" \"\"\"\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper.__module__, view.__module__)\n        self.assertEqual(wrapper.__name__, view.__name__)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        self.assertEqual(wrapper.__discriminator__(None, None).resolve()[0],\n                         'view')\n\n    def test_add_view_view_callable_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        config.add_view(view='pyramid.tests.test_config.dummy_view',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_function_callable(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_function_callable_requestonly(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, name='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name='abc')\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name_unicode(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        name = text_(b'La Pe\\xc3\\xb1a', 'utf-8')\n        config.add_view(view=view, name=name, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name=name)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper(fn):\n            def inner(context, request):\n                return fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=view_wrapper,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator_tuple(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper1(fn):\n            def inner(context, request):\n                return 'wrapped1' + fn(context, request)\n            return inner\n        def view_wrapper2(fn):\n            def inner(context, request):\n                return 'wrapped2' + fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=(view_wrapper2, view_wrapper1),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'wrapped2wrapped1OK')\n\n    def test_add_view_with_http_cache(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return response\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, http_cache=(86400, {'public':True}))\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        request = testing.DummyRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(days=1)\n        result = wrapper(None, request)\n        self.assertEqual(result, response)\n        headers = dict(response.headerlist)\n        self.assertEqual(headers['Cache-Control'], 'max-age=86400, public')\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n\n    def test_add_view_as_instance(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, context, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instance_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_oldstyle_class(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, context, request):\n                self.context = context\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_as_oldstyle_class_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, request):\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_context_as_class(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_iface(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context='pyramid.tests.test_config.IDummy',\n                        view=view,  renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for__as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_='pyramid.tests.test_config.IDummy',\n                        view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_class(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_iface(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_trumps_for(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        class Foo:\n            pass\n        config.add_view(context=IDummy, for_=Foo, view=view,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_exception_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_mixed_case_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/HTML', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.media_views.items()),1)\n        self.assertFalse('text/HTML' in wrapper.media_views)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_views_with_accept_multiview_replaces_existing(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(len(wrapper.media_views['text/html']), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_view_exc_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, accept='text/html', context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_multiview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_mulview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_exc_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_multiview_context_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        class ISuper(Interface):\n            pass\n        class ISub(ISuper):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, ISuper), IView, name='')\n        config.add_view(view=view2, for_=ISub, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, ISuper, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n        wrapper = self._getViewCallable(config, ISub, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK2')\n\n    def test_add_view_multiview_exception_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        class Super(Exception):\n            pass\n        class Sub(Super):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Super), IView, name='')\n        config.registry.registerAdapter(\n            view, (IExceptionViewClassifier, IRequest, Super), IView, name='')\n        config.add_view(view=view2, for_=Sub, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, implementedBy(Super), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Super), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n        wrapper = self._getViewCallable(\n            config, implementedBy(Sub), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Sub), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK2')\n\n    def test_add_view_multiview_call_ordering(self):\n        from pyramid.renderers import null_renderer as nr\n        from zope.interface import directlyProvides\n        def view1(context, request): return 'view1'\n        def view2(context, request): return 'view2'\n        def view3(context, request): return 'view3'\n        def view4(context, request): return 'view4'\n        def view5(context, request): return 'view5'\n        def view6(context, request): return 'view6'\n        def view7(context, request): return 'view7'\n        def view8(context, request): return 'view8'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view1, renderer=nr)\n        config.add_view(view=view2, request_method='POST', renderer=nr)\n        config.add_view(view=view3,request_param='param', renderer=nr)\n        config.add_view(view=view4, containment=IDummy, renderer=nr)\n        config.add_view(view=view5, request_method='POST',\n                        request_param='param',  renderer=nr)\n        config.add_view(view=view6, request_method='POST', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view7, request_param='param', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view8, request_method='POST',request_param='param',\n                        containment=IDummy, renderer=nr)\n\n\n        wrapper = self._getViewCallable(config)\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view1')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view2')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {'param':'1'}\n        request.method = 'GET'\n        self.assertEqual(wrapper(ctx, request), 'view3')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view4')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view5')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view6')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view7')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view8')\n\n    def test_add_view_multiview___discriminator__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        class IFoo(Interface):\n            pass\n        class IBar(Interface):\n            pass\n        @implementer(IFoo)\n        class Foo(object):\n            pass\n        @implementer(IBar)\n        class Bar(object):\n            pass\n        foo = Foo()\n        bar = Bar()\n\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IFoo)\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IBar)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        request = self._makeRequest(config)\n        self.assertNotEqual(\n            wrapper.__discriminator__(foo, request),\n            wrapper.__discriminator__(bar, request),\n            )\n\n    def test_add_view_with_template_renderer(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=view, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_default_renderer(self):\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        class moo(object):\n            def __init__(self, *arg, **kw):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'moo'\n        config.add_renderer(None, moo)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'moo')\n\n    def test_add_view_with_template_renderer_no_callable(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=None, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_request_type_as_iface(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        def view(context, request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(request_type=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, None)\n        request = self._makeRequest(config)\n        directlyProvides(request, IDummy)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_request_type_as_noniface(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        self.assertRaises(ConfigurationError,\n                          config.add_view, view, '', None, None, object)\n\n    def test_add_view_with_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        self.assertNotEqual(request_iface, None)\n        wrapper = self._getViewCallable(config, request_iface=request_iface)\n        self.assertNotEqual(wrapper, None)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_nonexistant_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        self.assertRaises(ConfigurationExecutionError, config.commit)\n\n    def test_add_view_with_route_name_exception(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', context=RuntimeError,\n                        renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        wrapper_exc_view = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface, exception_view=True)\n        self.assertNotEqual(wrapper_exc_view, None)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n\n    def test_add_view_with_request_method_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_sequence_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_sequence_conflict(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        config.add_view(view=view, request_method=('GET', 'POST'),\n                        renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_request_method_sequence_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'HEAD'))\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_get_implies_head(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'HEAD'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_param_val_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':'123'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_val_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_xhr_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_xhr_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = False\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, header='Host:a\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_header_noval_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'whatever'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_noval_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NotHost':'whatever'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'1'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_val_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'abc'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_missing(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NoHost':'1'}\n        self.assertRaises(HTTPNotFound, wrapper, None, request)\n\n    def test_add_view_with_accept_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/xml']\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_accept_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/html']\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_containment_true(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_containment_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        self._assertNotFound(wrapper, context, None)\n\n    def test_add_view_with_containment_dottedname(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            containment='pyramid.tests.test_config.IDummy',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_path_info_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, path_info='\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_path_info_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_(b'/foo')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_path_info_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_('/')\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_custom_predicates_match(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return True\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates,\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_custom_predicates_nomatch(self):\n        import warnings\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return False\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_custom_predicate_bests_standard_predicate(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=(pred1,),\n                        renderer=null_renderer)\n            config.add_view(view=view2, request_method='GET',\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_custom_more_preds_first_bests_fewer_preds_last(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', xhr=True,\n                        renderer=null_renderer)\n        config.add_view(view=view2, request_method='GET',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_same_predicates(self):\n        view2 = lambda *arg: 'second'\n        view1 = lambda *arg: 'first'\n        config = self._makeOne()\n        config.add_view(view=view1)\n        config.add_view(view=view2)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, permission='view', renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               default_permission='view',\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_no_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        class DummyPolicy(object): pass # wont be called\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_mapper(self):\n        from pyramid.renderers import null_renderer\n        class Mapper(object):\n            def __init__(self, **kw):\n                self.__class__.kw = kw\n            def __call__(self, view):\n                return view\n        config = self._makeOne(autocommit=True)\n        def view(context, request): return 'OK'\n        config.add_view(view=view, mapper=Mapper, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        self.assertEqual(view(None, None), 'OK')\n        self.assertEqual(Mapper.kw['mapper'], Mapper)\n\n    def test_add_view_with_view_defaults(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_kwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view='pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            'pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_config_and_view_defaults_doesnt_conflict(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IFactory'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        config.commit() # does not raise\n\n    def test_add_view_with_view_config_and_view_defaults_conflicts(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_derive_view_function(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        result = config.derive_view(view, renderer=null_renderer)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne()\n        result = config.derive_view(\n            'pyramid.tests.test_config.dummy_view',\n            renderer=null_renderer)\n        self.assertFalse(result is dummy_view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_with_default_renderer_no_explicit_renderer(self):\n        config = self._makeOne()\n        class moo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return 'moo'\n        config.add_renderer(None, moo)\n        config.commit()\n        def view(request):\n            return 'OK'\n        result = config.derive_view(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None).body, b'moo')\n\n    def test_derive_view_with_default_renderer_with_explicit_renderer(self):\n        class moo(object): pass\n        class foo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'foo'\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        config.add_renderer(None, moo)\n        config.add_renderer('foo', foo)\n        config.commit()\n        result = config.derive_view(view, renderer='foo')\n        self.assertFalse(result is view)\n        request = self._makeRequest(config)\n        self.assertEqual(result(None, request).body, b'foo')\n\n    def test_add_static_view_here_no_utility_registered(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        config = self._makeOne(autocommit=True)\n        config.add_static_view('static', 'files', renderer=null_renderer)\n        request_type = self._getRouteRequestIface(config, '__static/')\n        self._assertRoute(config, '__static/', 'static/*subpath')\n        wrapped = config.registry.adapters.lookup(\n            (IViewClassifier, request_type, Interface), IView, name='')\n        from pyramid.request import Request\n        request = Request.blank('/static/minimal.txt')\n        request.subpath = ('minimal.txt', )\n        result = wrapped(None, request)\n        self.assertEqual(result.status, '200 OK')\n        self.assertTrue(result.body.startswith(b'<div'))\n\n    def test_add_static_view_package_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static',\n                               'pyramid.tests.test_config:files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_package_here_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static', 'files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_absolute(self):\n        import os\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        here = os.path.dirname(__file__)\n        static_path = os.path.join(here, 'files')\n        config.add_static_view('static', static_path)\n        self.assertEqual(info.added,\n                         [(config, 'static', static_path, {})])\n\n    def test_add_forbidden_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        config.add_forbidden_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_forbidden_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_forbidden_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_forbidden_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, name='foo')\n\n    def test_add_forbidden_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, permission='foo')\n\n    def test_add_forbidden_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, context='foo')\n\n    def test_add_forbidden_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, for_='foo')\n\n    def test_add_forbidden_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, http_cache='foo')\n\n    def test_add_forbidden_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPForbidden\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_forbidden_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPForbidden),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_notfound_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: arg\n        config.add_notfound_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, (None, request))\n\n    def test_add_notfound_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_notfound_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_notfound_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, name='foo')\n\n    def test_add_notfound_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, permission='foo')\n\n    def test_add_notfound_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, context='foo')\n\n    def test_add_notfound_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, for_='foo')\n\n    def test_add_notfound_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, http_cache='foo')\n\n    def test_add_notfound_view_append_slash(self):\n        from pyramid.response import Response\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/foo/')\n        def view(request): return Response('OK')\n        config.add_notfound_view(view, renderer=null_renderer,append_slash=True)\n        request = self._makeRequest(config)\n        request.environ['PATH_INFO'] = '/foo'\n        request.query_string = 'a=1&b=2'\n        request.path = '/scriptname/foo'\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result.location, '/scriptname/foo/?a=1&b=2')\n\n    def test_add_notfound_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPNotFound\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_notfound_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPNotFound),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    # Since Python 3 has to be all cool and fancy and different...\n    def _assertBody(self, response, value):\n        from pyramid.compat import text_type\n        if isinstance(value, text_type): # pragma: nocover\n            self.assertEqual(response.text, value)\n        else: # pragma: nocover\n            self.assertEqual(response.body, value)\n\n    def test_add_notfound_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_notfound_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_add_forbidden_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_forbidden_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_set_view_mapper(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        mapper = object()\n        config.set_view_mapper(mapper)\n        result = config.registry.getUtility(IViewMapperFactory)\n        self.assertEqual(result, mapper)\n\n    def test_set_view_mapper_dottedname(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        config.set_view_mapper('pyramid.tests.test_config')\n        result = config.registry.getUtility(IViewMapperFactory)\n        from pyramid.tests import test_config\n        self.assertEqual(result, test_config)\n\nclass Test_requestonly(unittest.TestCase):\n    def _callFUT(self, view, attr=None):\n        from pyramid.config.views import requestonly\n        return requestonly(view, attr=attr)\n\n    def test_defaults(self):\n        def aview(request, a=1, b=2): pass\n        self.assertTrue(self._callFUT(aview))\n\n    def test_otherattr(self):\n        class AView(object):\n            def __init__(self, request, a=1, b=2): pass\n            def bleh(self): pass\n        self.assertTrue(self._callFUT(AView, 'bleh'))\n\nclass Test_isexception(unittest.TestCase):\n    def _callFUT(self, ob):\n        from pyramid.config.views import isexception\n        return isexception(ob)\n\n    def test_is_exception_instance(self):\n        class E(Exception):\n            pass\n        e = E()\n        self.assertEqual(self._callFUT(e), True)\n\n    def test_is_exception_class(self):\n        class E(Exception):\n            pass\n        self.assertEqual(self._callFUT(E), True)\n\n    def test_is_IException(self):\n        from pyramid.interfaces import IException\n        self.assertEqual(self._callFUT(IException), True)\n\n    def test_is_IException_subinterface(self):\n        from pyramid.interfaces import IException\n        class ISubException(IException):\n            pass\n        self.assertEqual(self._callFUT(ISubException), True)\n\nclass TestMultiView(unittest.TestCase):\n    def _getTargetClass(self):\n        from pyramid.config.views import MultiView\n        return MultiView\n\n    def _makeOne(self, name='name'):\n        return self._getTargetClass()(name)\n\n    def test_class_implements_ISecuredView(self):\n        from zope.interface.verify import verifyClass\n        from pyramid.interfaces import ISecuredView\n        verifyClass(ISecuredView, self._getTargetClass())\n\n    def test_instance_implements_ISecuredView(self):\n        from zope.interface.verify import verifyObject\n        from pyramid.interfaces import ISecuredView\n        verifyObject(ISecuredView, self._makeOne())\n\n    def test_add(self):\n        mv = self._makeOne()\n        mv.add('view', 100)\n        self.assertEqual(mv.views, [(100, 'view', None)])\n        mv.add('view2', 99)\n        self.assertEqual(mv.views, [(99, 'view2', None), (100, 'view', None)])\n        mv.add('view3', 100, 'text/html')\n        self.assertEqual(mv.media_views['text/html'], [(100, 'view3', None)])\n        mv.add('view4', 99, 'text/html', 'abc')\n        self.assertEqual(mv.media_views['text/html'],\n                         [(99, 'view4', 'abc'), (100, 'view3', None)])\n        mv.add('view5', 100, 'text/xml')\n        self.assertEqual(mv.media_views['text/xml'], [(100, 'view5', None)])\n        self.assertEqual(set(mv.accepts), set(['text/xml', 'text/html']))\n        self.assertEqual(mv.views, [(99, 'view2', None), (100, 'view', None)])\n        mv.add('view6', 98, 'text/*')\n        self.assertEqual(mv.views, [(98, 'view6', None),\n                                    (99, 'view2', None),\n                                    (100, 'view', None)])\n\n    def test_add_with_phash(self):\n        mv = self._makeOne()\n        mv.add('view', 100, phash='abc')\n        self.assertEqual(mv.views, [(100, 'view', 'abc')])\n        mv.add('view', 100, phash='abc')\n        self.assertEqual(mv.views, [(100, 'view', 'abc')])\n        mv.add('view', 100, phash='def')\n        self.assertEqual(mv.views, [(100, 'view', 'abc'),\n                                    (100, 'view', 'def')])\n        mv.add('view', 100, phash='abc')\n        self.assertEqual(mv.views, [(100, 'view', 'abc'),\n                                    (100, 'view', 'def')])\n\n    def test_add_with_phash_override_accept(self):\n        mv = self._makeOne()\n        def view1(): pass\n        def view2(): pass\n        def view3(): pass\n        mv.add(view1, 100, accept='text/html', phash='abc')\n        mv.add(view2, 100, accept='text/html', phash='abc')\n        mv.add(view3, 99, accept='text/html', phash='def')\n        self.assertEqual(mv.media_views['text/html'],\n                         [(99, view3, 'def'), (100, view2, 'abc')])\n\n    def test_add_with_phash_override_accept2(self):\n        mv = self._makeOne()\n        def view1(): pass\n        def view2(): pass\n        def view3(): pass\n        mv.add(view1, 100, accept='text/html', phash='abc')\n        mv.add(view2, 100, accept='text/html', phash='def')\n        mv.add(view3, 99, accept='text/html', phash='ghi')\n        self.assertEqual(mv.media_views['text/html'],\n                         [(99, view3, 'ghi'),\n                          (100, view1, 'abc'),\n                          (100, view2, 'def')]\n                         )\n\n    def test_multiple_with_functions_as_views(self):\n        # this failed on py3 at one point, because functions aren't orderable\n        # and we were sorting the views via a plain sort() rather than\n        # sort(key=itemgetter(0)).\n        def view1(request): pass\n        def view2(request): pass\n        mv = self._makeOne()\n        mv.add(view1, 100, None)\n        self.assertEqual(mv.views, [(100, view1, None)])\n        mv.add(view2, 100, None)\n        self.assertEqual(mv.views, [(100, view1, None), (100, view2, None)])\n\n    def test_get_views_request_has_no_accept(self):\n        request = DummyRequest()\n        mv = self._makeOne()\n        mv.views = [(99, lambda *arg: None)]\n        self.assertEqual(mv.get_views(request), mv.views)\n\n    def test_get_views_no_self_accepts(self):\n        request = DummyRequest()\n        request.accept = True\n        mv = self._makeOne()\n        mv.accepts = []\n        mv.views = [(99, lambda *arg: None)]\n        self.assertEqual(mv.get_views(request), mv.views)\n\n    def test_get_views(self):\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        mv = self._makeOne()\n        mv.accepts = ['text/html']\n        mv.views = [(99, lambda *arg: None)]\n        html_views = [(98, lambda *arg: None)]\n        mv.media_views['text/html'] = html_views\n        self.assertEqual(mv.get_views(request), html_views + mv.views)\n\n    def test_get_views_best_match_returns_None(self):\n        request = DummyRequest()\n        request.accept = DummyAccept(None)\n        mv = self._makeOne()\n        mv.accepts = ['text/html']\n        mv.views = [(99, lambda *arg: None)]\n        self.assertEqual(mv.get_views(request), mv.views)\n\n    def test_match_not_found(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv.match, context, request)\n\n    def test_match_predicate_fails(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        def view(context, request):\n            \"\"\" \"\"\"\n        view.__predicated__ = lambda *arg: False\n        mv.views = [(100, view, None)]\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv.match, context, request)\n\n    def test_match_predicate_succeeds(self):\n        mv = self._makeOne()\n        def view(context, request):\n            \"\"\" \"\"\"\n        view.__predicated__ = lambda *arg: True\n        mv.views = [(100, view, None)]\n        context = DummyContext()\n        request = DummyRequest()\n        result = mv.match(context, request)\n        self.assertEqual(result, view)\n\n    def test_permitted_no_views(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv.__permitted__, context, request)\n\n    def test_permitted_no_match_with__permitted__(self):\n        mv = self._makeOne()\n        def view(context, request):\n            \"\"\" \"\"\"\n        mv.views = [(100, view, None)]\n        self.assertEqual(mv.__permitted__(None, None), True)\n\n    def test_permitted(self):\n        mv = self._makeOne()\n        def view(context, request):\n            \"\"\" \"\"\"\n        def permitted(context, request):\n            return False\n        view.__permitted__ = permitted\n        mv.views = [(100, view, None)]\n        context = DummyContext()\n        request = DummyRequest()\n        result = mv.__permitted__(context, request)\n        self.assertEqual(result, False)\n\n    def test__call__not_found(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv, context, request)\n\n    def test___call__intermediate_not_found(self):\n        from pyramid.exceptions import PredicateMismatch\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        expected_response = DummyResponse()\n        def view1(context, request):\n            raise PredicateMismatch\n        def view2(context, request):\n            return expected_response\n        mv.views = [(100, view1, None), (99, view2, None)]\n        response = mv(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test___call__raise_not_found_isnt_interpreted_as_pred_mismatch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        def view1(context, request):\n            raise  HTTPNotFound\n        def view2(context, request):\n            \"\"\" \"\"\"\n        mv.views = [(100, view1, None), (99, view2, None)]\n        self.assertRaises(HTTPNotFound, mv, context, request)\n\n    def test___call__(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        expected_response = DummyResponse()\n        def view(context, request):\n            return expected_response\n        mv.views = [(100, view, None)]\n        response = mv(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test__call_permissive__not_found(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv, context, request)\n\n    def test___call_permissive_has_call_permissive(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        expected_response = DummyResponse()\n        def view(context, request):\n            \"\"\" \"\"\"\n        def permissive(context, request):\n            return expected_response\n        view.__call_permissive__ = permissive\n        mv.views = [(100, view, None)]\n        response = mv.__call_permissive__(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test___call_permissive_has_no_call_permissive(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        expected_response = DummyResponse()\n        def view(context, request):\n            return expected_response\n        mv.views = [(100, view, None)]\n        response = mv.__call_permissive__(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test__call__with_accept_match(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/xml')\n        expected_response = DummyResponse()\n        def view(context, request):\n            return expected_response\n        mv.views = [(100, None)]\n        mv.media_views['text/xml'] = [(100, view, None)]\n        mv.accepts = ['text/xml']\n        response = mv(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test__call__with_accept_miss(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.accept = DummyAccept('text/plain', 'text/html')\n        expected_response = DummyResponse()\n        def view(context, request):\n            return expected_response\n        mv.views = [(100, view, None)]\n        mv.media_views['text/xml'] = [(100, None, None)]\n        mv.accepts = ['text/xml']\n        response = mv(context, request)\n        self.assertEqual(response, expected_response)\n\nclass TestViewDeriver(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n\n    def tearDown(self):\n        self.config = None\n\n    def _makeOne(self, **kw):\n        kw['registry'] = self.config.registry\n        from pyramid.config.views import ViewDeriver\n        return ViewDeriver(**kw)\n\n    def _makeRequest(self):\n        request = DummyRequest()\n        request.registry = self.config.registry\n        return request\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n        logger = DummyLogger()\n        self.config.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSecurityPolicy(self, permissive):\n        from pyramid.interfaces import IAuthenticationPolicy\n        from pyramid.interfaces import IAuthorizationPolicy\n        policy = DummySecurityPolicy(permissive)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n\n    def test_function_returns_non_adaptable(self):\n        def view(request):\n            return None\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n            self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable function '\n                'pyramid.tests.test_config.test_views.view into a response '\n                'object. The value returned was None. You may have forgotten '\n                'to return a value from the view callable.'\n                )\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_function_returns_non_adaptable_dict(self):\n        def view(request):\n            return {'a':1}\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n            self.assertEqual(\n                e.args[0],\n                \"Could not convert return value of the view callable function \"\n                \"pyramid.tests.test_config.test_views.view into a response \"\n                \"object. The value returned was {'a': 1}. You may have \"\n                \"forgotten to define a renderer in the view configuration.\"\n                )\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_instance_returns_non_adaptable(self):\n        class AView(object):\n            def __call__(self, request):\n                return None\n        view = AView()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n            msg = e.args[0]\n            self.assertTrue(msg.startswith(\n                'Could not convert return value of the view callable object '\n                '<pyramid.tests.test_config.test_views.'))\n            self.assertTrue(msg.endswith(\n                '> into a response object. The value returned was None. You '\n                'may have forgotten to return a value from the view callable.'))\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_function_returns_true_Response_no_renderer(self):\n        from pyramid.response import Response\n        r = Response('Hello')\n        def view(request):\n            return r\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        response = result(None, None)\n        self.assertEqual(response, r)\n\n    def test_function_returns_true_Response_with_renderer(self):\n        from pyramid.response import Response\n        r = Response('Hello')\n        def view(request):\n            return r\n        renderer = object()\n        deriver = self._makeOne(renderer=renderer)\n        result = deriver(view)\n        self.assertFalse(result is view)\n        response = result(None, None)\n        self.assertEqual(response, r)\n\n    def test_requestonly_default_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return None\n        deriver = self._makeOne()\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n            result(None, request)\n        except ValueError as e:\n            self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable '\n                'method __call__ of '\n                'class pyramid.tests.test_config.test_views.AView into a '\n                'response object. The value returned was None. You may have '\n                'forgotten to return a value from the view callable.'\n                )\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_requestonly_nondefault_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def theviewmethod(self):\n                return None\n        deriver = self._makeOne(attr='theviewmethod')\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n            result(None, request)\n        except ValueError as e:\n            self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable '\n                'method theviewmethod of '\n                'class pyramid.tests.test_config.test_views.AView into a '\n                'response object. The value returned was None. You may have '\n                'forgotten to return a value from the view callable.'\n                )\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_requestonly_function(self):\n        response = DummyResponse()\n        def view(request):\n            return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None), response)\n\n    def test_requestonly_function_with_renderer(self):\n        response = DummyResponse()\n        class moo(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, 'OK')\n                self.assertEqual(view_inst, view)\n                self.assertEqual(ctx, context)\n                return response\n        def view(request):\n            return 'OK'\n        deriver = self._makeOne(renderer=moo())\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_requestonly_function_with_renderer_request_override(self):\n        def moo(info):\n            def inner(value, system):\n                self.assertEqual(value, 'OK')\n                self.assertEqual(system['request'], request)\n                self.assertEqual(system['context'], context)\n                return b'moo'\n            return inner\n        def view(request):\n            return 'OK'\n        self.config.add_renderer('moo', moo)\n        deriver = self._makeOne(renderer='string')\n        result = deriver(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        request.override_renderer = 'moo'\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request).body, b'moo')\n\n    def test_requestonly_function_with_renderer_request_has_view(self):\n        response = DummyResponse()\n        class moo(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, 'OK')\n                self.assertEqual(view_inst, 'view')\n                self.assertEqual(ctx, context)\n                return response\n        def view(request):\n            return 'OK'\n        deriver = self._makeOne(renderer=moo())\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        request = self._makeRequest()\n        request.__view__ = 'view'\n        context = testing.DummyResource()\n        r = result(context, request)\n        self.assertEqual(r, response)\n        self.assertFalse(hasattr(request, '__view__'))\n\n    def test_class_without_attr(self):\n        response = DummyResponse()\n        class View(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(View)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, View)\n\n    def test_class_with_attr(self):\n        response = DummyResponse()\n        class View(object):\n            def __init__(self, request):\n                pass\n            def another(self):\n                return response\n        deriver = self._makeOne(attr='another')\n        result = deriver(View)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, View)\n\n    def test_as_function_context_and_request(self):\n        def view(context, request):\n            return 'OK'\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertTrue(result.__wraps__ is view)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        self.assertEqual(view(None, None), 'OK')\n\n    def test_as_function_requestonly(self):\n        response = DummyResponse()\n        def view(request):\n            return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        self.assertEqual(result(None, None), response)\n\n    def test_as_newstyle_class_context_and_request(self):\n        response = DummyResponse()\n        class view(object):\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_as_newstyle_class_requestonly(self):\n        response = DummyResponse()\n        class view(object):\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_as_oldstyle_class_context_and_request(self):\n        response = DummyResponse()\n        class view:\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_as_oldstyle_class_requestonly(self):\n        response = DummyResponse()\n        class view:\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_as_instance_context_and_request(self):\n        response = DummyResponse()\n        class View:\n            def __call__(self, context, request):\n                return response\n        view = View()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertTrue(result.__wraps__ is view)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        self.assertEqual(result(None, None), response)\n\n    def test_as_instance_requestonly(self):\n        response = DummyResponse()\n        class View:\n            def __call__(self, request):\n                return response\n        view = View()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertTrue('test_views' in result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        self.assertEqual(result(None, None), response)\n\n    def test_with_debug_authorization_no_authpol(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): Allowed \"\n                         \"(no authorization policy in use)\")\n\n    def test_with_debug_authorization_authn_policy_no_authz_policy(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(debug_authorization=True)\n        from pyramid.interfaces import IAuthenticationPolicy\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        logger = self._registerLogger()\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): Allowed \"\n                         \"(no authorization policy in use)\")\n\n    def test_with_debug_authorization_authz_policy_no_authn_policy(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(debug_authorization=True)\n        from pyramid.interfaces import IAuthorizationPolicy\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n        logger = self._registerLogger()\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): Allowed \"\n                         \"(no authorization policy in use)\")\n\n    def test_with_debug_authorization_no_permission(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        self._registerSecurityPolicy(True)\n        logger = self._registerLogger()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): Allowed (\"\n                         \"no permission registered)\")\n\n    def test_debug_auth_permission_authpol_permitted(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        self._registerSecurityPolicy(True)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertEqual(result.__call_permissive__.__wraps__, view)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): True\")\n\n    def test_debug_auth_permission_authpol_permitted_no_request(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        self._registerSecurityPolicy(True)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertEqual(result.__call_permissive__.__wraps__, view)\n        self.assertEqual(result(None, None), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url None (view name \"\n                         \"None against context None): True\")\n\n    def test_debug_auth_permission_authpol_denied(self):\n        from pyramid.httpexceptions import HTTPForbidden\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        self._registerSecurityPolicy(False)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertEqual(result.__call_permissive__.__wraps__, view)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertRaises(HTTPForbidden, result, None, request)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): False\")\n\n    def test_debug_auth_permission_authpol_denied2(self):\n        view = lambda *arg: 'OK'\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        self._registerLogger()\n        self._registerSecurityPolicy(False)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        permitted = result.__permitted__(None, None)\n        self.assertEqual(permitted, False)\n\n    def test_debug_auth_permission_authpol_overridden(self):\n        from pyramid.security import NO_PERMISSION_REQUIRED\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        self._registerSecurityPolicy(False)\n        deriver = self._makeOne(permission=NO_PERMISSION_REQUIRED)\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): \"\n                         \"Allowed (NO_PERMISSION_REQUIRED)\")\n\n    def test_secured_view_authn_policy_no_authz_policy(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = {}\n        from pyramid.interfaces import IAuthenticationPolicy\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n\n    def test_secured_view_authz_policy_no_authn_policy(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = {}\n        from pyramid.interfaces import IAuthorizationPolicy\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n\n    def test_secured_view_raises_forbidden_no_name(self):\n        from pyramid.interfaces import IAuthenticationPolicy\n        from pyramid.interfaces import IAuthorizationPolicy\n        from pyramid.httpexceptions import HTTPForbidden\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = {}\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        try:\n            result(None, request)\n        except HTTPForbidden as e:\n            self.assertEqual(e.message,\n                             'Unauthorized: <lambda> failed permission check')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_secured_view_raises_forbidden_with_name(self):\n        from pyramid.interfaces import IAuthenticationPolicy\n        from pyramid.interfaces import IAuthorizationPolicy\n        from pyramid.httpexceptions import HTTPForbidden\n        def myview(request): pass\n        self.config.registry.settings = {}\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n        deriver = self._makeOne(permission='view')\n        result = deriver(myview)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        try:\n            result(None, request)\n        except HTTPForbidden as e:\n            self.assertEqual(e.message,\n                             'Unauthorized: myview failed permission check')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_predicate_mismatch_view_has_no_name(self):\n        from pyramid.exceptions import PredicateMismatch\n        response = DummyResponse()\n        view = lambda *arg: response\n        def predicate1(context, request):\n            return False\n        predicate1.text = lambda *arg: 'text'\n        deriver = self._makeOne(predicates=[predicate1])\n        result = deriver(view)\n        request = self._makeRequest()\n        request.method = 'POST'\n        try:\n            result(None, None)\n        except PredicateMismatch as e:\n            self.assertEqual(e.detail,\n                             'predicate mismatch for view <lambda> (text)')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_predicate_mismatch_view_has_name(self):\n        from pyramid.exceptions import PredicateMismatch\n        def myview(request): pass\n        def predicate1(context, request):\n            return False\n        predicate1.text = lambda *arg: 'text'\n        deriver = self._makeOne(predicates=[predicate1])\n        result = deriver(myview)\n        request = self._makeRequest()\n        request.method = 'POST'\n        try:\n            result(None, None)\n        except PredicateMismatch as e:\n            self.assertEqual(e.detail,\n                             'predicate mismatch for view myview (text)')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_predicate_mismatch_exception_has_text_in_detail(self):\n        from pyramid.exceptions import PredicateMismatch\n        def myview(request): pass\n        def predicate1(context, request):\n            return True\n        predicate1.text = lambda *arg: 'pred1'\n        def predicate2(context, request):\n            return False\n        predicate2.text = lambda *arg: 'pred2'\n        deriver = self._makeOne(predicates=[predicate1, predicate2])\n        result = deriver(myview)\n        request = self._makeRequest()\n        request.method = 'POST'\n        try:\n            result(None, None)\n        except PredicateMismatch as e:\n            self.assertEqual(e.detail,\n                             'predicate mismatch for view myview (pred2)')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_with_predicates_all(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        predicates = []\n        def predicate1(context, request):\n            predicates.append(True)\n            return True\n        def predicate2(context, request):\n            predicates.append(True)\n            return True\n        deriver = self._makeOne(predicates=[predicate1, predicate2])\n        result = deriver(view)\n        request = self._makeRequest()\n        request.method = 'POST'\n        next = result(None, None)\n        self.assertEqual(next, response)\n        self.assertEqual(predicates, [True, True])\n\n    def test_with_predicates_checker(self):\n        view = lambda *arg: 'OK'\n        predicates = []\n        def predicate1(context, request):\n            predicates.append(True)\n            return True\n        def predicate2(context, request):\n            predicates.append(True)\n            return True\n        deriver = self._makeOne(predicates=[predicate1, predicate2])\n        result = deriver(view)\n        request = self._makeRequest()\n        request.method = 'POST'\n        next = result.__predicated__(None, None)\n        self.assertEqual(next, True)\n        self.assertEqual(predicates, [True, True])\n\n    def test_with_predicates_notall(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        view = lambda *arg: 'OK'\n        predicates = []\n        def predicate1(context, request):\n            predicates.append(True)\n            return True\n        predicate1.text = lambda *arg: 'text'\n        def predicate2(context, request):\n            predicates.append(True)\n            return False\n        predicate2.text = lambda *arg: 'text'\n        deriver = self._makeOne(predicates=[predicate1, predicate2])\n        result = deriver(view)\n        request = self._makeRequest()\n        request.method = 'POST'\n        self.assertRaises(HTTPNotFound, result, None, None)\n        self.assertEqual(predicates, [True, True])\n\n    def test_with_wrapper_viewname(self):\n        from pyramid.response import Response\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        inner_response = Response('OK')\n        def inner_view(context, request):\n            return inner_response\n        def outer_view(context, request):\n            self.assertEqual(request.wrapped_response, inner_response)\n            self.assertEqual(request.wrapped_body, inner_response.body)\n            self.assertEqual(request.wrapped_view.__original_view__,\n                             inner_view)\n            return Response(b'outer ' + request.wrapped_body)\n        self.config.registry.registerAdapter(\n            outer_view, (IViewClassifier, None, None), IView, 'owrap')\n        deriver = self._makeOne(viewname='inner',\n                                wrapper_viewname='owrap')\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        response = result(None, request)\n        self.assertEqual(response.body, b'outer OK')\n\n    def test_with_wrapper_viewname_notfound(self):\n        from pyramid.response import Response\n        inner_response = Response('OK')\n        def inner_view(context, request):\n            return inner_response\n        deriver = self._makeOne(viewname='inner', wrapper_viewname='owrap')\n        wrapped = deriver(inner_view)\n        request = self._makeRequest()\n        self.assertRaises(ValueError, wrapped, None, request)\n\n    def test_as_newstyle_class_context_and_request_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst.__class__, View)\n                self.assertEqual(ctx, context)\n                return response\n        class View(object):\n            def __init__(self, context, request):\n                pass\n            def index(self):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        result = deriver(View)\n        self.assertFalse(result is View)\n        self.assertEqual(result.__module__, View.__module__)\n        self.assertEqual(result.__doc__, View.__doc__)\n        self.assertEqual(result.__name__, View.__name__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_newstyle_class_requestonly_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst.__class__, View)\n                self.assertEqual(ctx, context)\n                return response\n        class View(object):\n            def __init__(self, request):\n                pass\n            def index(self):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        result = deriver(View)\n        self.assertFalse(result is View)\n        self.assertEqual(result.__module__, View.__module__)\n        self.assertEqual(result.__doc__, View.__doc__)\n        self.assertEqual(result.__name__, View.__name__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_oldstyle_cls_context_request_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst.__class__, View)\n                self.assertEqual(ctx, context)\n                return response\n        class View:\n            def __init__(self, context, request):\n                pass\n            def index(self):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        result = deriver(View)\n        self.assertFalse(result is View)\n        self.assertEqual(result.__module__, View.__module__)\n        self.assertEqual(result.__doc__, View.__doc__)\n        self.assertEqual(result.__name__, View.__name__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_oldstyle_cls_requestonly_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst.__class__, View)\n                self.assertEqual(ctx, context)\n                return response\n        class View:\n            def __init__(self, request):\n                pass\n            def index(self):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        result = deriver(View)\n        self.assertFalse(result is View)\n        self.assertEqual(result.__module__, View.__module__)\n        self.assertEqual(result.__doc__, View.__doc__)\n        self.assertEqual(result.__name__, View.__name__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_instance_context_and_request_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst, view)\n                self.assertEqual(ctx, context)\n                return response\n        class View:\n            def index(self, context, request):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        view = View()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result.__module__, view.__module__)\n        self.assertEqual(result.__doc__, view.__doc__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_instance_requestonly_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst, view)\n                self.assertEqual(ctx, context)\n                return response\n        class View:\n            def index(self, request):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        view = View()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result.__module__, view.__module__)\n        self.assertEqual(result.__doc__, view.__doc__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_with_view_mapper_config_specified(self):\n        response = DummyResponse()\n        class mapper(object):\n            def __init__(self, **kw):\n                self.kw = kw\n            def __call__(self, view):\n                def wrapped(context, request):\n                    return response\n                return wrapped\n        def view(context, request): return 'NOTOK'\n        deriver = self._makeOne(mapper=mapper)\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        self.assertEqual(result(None, None), response)\n\n    def test_with_view_mapper_view_specified(self):\n        from pyramid.response import Response\n        response = Response()\n        def mapper(**kw):\n            def inner(view):\n                def superinner(context, request):\n                    self.assertEqual(request, None)\n                    return response\n                return superinner\n            return inner\n        def view(context, request): return 'NOTOK'\n        view.__view_mapper__ = mapper\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        self.assertEqual(result(None, None), response)\n\n    def test_with_view_mapper_default_mapper_specified(self):\n        from pyramid.response import Response\n        response = Response()\n        def mapper(**kw):\n            def inner(view):\n                def superinner(context, request):\n                    self.assertEqual(request, None)\n                    return  response\n                return superinner\n            return inner\n        self.config.set_view_mapper(mapper)\n        def view(context, request): return 'NOTOK'\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        self.assertEqual(result(None, None), response)\n\n    def test_attr_wrapped_view_branching_default_phash(self):\n        from pyramid.config.util import DEFAULT_PHASH\n        def view(context, request): pass\n        deriver = self._makeOne(phash=DEFAULT_PHASH)\n        result = deriver(view)\n        self.assertEqual(result.__wraps__, view)\n\n    def test_attr_wrapped_view_branching_nondefault_phash(self):\n        def view(context, request): pass\n        deriver = self._makeOne(phash='nondefault')\n        result = deriver(view)\n        self.assertNotEqual(result, view)\n\n    def test_http_cached_view_integer(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=3600)\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(hours=1)\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n        self.assertEqual(headers['Cache-Control'], 'max-age=3600')\n\n    def test_http_cached_view_timedelta(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=datetime.timedelta(hours=1))\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(hours=1)\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n        self.assertEqual(headers['Cache-Control'], 'max-age=3600')\n\n    def test_http_cached_view_tuple(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=(3600, {'public':True}))\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(hours=1)\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n        self.assertEqual(headers['Cache-Control'], 'max-age=3600, public')\n\n    def test_http_cached_view_tuple_seconds_None(self):\n        from pyramid.response import Response\n        response = Response('OK')\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=(None, {'public':True}))\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        self.assertFalse('Expires' in headers)\n        self.assertEqual(headers['Cache-Control'], 'public')\n\n    def test_http_cached_view_prevent_auto_set(self):\n        from pyramid.response import Response\n        response = Response()\n        response.cache_control.prevent_auto = True\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=3600)\n        result = deriver(inner_view)\n        request = self._makeRequest()\n        result = result(None, request)\n        self.assertEqual(result, response) # doesn't blow up\n        headers = dict(result.headerlist)\n        self.assertFalse('Expires' in headers)\n        self.assertFalse('Cache-Control' in headers)\n\n    def test_http_cached_prevent_http_cache_in_settings(self):\n        self.config.registry.settings['prevent_http_cache'] = True\n        from pyramid.response import Response\n        response = Response()\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=3600)\n        result = deriver(inner_view)\n        request = self._makeRequest()\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        self.assertFalse('Expires' in headers)\n        self.assertFalse('Cache-Control' in headers)\n\n    def test_http_cached_view_bad_tuple(self):\n        deriver = self._makeOne(http_cache=(None,))\n        def view(request): pass\n        self.assertRaises(ConfigurationError, deriver, view)\n\nclass TestDefaultViewMapper(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        del self.registry\n        testing.tearDown()\n\n    def _makeOne(self, **kw):\n        from pyramid.config.views import DefaultViewMapper\n        kw['registry'] = self.registry\n        return DefaultViewMapper(**kw)\n\n    def _makeRequest(self):\n        request = DummyRequest()\n        request.registry = self.registry\n        return request\n\n    def test_view_as_function_context_and_request(self):\n        def view(context, request):\n            return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertTrue(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test__view_as_function_with_attr(self):\n        def view(context, request):\n            \"\"\" \"\"\"\n        mapper = self._makeOne(attr='__name__')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertRaises(TypeError, result, None, request)\n\n    def test_view_as_function_requestonly(self):\n        def view(request):\n            return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_function_requestonly_with_attr(self):\n        def view(request):\n            \"\"\" \"\"\"\n        mapper = self._makeOne(attr='__name__')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertRaises(TypeError, result, None, request)\n\n    def test_view_as_newstyle_class_context_and_request(self):\n        class view(object):\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_newstyle_class_context_and_request_with_attr(self):\n        class view(object):\n            def __init__(self, context, request):\n                pass\n            def index(self):\n                return 'OK'\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_newstyle_class_requestonly(self):\n        class view(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_newstyle_class_requestonly_with_attr(self):\n        class view(object):\n            def __init__(self, request):\n                pass\n            def index(self):\n                return 'OK'\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_oldstyle_class_context_and_request(self):\n        class view:\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_oldstyle_class_context_and_request_with_attr(self):\n        class view:\n            def __init__(self, context, request):\n                pass\n            def index(self):\n                return 'OK'\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_oldstyle_class_requestonly(self):\n        class view:\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_oldstyle_class_requestonly_with_attr(self):\n        class view:\n            def __init__(self, request):\n                pass\n            def index(self):\n                return 'OK'\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_instance_context_and_request(self):\n        class View:\n            def __call__(self, context, request):\n                return 'OK'\n        view = View()\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertTrue(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_instance_context_and_request_and_attr(self):\n        class View:\n            def index(self, context, request):\n                return 'OK'\n        view = View()\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_instance_requestonly(self):\n        class View:\n            def __call__(self, request):\n                return 'OK'\n        view = View()\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_instance_requestonly_with_attr(self):\n        class View:\n            def index(self, request):\n                return 'OK'\n        view = View()\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\nclass Test_preserve_view_attrs(unittest.TestCase):\n    def _callFUT(self, view, wrapped_view):\n        from pyramid.config.views import preserve_view_attrs\n        return preserve_view_attrs(view, wrapped_view)\n\n    def test_it_same(self):\n        def view(context, request):\n            \"\"\" \"\"\"\n        result = self._callFUT(view, view)\n        self.assertTrue(result is view)\n\n    def test_it_view_is_None(self):\n        def view(context, request):\n            \"\"\" \"\"\"\n        result = self._callFUT(None, view)\n        self.assertTrue(result is view)\n\n    def test_it_different_with_existing_original_view(self):\n        def view1(context, request): pass\n        view1.__original_view__ = 'abc'\n        def view2(context, request): pass\n        result = self._callFUT(view1, view2)\n        self.assertEqual(result.__original_view__, 'abc')\n        self.assertFalse(result is view1)\n\n    def test_it_different(self):\n        class DummyView1:\n            \"\"\" 1 \"\"\"\n            __name__ = '1'\n            __module__ = '1'\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n            def __call_permissive__(self, context, request):\n                \"\"\" \"\"\"\n            def __predicated__(self, context, request):\n                \"\"\" \"\"\"\n            def __permitted__(self, context, request):\n                \"\"\" \"\"\"\n        class DummyView2:\n            \"\"\" 2 \"\"\"\n            __name__ = '2'\n            __module__ = '2'\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n            def __call_permissive__(self, context, request):\n                \"\"\" \"\"\"\n            def __predicated__(self, context, request):\n                \"\"\" \"\"\"\n            def __permitted__(self, context, request):\n                \"\"\" \"\"\"\n        view1 = DummyView1()\n        view2 = DummyView2()\n        result = self._callFUT(view2, view1)\n        self.assertEqual(result, view1)\n        self.assertTrue(view1.__original_view__ is view2)\n        self.assertTrue(view1.__doc__ is view2.__doc__)\n        self.assertTrue(view1.__module__ is view2.__module__)\n        self.assertTrue(view1.__name__ is view2.__name__)\n        self.assertTrue(getattr(view1.__call_permissive__, im_func) is\n                        getattr(view2.__call_permissive__, im_func))\n        self.assertTrue(getattr(view1.__permitted__, im_func) is\n                        getattr(view2.__permitted__, im_func))\n        self.assertTrue(getattr(view1.__predicated__, im_func) is\n                        getattr(view2.__predicated__, im_func))\n\n\nclass TestStaticURLInfo(unittest.TestCase):\n    def _getTargetClass(self):\n        from pyramid.config.views import StaticURLInfo\n        return StaticURLInfo\n\n    def _makeOne(self):\n        return self._getTargetClass()()\n\n    def _makeConfig(self, registrations=None):\n        config = DummyConfig()\n        registry = DummyRegistry()\n        if registrations is not None:\n            registry._static_url_registrations = registrations\n        config.registry = registry\n        return config\n\n    def _makeRequest(self):\n        request = DummyRequest()\n        request.registry = DummyRegistry()\n        return request\n\n    def _assertRegistrations(self, config, expected):\n        self.assertEqual(config.registry._static_url_registrations, expected)\n\n    def test_verifyClass(self):\n        from pyramid.interfaces import IStaticURLInfo\n        from zope.interface.verify import verifyClass\n        verifyClass(IStaticURLInfo, self._getTargetClass())\n\n    def test_verifyObject(self):\n        from pyramid.interfaces import IStaticURLInfo\n        from zope.interface.verify import verifyObject\n        verifyObject(IStaticURLInfo, self._makeOne())\n\n    def test_generate_missing(self):\n        inst = self._makeOne()\n        request = self._makeRequest()\n        self.assertRaises(ValueError, inst.generate, 'path', request)\n\n    def test_generate_registration_miss(self):\n        inst = self._makeOne()\n        registrations = [(None, 'spec', 'route_name'),\n                         ('http://example.com/foo/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        result = inst.generate('package:path/abc', request)\n        self.assertEqual(result, 'http://example.com/foo/abc')\n\n    def test_generate_registration_no_registry_on_request(self):\n        inst = self._makeOne()\n        registrations = [('http://example.com/foo/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        del request.registry\n        result = inst.generate('package:path/abc', request)\n        self.assertEqual(result, 'http://example.com/foo/abc')\n\n    def test_generate_slash_in_name1(self):\n        inst = self._makeOne()\n        registrations = [('http://example.com/foo/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        result = inst.generate('package:path/abc', request)\n        self.assertEqual(result, 'http://example.com/foo/abc')\n\n    def test_generate_slash_in_name2(self):\n        inst = self._makeOne()\n        registrations = [('http://example.com/foo/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        result = inst.generate('package:path/', request)\n        self.assertEqual(result, 'http://example.com/foo/')\n\n    def test_generate_quoting(self):\n        config = testing.setUp()\n        try:\n            config.add_static_view('images', path='mypkg:templates')\n            inst = self._makeOne()\n            request = testing.DummyRequest()\n            request.registry = config.registry\n            result = inst.generate('mypkg:templates/foo%2Fbar', request)\n            self.assertEqual(result, 'http://example.com/images/foo%252Fbar')\n        finally:\n            testing.tearDown()\n\n    def test_generate_route_url(self):\n        inst = self._makeOne()\n        registrations = [(None, 'package:path/', '__viewname/')]\n        inst._get_registrations = lambda *x: registrations\n        def route_url(n, **kw):\n            self.assertEqual(n, '__viewname/')\n            self.assertEqual(kw, {'subpath':'abc', 'a':1})\n            return 'url'\n        request = self._makeRequest()\n        request.route_url = route_url\n        result = inst.generate('package:path/abc', request, a=1)\n        self.assertEqual(result, 'url')\n\n    def test_generate_url_unquoted_local(self):\n        inst = self._makeOne()\n        registrations = [(None, 'package:path/', '__viewname/')]\n        inst._get_registrations = lambda *x: registrations\n        def route_url(n, **kw):\n            self.assertEqual(n, '__viewname/')\n            self.assertEqual(kw, {'subpath':'abc def', 'a':1})\n            return 'url'\n        request = self._makeRequest()\n        request.route_url = route_url\n        result = inst.generate('package:path/abc def', request, a=1)\n        self.assertEqual(result, 'url')\n\n    def test_generate_url_quoted_remote(self):\n        inst = self._makeOne()\n        registrations = [('http://example.com/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        result = inst.generate('package:path/abc def', request, a=1)\n        self.assertEqual(result, 'http://example.com/abc%20def')\n\n    def test_add_already_exists(self):\n        inst = self._makeOne()\n        config = self._makeConfig(\n            [('http://example.com/', 'package:path/', None)])\n        inst.add(config, 'http://example.com', 'anotherpackage:path')\n        expected = [('http://example.com/',  'anotherpackage:path/', None)]\n        self._assertRegistrations(config, expected)\n\n    def test_add_url_withendslash(self):\n        inst = self._makeOne()\n        config = self._makeConfig()\n        inst.add(config, 'http://example.com/', 'anotherpackage:path')\n        expected = [('http://example.com/', 'anotherpackage:path/', None)]\n        self._assertRegistrations(config, expected)\n\n    def test_add_url_noendslash(self):\n        inst = self._makeOne()\n        config = self._makeConfig()\n        inst.add(config, 'http://example.com', 'anotherpackage:path')\n        expected = [('http://example.com/', 'anotherpackage:path/', None)]\n        self._assertRegistrations(config, expected)\n\n    def test_add_url_noscheme(self):\n        inst = self._makeOne()\n        config = self._makeConfig()\n        inst.add(config, '//example.com', 'anotherpackage:path')\n        expected = [('//example.com/', 'anotherpackage:path/', None)]\n        self._assertRegistrations(config, expected)\n\n    def test_add_viewname(self):\n        from pyramid.security import NO_PERMISSION_REQUIRED\n        from pyramid.static import static_view\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1)\n        expected = [(None, 'anotherpackage:path/', '__view/')]\n        self._assertRegistrations(config, expected)\n        self.assertEqual(config.route_args, ('__view/', 'view/*subpath'))\n        self.assertEqual(config.view_kw['permission'], NO_PERMISSION_REQUIRED)\n        self.assertEqual(config.view_kw['view'].__class__, static_view)\n\n    def test_add_viewname_with_route_prefix(self):\n        config = self._makeConfig()\n        config.route_prefix = '/abc'\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path',)\n        expected = [(None, 'anotherpackage:path/', '__/abc/view/')]\n        self._assertRegistrations(config, expected)\n        self.assertEqual(config.route_args, ('__/abc/view/', 'view/*subpath'))\n\n    def test_add_viewname_with_permission(self):\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1,\n                 permission='abc')\n        self.assertEqual(config.view_kw['permission'], 'abc')\n\n    def test_add_viewname_with_context(self):\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1,\n                 context=DummyContext)\n        self.assertEqual(config.view_kw['context'], DummyContext)\n        \n    def test_add_viewname_with_for_(self):\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1,\n                 for_=DummyContext)\n        self.assertEqual(config.view_kw['context'], DummyContext)\n\n    def test_add_viewname_with_renderer(self):\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1,\n                 renderer='mypackage:templates/index.pt')\n        self.assertEqual(config.view_kw['renderer'],\n                         'mypackage:templates/index.pt')\n\nclass Test_view_description(unittest.TestCase):\n    def _callFUT(self, view):\n        from pyramid.config.views import view_description\n        return view_description(view)\n\n    def test_with_text(self):\n        def view(): pass\n        view.__text__ = 'some text'\n        result = self._callFUT(view)\n        self.assertEqual(result, 'some text')\n\n    def test_without_text(self):\n        def view(): pass\n        result = self._callFUT(view)\n        self.assertEqual(result,\n                         'function pyramid.tests.test_config.test_views.view')\n\n\nclass DummyRegistry:\n    pass\n\nfrom zope.interface import implementer\nfrom pyramid.interfaces import IResponse\n@implementer(IResponse)\nclass DummyResponse(object):\n    content_type = None\n    default_content_type = None\n    body = None\n\nclass DummyRequest:\n    subpath = ()\n    matchdict = None\n\n    def __init__(self, environ=None):\n        if environ is None:\n            environ = {}\n        self.environ = environ\n        self.params = {}\n        self.cookies = {}\n        self.response = DummyResponse()\n\nclass DummyContext:\n    pass\n\nclass DummyAccept(object):\n    def __init__(self, *matches):\n        self.matches = list(matches)\n\n    def best_match(self, offered):\n        if self.matches:\n            for match in self.matches:\n                if match in offered:\n                    self.matches.remove(match)\n                    return match\n    def __contains__(self, val):\n        return val in self.matches\n\nclass DummyLogger:\n    def __init__(self):\n        self.messages = []\n    def info(self, msg):\n        self.messages.append(msg)\n    warn = info\n    debug = info\n\nclass DummySecurityPolicy:\n    def __init__(self, permitted=True):\n        self.permitted = permitted\n\n    def effective_principals(self, request):\n        return []\n\n    def permits(self, context, principals, permission):\n        return self.permitted\n\nclass DummyConfig:\n    route_prefix = ''\n    def add_route(self, *args, **kw):\n        self.route_args = args\n        self.route_kw = kw\n\n    def add_view(self, *args, **kw):\n        self.view_args = args\n        self.view_kw = kw\n\n    def action(self, discriminator, callable, introspectables=()):\n        callable()\n\n    def introspectable(self, *arg):\n        return {}\n\nfrom zope.interface import implementer\nfrom pyramid.interfaces import IMultiView\n@implementer(IMultiView)\nclass DummyMultiView:\n    def __init__(self):\n        self.views = []\n        self.name = 'name'\n    def add(self, view, order, accept=None, phash=None):\n        self.views.append((view, accept, phash))\n    def __call__(self, context, request):\n        return 'OK1'\n    def __permitted__(self, context, request):\n        \"\"\" \"\"\"\n\ndef parse_httpdate(s):\n    import datetime\n    # cannot use %Z, must use literal GMT; Jython honors timezone\n    # but CPython does not\n    return datetime.datetime.strptime(s, \"%a, %d %b %Y %H:%M:%S GMT\")\n\ndef assert_similar_datetime(one, two):\n    for attr in ('year', 'month', 'day', 'hour', 'minute'):\n        one_attr = getattr(one, attr)\n        two_attr = getattr(two, attr)\n        if not one_attr == two_attr: # pragma: no cover\n            raise AssertionError('%r != %r in %s' % (one_attr, two_attr, attr))\n\nclass DummyStaticURLInfo:\n    def __init__(self):\n        self.added = []\n\n    def add(self, config, name, spec, **kw):\n        self.added.append((config, name, spec, kw))\n\nclass DummyViewDefaultsClass(object):\n    __view_defaults__ = {\n        'containment':'pyramid.tests.test_config.IDummy'\n        }\n    def __init__(self, request):\n        pass\n    def __call__(self):\n        return 'OK'\n\nclass DummyPredicate(object):\n    def __init__(self, val, config):\n        self.val = val\n\n    def text(self):\n        return 'dummy'\n\n    phash = text\n\nclass DummyIntrospector(object):\n    def __init__(self, getval=None):\n        self.related = []\n        self.introspectables = []\n        self.getval = getval\n    def add(self, introspectable):\n        self.introspectables.append(introspectable)\n    def get(self, name, discrim):\n        return self.getval\n    def relate(self, a, b):\n        self.related.append((a, b))\n",
            "header": {
                "file": {
                    "path": "pyramid/tests/test_config/test_views.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "4924fff57",
                "new_commit_hash": "051961d25",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/pyramid/tests/test_config/test_views.py"
            },
            "plus_file": {
                "path": "b/pyramid/tests/test_config/test_views.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 1815,
                            "length": 6
                        },
                        "new_range": {
                            "start": 1815,
                            "length": 36
                        },
                        "section": "class TestViewsConfigurationMixin(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        self.assertRaises(ConfigurationError,",
                                "type": "context"
                            },
                            {
                                "content": "                          config.add_forbidden_view, http_cache='foo')",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_add_forbidden_view_with_view_defaults(self):",
                                "type": "added"
                            },
                            {
                                "content": "        from pyramid.interfaces import IRequest",
                                "type": "added"
                            },
                            {
                                "content": "        from pyramid.renderers import null_renderer",
                                "type": "added"
                            },
                            {
                                "content": "        from pyramid.exceptions import PredicateMismatch",
                                "type": "added"
                            },
                            {
                                "content": "        from pyramid.httpexceptions import HTTPForbidden",
                                "type": "added"
                            },
                            {
                                "content": "        from zope.interface import directlyProvides",
                                "type": "added"
                            },
                            {
                                "content": "        from zope.interface import implementedBy",
                                "type": "added"
                            },
                            {
                                "content": "        class view(object):",
                                "type": "added"
                            },
                            {
                                "content": "            __view_defaults__ = {",
                                "type": "added"
                            },
                            {
                                "content": "                'containment':'pyramid.tests.test_config.IDummy'",
                                "type": "added"
                            },
                            {
                                "content": "                }",
                                "type": "added"
                            },
                            {
                                "content": "            def __init__(self, request):",
                                "type": "added"
                            },
                            {
                                "content": "                pass",
                                "type": "added"
                            },
                            {
                                "content": "            def __call__(self):",
                                "type": "added"
                            },
                            {
                                "content": "                return 'OK'",
                                "type": "added"
                            },
                            {
                                "content": "        config = self._makeOne(autocommit=True)",
                                "type": "added"
                            },
                            {
                                "content": "        config.add_forbidden_view(",
                                "type": "added"
                            },
                            {
                                "content": "            view=view,",
                                "type": "added"
                            },
                            {
                                "content": "            renderer=null_renderer)",
                                "type": "added"
                            },
                            {
                                "content": "        wrapper = self._getViewCallable(",
                                "type": "added"
                            },
                            {
                                "content": "            config, ctx_iface=implementedBy(HTTPForbidden),",
                                "type": "added"
                            },
                            {
                                "content": "            request_iface=IRequest)",
                                "type": "added"
                            },
                            {
                                "content": "        context = DummyContext()",
                                "type": "added"
                            },
                            {
                                "content": "        directlyProvides(context, IDummy)",
                                "type": "added"
                            },
                            {
                                "content": "        request = self._makeRequest(config)",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(wrapper(context, request), 'OK')",
                                "type": "added"
                            },
                            {
                                "content": "        context = DummyContext()",
                                "type": "added"
                            },
                            {
                                "content": "        request = self._makeRequest(config)",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertRaises(PredicateMismatch, wrapper, context, request)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    def test_add_notfound_view(self):",
                                "type": "context"
                            },
                            {
                                "content": "        from pyramid.renderers import null_renderer",
                                "type": "context"
                            },
                            {
                                "content": "        from zope.interface import implementedBy",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "pyramid/tests/test_config/test_views.py",
                            "type": "class",
                            "name": "TestViewsConfigurationMixin",
                            "content": "class TestViewsConfigurationMixin(unittest.TestCase):\n    def _makeOne(self, *arg, **kw):\n        from pyramid.config import Configurator\n        config = Configurator(*arg, **kw)\n        return config\n\n    def _getViewCallable(self, config, ctx_iface=None, request_iface=None,\n                         name='', exception_view=False):\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        if exception_view:\n            classifier = IExceptionViewClassifier\n        else:\n            classifier = IViewClassifier\n        if ctx_iface is None:\n            ctx_iface = Interface\n        if request_iface is None:\n            request_iface = IRequest\n        return config.registry.adapters.lookup(\n            (classifier, request_iface, ctx_iface), IView, name=name,\n            default=None)\n\n    def _registerRenderer(self, config, name='.txt'):\n        from pyramid.interfaces import IRendererFactory\n        class Renderer:\n            def __init__(self, info):\n                self.__class__.info = info\n            def __call__(self, *arg):\n                return b'Hello!'\n        config.registry.registerUtility(Renderer, IRendererFactory, name=name)\n        return Renderer\n\n    def _makeRequest(self, config):\n        request = DummyRequest()\n        request.registry = config.registry\n        return request\n\n    def _assertNotFound(self, wrapper, *arg):\n        from pyramid.httpexceptions import HTTPNotFound\n        self.assertRaises(HTTPNotFound, wrapper, *arg)\n\n    def _getRouteRequestIface(self, config, name):\n        from pyramid.interfaces import IRouteRequest\n        iface = config.registry.getUtility(IRouteRequest, name)\n        return iface\n\n    def _assertRoute(self, config, name, path, num_predicates=0):\n        from pyramid.interfaces import IRoutesMapper\n        mapper = config.registry.getUtility(IRoutesMapper)\n        routes = mapper.get_routes()\n        route = routes[0]\n        self.assertEqual(len(routes), 1)\n        self.assertEqual(route.name, name)\n        self.assertEqual(route.path, path)\n        self.assertEqual(len(routes[0].predicates), num_predicates)\n        return route\n\n    def test_add_view_view_callable_None_no_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError, config.add_view)\n\n    def test_add_view_with_request_type_and_route_name(self):\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        self.assertRaises(ConfigurationError, config.add_view, view, '', None,\n                          None, True, True)\n\n    def test_add_view_with_request_type(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        from pyramid.interfaces import IRequest\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view,\n                        request_type='pyramid.interfaces.IRequest',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = DummyRequest()\n        self._assertNotFound(wrapper, None, request)\n        directlyProvides(request, IRequest)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_view_callable_None_with_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self._registerRenderer(config, name='dummy')\n        config.add_view(renderer='dummy')\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n\n    def test_add_view_with_tmpl_renderer_factory_introspector_missing(self):\n        config = self._makeOne(autocommit=True)\n        config.introspection = False\n        config.introspector = None\n        config.add_view(renderer='dummy.pt')\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n        \n    def test_add_view_with_tmpl_renderer_factory_no_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector()\n        config.introspector = introspector\n        config.add_view(renderer='dummy.pt')\n        self.assertFalse(('renderer factories', '.pt') in\n                         introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n\n    def test_add_view_with_tmpl_renderer_factory_with_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector(True)\n        config.introspector = introspector\n        def dummy_factory(helper):\n            return lambda val, system_vals: 'Hello!'\n        config.add_renderer('.pt', dummy_factory)\n        config.add_view(renderer='dummy.pt')\n        self.assertTrue(\n            ('renderer factories', '.pt') in introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n        \n    def test_add_view_wrapped_view_is_decorated(self):\n        def view(request): # request-only wrapper\n            \"\"\" \"\"\"\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper.__module__, view.__module__)\n        self.assertEqual(wrapper.__name__, view.__name__)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        self.assertEqual(wrapper.__discriminator__(None, None).resolve()[0],\n                         'view')\n\n    def test_add_view_view_callable_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        config.add_view(view='pyramid.tests.test_config.dummy_view',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_function_callable(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_function_callable_requestonly(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, name='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name='abc')\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name_unicode(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        name = text_(b'La Pe\\xc3\\xb1a', 'utf-8')\n        config.add_view(view=view, name=name, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name=name)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper(fn):\n            def inner(context, request):\n                return fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=view_wrapper,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator_tuple(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper1(fn):\n            def inner(context, request):\n                return 'wrapped1' + fn(context, request)\n            return inner\n        def view_wrapper2(fn):\n            def inner(context, request):\n                return 'wrapped2' + fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=(view_wrapper2, view_wrapper1),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'wrapped2wrapped1OK')\n\n    def test_add_view_with_http_cache(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return response\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, http_cache=(86400, {'public':True}))\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        request = testing.DummyRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(days=1)\n        result = wrapper(None, request)\n        self.assertEqual(result, response)\n        headers = dict(response.headerlist)\n        self.assertEqual(headers['Cache-Control'], 'max-age=86400, public')\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n\n    def test_add_view_as_instance(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, context, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instance_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_oldstyle_class(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, context, request):\n                self.context = context\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_as_oldstyle_class_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, request):\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_context_as_class(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_iface(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context='pyramid.tests.test_config.IDummy',\n                        view=view,  renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for__as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_='pyramid.tests.test_config.IDummy',\n                        view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_class(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_iface(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_trumps_for(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        class Foo:\n            pass\n        config.add_view(context=IDummy, for_=Foo, view=view,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_exception_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_mixed_case_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/HTML', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.media_views.items()),1)\n        self.assertFalse('text/HTML' in wrapper.media_views)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_views_with_accept_multiview_replaces_existing(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(len(wrapper.media_views['text/html']), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_view_exc_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, accept='text/html', context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_multiview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_mulview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_exc_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_multiview_context_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        class ISuper(Interface):\n            pass\n        class ISub(ISuper):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, ISuper), IView, name='')\n        config.add_view(view=view2, for_=ISub, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, ISuper, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n        wrapper = self._getViewCallable(config, ISub, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK2')\n\n    def test_add_view_multiview_exception_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        class Super(Exception):\n            pass\n        class Sub(Super):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Super), IView, name='')\n        config.registry.registerAdapter(\n            view, (IExceptionViewClassifier, IRequest, Super), IView, name='')\n        config.add_view(view=view2, for_=Sub, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, implementedBy(Super), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Super), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n        wrapper = self._getViewCallable(\n            config, implementedBy(Sub), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Sub), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK2')\n\n    def test_add_view_multiview_call_ordering(self):\n        from pyramid.renderers import null_renderer as nr\n        from zope.interface import directlyProvides\n        def view1(context, request): return 'view1'\n        def view2(context, request): return 'view2'\n        def view3(context, request): return 'view3'\n        def view4(context, request): return 'view4'\n        def view5(context, request): return 'view5'\n        def view6(context, request): return 'view6'\n        def view7(context, request): return 'view7'\n        def view8(context, request): return 'view8'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view1, renderer=nr)\n        config.add_view(view=view2, request_method='POST', renderer=nr)\n        config.add_view(view=view3,request_param='param', renderer=nr)\n        config.add_view(view=view4, containment=IDummy, renderer=nr)\n        config.add_view(view=view5, request_method='POST',\n                        request_param='param',  renderer=nr)\n        config.add_view(view=view6, request_method='POST', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view7, request_param='param', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view8, request_method='POST',request_param='param',\n                        containment=IDummy, renderer=nr)\n\n\n        wrapper = self._getViewCallable(config)\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view1')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view2')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {'param':'1'}\n        request.method = 'GET'\n        self.assertEqual(wrapper(ctx, request), 'view3')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view4')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view5')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view6')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view7')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view8')\n\n    def test_add_view_multiview___discriminator__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        class IFoo(Interface):\n            pass\n        class IBar(Interface):\n            pass\n        @implementer(IFoo)\n        class Foo(object):\n            pass\n        @implementer(IBar)\n        class Bar(object):\n            pass\n        foo = Foo()\n        bar = Bar()\n\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IFoo)\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IBar)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        request = self._makeRequest(config)\n        self.assertNotEqual(\n            wrapper.__discriminator__(foo, request),\n            wrapper.__discriminator__(bar, request),\n            )\n\n    def test_add_view_with_template_renderer(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=view, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_default_renderer(self):\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        class moo(object):\n            def __init__(self, *arg, **kw):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'moo'\n        config.add_renderer(None, moo)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'moo')\n\n    def test_add_view_with_template_renderer_no_callable(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=None, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_request_type_as_iface(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        def view(context, request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(request_type=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, None)\n        request = self._makeRequest(config)\n        directlyProvides(request, IDummy)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_request_type_as_noniface(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        self.assertRaises(ConfigurationError,\n                          config.add_view, view, '', None, None, object)\n\n    def test_add_view_with_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        self.assertNotEqual(request_iface, None)\n        wrapper = self._getViewCallable(config, request_iface=request_iface)\n        self.assertNotEqual(wrapper, None)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_nonexistant_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        self.assertRaises(ConfigurationExecutionError, config.commit)\n\n    def test_add_view_with_route_name_exception(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', context=RuntimeError,\n                        renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        wrapper_exc_view = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface, exception_view=True)\n        self.assertNotEqual(wrapper_exc_view, None)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n\n    def test_add_view_with_request_method_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_sequence_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_sequence_conflict(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        config.add_view(view=view, request_method=('GET', 'POST'),\n                        renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_request_method_sequence_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'HEAD'))\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_get_implies_head(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'HEAD'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_param_val_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':'123'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_val_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_xhr_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_xhr_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = False\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, header='Host:a\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_header_noval_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'whatever'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_noval_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NotHost':'whatever'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'1'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_val_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'abc'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_missing(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NoHost':'1'}\n        self.assertRaises(HTTPNotFound, wrapper, None, request)\n\n    def test_add_view_with_accept_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/xml']\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_accept_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/html']\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_containment_true(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_containment_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        self._assertNotFound(wrapper, context, None)\n\n    def test_add_view_with_containment_dottedname(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            containment='pyramid.tests.test_config.IDummy',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_path_info_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, path_info='\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_path_info_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_(b'/foo')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_path_info_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_('/')\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_custom_predicates_match(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return True\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates,\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_custom_predicates_nomatch(self):\n        import warnings\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return False\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_custom_predicate_bests_standard_predicate(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=(pred1,),\n                        renderer=null_renderer)\n            config.add_view(view=view2, request_method='GET',\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_custom_more_preds_first_bests_fewer_preds_last(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', xhr=True,\n                        renderer=null_renderer)\n        config.add_view(view=view2, request_method='GET',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_same_predicates(self):\n        view2 = lambda *arg: 'second'\n        view1 = lambda *arg: 'first'\n        config = self._makeOne()\n        config.add_view(view=view1)\n        config.add_view(view=view2)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, permission='view', renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               default_permission='view',\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_no_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        class DummyPolicy(object): pass # wont be called\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_mapper(self):\n        from pyramid.renderers import null_renderer\n        class Mapper(object):\n            def __init__(self, **kw):\n                self.__class__.kw = kw\n            def __call__(self, view):\n                return view\n        config = self._makeOne(autocommit=True)\n        def view(context, request): return 'OK'\n        config.add_view(view=view, mapper=Mapper, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        self.assertEqual(view(None, None), 'OK')\n        self.assertEqual(Mapper.kw['mapper'], Mapper)\n\n    def test_add_view_with_view_defaults(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_kwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view='pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            'pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_config_and_view_defaults_doesnt_conflict(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IFactory'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        config.commit() # does not raise\n\n    def test_add_view_with_view_config_and_view_defaults_conflicts(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_derive_view_function(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        result = config.derive_view(view, renderer=null_renderer)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne()\n        result = config.derive_view(\n            'pyramid.tests.test_config.dummy_view',\n            renderer=null_renderer)\n        self.assertFalse(result is dummy_view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_with_default_renderer_no_explicit_renderer(self):\n        config = self._makeOne()\n        class moo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return 'moo'\n        config.add_renderer(None, moo)\n        config.commit()\n        def view(request):\n            return 'OK'\n        result = config.derive_view(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None).body, b'moo')\n\n    def test_derive_view_with_default_renderer_with_explicit_renderer(self):\n        class moo(object): pass\n        class foo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'foo'\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        config.add_renderer(None, moo)\n        config.add_renderer('foo', foo)\n        config.commit()\n        result = config.derive_view(view, renderer='foo')\n        self.assertFalse(result is view)\n        request = self._makeRequest(config)\n        self.assertEqual(result(None, request).body, b'foo')\n\n    def test_add_static_view_here_no_utility_registered(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        config = self._makeOne(autocommit=True)\n        config.add_static_view('static', 'files', renderer=null_renderer)\n        request_type = self._getRouteRequestIface(config, '__static/')\n        self._assertRoute(config, '__static/', 'static/*subpath')\n        wrapped = config.registry.adapters.lookup(\n            (IViewClassifier, request_type, Interface), IView, name='')\n        from pyramid.request import Request\n        request = Request.blank('/static/minimal.txt')\n        request.subpath = ('minimal.txt', )\n        result = wrapped(None, request)\n        self.assertEqual(result.status, '200 OK')\n        self.assertTrue(result.body.startswith(b'<div'))\n\n    def test_add_static_view_package_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static',\n                               'pyramid.tests.test_config:files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_package_here_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static', 'files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_absolute(self):\n        import os\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        here = os.path.dirname(__file__)\n        static_path = os.path.join(here, 'files')\n        config.add_static_view('static', static_path)\n        self.assertEqual(info.added,\n                         [(config, 'static', static_path, {})])\n\n    def test_add_forbidden_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        config.add_forbidden_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_forbidden_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_forbidden_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_forbidden_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, name='foo')\n\n    def test_add_forbidden_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, permission='foo')\n\n    def test_add_forbidden_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, context='foo')\n\n    def test_add_forbidden_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, for_='foo')\n\n    def test_add_forbidden_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, http_cache='foo')\n\n    def test_add_forbidden_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPForbidden\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_forbidden_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPForbidden),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_notfound_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: arg\n        config.add_notfound_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, (None, request))\n\n    def test_add_notfound_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_notfound_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_notfound_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, name='foo')\n\n    def test_add_notfound_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, permission='foo')\n\n    def test_add_notfound_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, context='foo')\n\n    def test_add_notfound_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, for_='foo')\n\n    def test_add_notfound_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, http_cache='foo')\n\n    def test_add_notfound_view_append_slash(self):\n        from pyramid.response import Response\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/foo/')\n        def view(request): return Response('OK')\n        config.add_notfound_view(view, renderer=null_renderer,append_slash=True)\n        request = self._makeRequest(config)\n        request.environ['PATH_INFO'] = '/foo'\n        request.query_string = 'a=1&b=2'\n        request.path = '/scriptname/foo'\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result.location, '/scriptname/foo/?a=1&b=2')\n\n    def test_add_notfound_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPNotFound\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_notfound_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPNotFound),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    # Since Python 3 has to be all cool and fancy and different...\n    def _assertBody(self, response, value):\n        from pyramid.compat import text_type\n        if isinstance(value, text_type): # pragma: nocover\n            self.assertEqual(response.text, value)\n        else: # pragma: nocover\n            self.assertEqual(response.body, value)\n\n    def test_add_notfound_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_notfound_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_add_forbidden_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_forbidden_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_set_view_mapper(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        mapper = object()\n        config.set_view_mapper(mapper)\n        result = config.registry.getUtility(IViewMapperFactory)\n        self.assertEqual(result, mapper)\n\n    def test_set_view_mapper_dottedname(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        config.set_view_mapper('pyramid.tests.test_config')\n        result = config.registry.getUtility(IViewMapperFactory)\n        from pyramid.tests import test_config\n        self.assertEqual(result, test_config)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 16,
                            "end_lineno": 2001,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "pyramid/tests/test_config/test_views.py",
                            "type": "method",
                            "name": "TestViewsConfigurationMixin.test_add_forbidden_view_with_view_defaults",
                            "content": "class TestViewsConfigurationMixin(unittest.TestCase):\n    def _makeOne(self, *arg, **kw):\n        from pyramid.config import Configurator\n        config = Configurator(*arg, **kw)\n        return config\n\n    def _getViewCallable(self, config, ctx_iface=None, request_iface=None,\n                         name='', exception_view=False):\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        if exception_view:\n            classifier = IExceptionViewClassifier\n        else:\n            classifier = IViewClassifier\n        if ctx_iface is None:\n            ctx_iface = Interface\n        if request_iface is None:\n            request_iface = IRequest\n        return config.registry.adapters.lookup(\n            (classifier, request_iface, ctx_iface), IView, name=name,\n            default=None)\n\n    def _registerRenderer(self, config, name='.txt'):\n        from pyramid.interfaces import IRendererFactory\n        class Renderer:\n            def __init__(self, info):\n                self.__class__.info = info\n            def __call__(self, *arg):\n                return b'Hello!'\n        config.registry.registerUtility(Renderer, IRendererFactory, name=name)\n        return Renderer\n\n    def _makeRequest(self, config):\n        request = DummyRequest()\n        request.registry = config.registry\n        return request\n\n    def _assertNotFound(self, wrapper, *arg):\n        from pyramid.httpexceptions import HTTPNotFound\n        self.assertRaises(HTTPNotFound, wrapper, *arg)\n\n    def _getRouteRequestIface(self, config, name):\n        from pyramid.interfaces import IRouteRequest\n        iface = config.registry.getUtility(IRouteRequest, name)\n        return iface\n\n    def _assertRoute(self, config, name, path, num_predicates=0):\n        from pyramid.interfaces import IRoutesMapper\n        mapper = config.registry.getUtility(IRoutesMapper)\n        routes = mapper.get_routes()\n        route = routes[0]\n        self.assertEqual(len(routes), 1)\n        self.assertEqual(route.name, name)\n        self.assertEqual(route.path, path)\n        self.assertEqual(len(routes[0].predicates), num_predicates)\n        return route\n\n    def test_add_view_view_callable_None_no_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError, config.add_view)\n\n    def test_add_view_with_request_type_and_route_name(self):\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        self.assertRaises(ConfigurationError, config.add_view, view, '', None,\n                          None, True, True)\n\n    def test_add_view_with_request_type(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        from pyramid.interfaces import IRequest\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view,\n                        request_type='pyramid.interfaces.IRequest',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = DummyRequest()\n        self._assertNotFound(wrapper, None, request)\n        directlyProvides(request, IRequest)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_view_callable_None_with_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self._registerRenderer(config, name='dummy')\n        config.add_view(renderer='dummy')\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n\n    def test_add_view_with_tmpl_renderer_factory_introspector_missing(self):\n        config = self._makeOne(autocommit=True)\n        config.introspection = False\n        config.introspector = None\n        config.add_view(renderer='dummy.pt')\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n        \n    def test_add_view_with_tmpl_renderer_factory_no_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector()\n        config.introspector = introspector\n        config.add_view(renderer='dummy.pt')\n        self.assertFalse(('renderer factories', '.pt') in\n                         introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n\n    def test_add_view_with_tmpl_renderer_factory_with_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector(True)\n        config.introspector = introspector\n        def dummy_factory(helper):\n            return lambda val, system_vals: 'Hello!'\n        config.add_renderer('.pt', dummy_factory)\n        config.add_view(renderer='dummy.pt')\n        self.assertTrue(\n            ('renderer factories', '.pt') in introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n        \n    def test_add_view_wrapped_view_is_decorated(self):\n        def view(request): # request-only wrapper\n            \"\"\" \"\"\"\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper.__module__, view.__module__)\n        self.assertEqual(wrapper.__name__, view.__name__)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        self.assertEqual(wrapper.__discriminator__(None, None).resolve()[0],\n                         'view')\n\n    def test_add_view_view_callable_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        config.add_view(view='pyramid.tests.test_config.dummy_view',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_function_callable(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_function_callable_requestonly(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, name='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name='abc')\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name_unicode(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        name = text_(b'La Pe\\xc3\\xb1a', 'utf-8')\n        config.add_view(view=view, name=name, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name=name)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper(fn):\n            def inner(context, request):\n                return fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=view_wrapper,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator_tuple(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper1(fn):\n            def inner(context, request):\n                return 'wrapped1' + fn(context, request)\n            return inner\n        def view_wrapper2(fn):\n            def inner(context, request):\n                return 'wrapped2' + fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=(view_wrapper2, view_wrapper1),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'wrapped2wrapped1OK')\n\n    def test_add_view_with_http_cache(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return response\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, http_cache=(86400, {'public':True}))\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        request = testing.DummyRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(days=1)\n        result = wrapper(None, request)\n        self.assertEqual(result, response)\n        headers = dict(response.headerlist)\n        self.assertEqual(headers['Cache-Control'], 'max-age=86400, public')\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n\n    def test_add_view_as_instance(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, context, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instance_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_oldstyle_class(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, context, request):\n                self.context = context\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_as_oldstyle_class_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, request):\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_context_as_class(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_iface(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context='pyramid.tests.test_config.IDummy',\n                        view=view,  renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for__as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_='pyramid.tests.test_config.IDummy',\n                        view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_class(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_iface(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_trumps_for(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        class Foo:\n            pass\n        config.add_view(context=IDummy, for_=Foo, view=view,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_exception_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_mixed_case_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/HTML', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.media_views.items()),1)\n        self.assertFalse('text/HTML' in wrapper.media_views)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_views_with_accept_multiview_replaces_existing(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(len(wrapper.media_views['text/html']), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_view_exc_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, accept='text/html', context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_multiview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_mulview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_exc_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_multiview_context_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        class ISuper(Interface):\n            pass\n        class ISub(ISuper):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, ISuper), IView, name='')\n        config.add_view(view=view2, for_=ISub, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, ISuper, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n        wrapper = self._getViewCallable(config, ISub, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK2')\n\n    def test_add_view_multiview_exception_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        class Super(Exception):\n            pass\n        class Sub(Super):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Super), IView, name='')\n        config.registry.registerAdapter(\n            view, (IExceptionViewClassifier, IRequest, Super), IView, name='')\n        config.add_view(view=view2, for_=Sub, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, implementedBy(Super), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Super), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n        wrapper = self._getViewCallable(\n            config, implementedBy(Sub), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Sub), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK2')\n\n    def test_add_view_multiview_call_ordering(self):\n        from pyramid.renderers import null_renderer as nr\n        from zope.interface import directlyProvides\n        def view1(context, request): return 'view1'\n        def view2(context, request): return 'view2'\n        def view3(context, request): return 'view3'\n        def view4(context, request): return 'view4'\n        def view5(context, request): return 'view5'\n        def view6(context, request): return 'view6'\n        def view7(context, request): return 'view7'\n        def view8(context, request): return 'view8'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view1, renderer=nr)\n        config.add_view(view=view2, request_method='POST', renderer=nr)\n        config.add_view(view=view3,request_param='param', renderer=nr)\n        config.add_view(view=view4, containment=IDummy, renderer=nr)\n        config.add_view(view=view5, request_method='POST',\n                        request_param='param',  renderer=nr)\n        config.add_view(view=view6, request_method='POST', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view7, request_param='param', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view8, request_method='POST',request_param='param',\n                        containment=IDummy, renderer=nr)\n\n\n        wrapper = self._getViewCallable(config)\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view1')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view2')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {'param':'1'}\n        request.method = 'GET'\n        self.assertEqual(wrapper(ctx, request), 'view3')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view4')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view5')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view6')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view7')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view8')\n\n    def test_add_view_multiview___discriminator__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        class IFoo(Interface):\n            pass\n        class IBar(Interface):\n            pass\n        @implementer(IFoo)\n        class Foo(object):\n            pass\n        @implementer(IBar)\n        class Bar(object):\n            pass\n        foo = Foo()\n        bar = Bar()\n\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IFoo)\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IBar)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        request = self._makeRequest(config)\n        self.assertNotEqual(\n            wrapper.__discriminator__(foo, request),\n            wrapper.__discriminator__(bar, request),\n            )\n\n    def test_add_view_with_template_renderer(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=view, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_default_renderer(self):\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        class moo(object):\n            def __init__(self, *arg, **kw):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'moo'\n        config.add_renderer(None, moo)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'moo')\n\n    def test_add_view_with_template_renderer_no_callable(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=None, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_request_type_as_iface(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        def view(context, request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(request_type=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, None)\n        request = self._makeRequest(config)\n        directlyProvides(request, IDummy)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_request_type_as_noniface(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        self.assertRaises(ConfigurationError,\n                          config.add_view, view, '', None, None, object)\n\n    def test_add_view_with_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        self.assertNotEqual(request_iface, None)\n        wrapper = self._getViewCallable(config, request_iface=request_iface)\n        self.assertNotEqual(wrapper, None)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_nonexistant_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        self.assertRaises(ConfigurationExecutionError, config.commit)\n\n    def test_add_view_with_route_name_exception(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', context=RuntimeError,\n                        renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        wrapper_exc_view = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface, exception_view=True)\n        self.assertNotEqual(wrapper_exc_view, None)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n\n    def test_add_view_with_request_method_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_sequence_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_sequence_conflict(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        config.add_view(view=view, request_method=('GET', 'POST'),\n                        renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_request_method_sequence_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'HEAD'))\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_get_implies_head(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'HEAD'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_param_val_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':'123'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_val_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_xhr_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_xhr_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = False\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, header='Host:a\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_header_noval_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'whatever'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_noval_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NotHost':'whatever'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'1'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_val_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'abc'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_missing(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NoHost':'1'}\n        self.assertRaises(HTTPNotFound, wrapper, None, request)\n\n    def test_add_view_with_accept_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/xml']\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_accept_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/html']\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_containment_true(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_containment_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        self._assertNotFound(wrapper, context, None)\n\n    def test_add_view_with_containment_dottedname(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            containment='pyramid.tests.test_config.IDummy',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_path_info_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, path_info='\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_path_info_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_(b'/foo')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_path_info_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_('/')\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_custom_predicates_match(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return True\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates,\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_custom_predicates_nomatch(self):\n        import warnings\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return False\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_custom_predicate_bests_standard_predicate(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=(pred1,),\n                        renderer=null_renderer)\n            config.add_view(view=view2, request_method='GET',\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_custom_more_preds_first_bests_fewer_preds_last(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', xhr=True,\n                        renderer=null_renderer)\n        config.add_view(view=view2, request_method='GET',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_same_predicates(self):\n        view2 = lambda *arg: 'second'\n        view1 = lambda *arg: 'first'\n        config = self._makeOne()\n        config.add_view(view=view1)\n        config.add_view(view=view2)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, permission='view', renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               default_permission='view',\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_no_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        class DummyPolicy(object): pass # wont be called\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_mapper(self):\n        from pyramid.renderers import null_renderer\n        class Mapper(object):\n            def __init__(self, **kw):\n                self.__class__.kw = kw\n            def __call__(self, view):\n                return view\n        config = self._makeOne(autocommit=True)\n        def view(context, request): return 'OK'\n        config.add_view(view=view, mapper=Mapper, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        self.assertEqual(view(None, None), 'OK')\n        self.assertEqual(Mapper.kw['mapper'], Mapper)\n\n    def test_add_view_with_view_defaults(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_kwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view='pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            'pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_config_and_view_defaults_doesnt_conflict(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IFactory'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        config.commit() # does not raise\n\n    def test_add_view_with_view_config_and_view_defaults_conflicts(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_derive_view_function(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        result = config.derive_view(view, renderer=null_renderer)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne()\n        result = config.derive_view(\n            'pyramid.tests.test_config.dummy_view',\n            renderer=null_renderer)\n        self.assertFalse(result is dummy_view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_with_default_renderer_no_explicit_renderer(self):\n        config = self._makeOne()\n        class moo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return 'moo'\n        config.add_renderer(None, moo)\n        config.commit()\n        def view(request):\n            return 'OK'\n        result = config.derive_view(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None).body, b'moo')\n\n    def test_derive_view_with_default_renderer_with_explicit_renderer(self):\n        class moo(object): pass\n        class foo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'foo'\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        config.add_renderer(None, moo)\n        config.add_renderer('foo', foo)\n        config.commit()\n        result = config.derive_view(view, renderer='foo')\n        self.assertFalse(result is view)\n        request = self._makeRequest(config)\n        self.assertEqual(result(None, request).body, b'foo')\n\n    def test_add_static_view_here_no_utility_registered(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        config = self._makeOne(autocommit=True)\n        config.add_static_view('static', 'files', renderer=null_renderer)\n        request_type = self._getRouteRequestIface(config, '__static/')\n        self._assertRoute(config, '__static/', 'static/*subpath')\n        wrapped = config.registry.adapters.lookup(\n            (IViewClassifier, request_type, Interface), IView, name='')\n        from pyramid.request import Request\n        request = Request.blank('/static/minimal.txt')\n        request.subpath = ('minimal.txt', )\n        result = wrapped(None, request)\n        self.assertEqual(result.status, '200 OK')\n        self.assertTrue(result.body.startswith(b'<div'))\n\n    def test_add_static_view_package_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static',\n                               'pyramid.tests.test_config:files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_package_here_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static', 'files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_absolute(self):\n        import os\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        here = os.path.dirname(__file__)\n        static_path = os.path.join(here, 'files')\n        config.add_static_view('static', static_path)\n        self.assertEqual(info.added,\n                         [(config, 'static', static_path, {})])\n\n    def test_add_forbidden_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        config.add_forbidden_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_forbidden_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_forbidden_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_forbidden_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, name='foo')\n\n    def test_add_forbidden_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, permission='foo')\n\n    def test_add_forbidden_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, context='foo')\n\n    def test_add_forbidden_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, for_='foo')\n\n    def test_add_forbidden_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, http_cache='foo')\n\n    def test_add_forbidden_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPForbidden\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_forbidden_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPForbidden),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_notfound_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: arg\n        config.add_notfound_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, (None, request))\n\n    def test_add_notfound_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_notfound_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_notfound_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, name='foo')\n\n    def test_add_notfound_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, permission='foo')\n\n    def test_add_notfound_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, context='foo')\n\n    def test_add_notfound_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, for_='foo')\n\n    def test_add_notfound_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, http_cache='foo')\n\n    def test_add_notfound_view_append_slash(self):\n        from pyramid.response import Response\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/foo/')\n        def view(request): return Response('OK')\n        config.add_notfound_view(view, renderer=null_renderer,append_slash=True)\n        request = self._makeRequest(config)\n        request.environ['PATH_INFO'] = '/foo'\n        request.query_string = 'a=1&b=2'\n        request.path = '/scriptname/foo'\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result.location, '/scriptname/foo/?a=1&b=2')\n\n    def test_add_notfound_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPNotFound\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_notfound_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPNotFound),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    # Since Python 3 has to be all cool and fancy and different...\n    def _assertBody(self, response, value):\n        from pyramid.compat import text_type\n        if isinstance(value, text_type): # pragma: nocover\n            self.assertEqual(response.text, value)\n        else: # pragma: nocover\n            self.assertEqual(response.body, value)\n\n    def test_add_notfound_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_notfound_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_add_forbidden_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_forbidden_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_set_view_mapper(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        mapper = object()\n        config.set_view_mapper(mapper)\n        result = config.registry.getUtility(IViewMapperFactory)\n        self.assertEqual(result, mapper)\n\n    def test_set_view_mapper_dottedname(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        config.set_view_mapper('pyramid.tests.test_config')\n        result = config.registry.getUtility(IViewMapperFactory)\n        from pyramid.tests import test_config\n        self.assertEqual(result, test_config)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 1818,
                            "end_lineno": 1846,
                            "parent": {
                                "file_name": "pyramid/tests/test_config/test_views.py",
                                "type": "class",
                                "name": "TestViewsConfigurationMixin",
                                "content": "class TestViewsConfigurationMixin(unittest.TestCase):\n    def _makeOne(self, *arg, **kw):\n        from pyramid.config import Configurator\n        config = Configurator(*arg, **kw)\n        return config\n\n    def _getViewCallable(self, config, ctx_iface=None, request_iface=None,\n                         name='', exception_view=False):\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        if exception_view:\n            classifier = IExceptionViewClassifier\n        else:\n            classifier = IViewClassifier\n        if ctx_iface is None:\n            ctx_iface = Interface\n        if request_iface is None:\n            request_iface = IRequest\n        return config.registry.adapters.lookup(\n            (classifier, request_iface, ctx_iface), IView, name=name,\n            default=None)\n\n    def _registerRenderer(self, config, name='.txt'):\n        from pyramid.interfaces import IRendererFactory\n        class Renderer:\n            def __init__(self, info):\n                self.__class__.info = info\n            def __call__(self, *arg):\n                return b'Hello!'\n        config.registry.registerUtility(Renderer, IRendererFactory, name=name)\n        return Renderer\n\n    def _makeRequest(self, config):\n        request = DummyRequest()\n        request.registry = config.registry\n        return request\n\n    def _assertNotFound(self, wrapper, *arg):\n        from pyramid.httpexceptions import HTTPNotFound\n        self.assertRaises(HTTPNotFound, wrapper, *arg)\n\n    def _getRouteRequestIface(self, config, name):\n        from pyramid.interfaces import IRouteRequest\n        iface = config.registry.getUtility(IRouteRequest, name)\n        return iface\n\n    def _assertRoute(self, config, name, path, num_predicates=0):\n        from pyramid.interfaces import IRoutesMapper\n        mapper = config.registry.getUtility(IRoutesMapper)\n        routes = mapper.get_routes()\n        route = routes[0]\n        self.assertEqual(len(routes), 1)\n        self.assertEqual(route.name, name)\n        self.assertEqual(route.path, path)\n        self.assertEqual(len(routes[0].predicates), num_predicates)\n        return route\n\n    def test_add_view_view_callable_None_no_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError, config.add_view)\n\n    def test_add_view_with_request_type_and_route_name(self):\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        self.assertRaises(ConfigurationError, config.add_view, view, '', None,\n                          None, True, True)\n\n    def test_add_view_with_request_type(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        from pyramid.interfaces import IRequest\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view,\n                        request_type='pyramid.interfaces.IRequest',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = DummyRequest()\n        self._assertNotFound(wrapper, None, request)\n        directlyProvides(request, IRequest)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_view_callable_None_with_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self._registerRenderer(config, name='dummy')\n        config.add_view(renderer='dummy')\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n\n    def test_add_view_with_tmpl_renderer_factory_introspector_missing(self):\n        config = self._makeOne(autocommit=True)\n        config.introspection = False\n        config.introspector = None\n        config.add_view(renderer='dummy.pt')\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n        \n    def test_add_view_with_tmpl_renderer_factory_no_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector()\n        config.introspector = introspector\n        config.add_view(renderer='dummy.pt')\n        self.assertFalse(('renderer factories', '.pt') in\n                         introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n\n    def test_add_view_with_tmpl_renderer_factory_with_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector(True)\n        config.introspector = introspector\n        def dummy_factory(helper):\n            return lambda val, system_vals: 'Hello!'\n        config.add_renderer('.pt', dummy_factory)\n        config.add_view(renderer='dummy.pt')\n        self.assertTrue(\n            ('renderer factories', '.pt') in introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n        \n    def test_add_view_wrapped_view_is_decorated(self):\n        def view(request): # request-only wrapper\n            \"\"\" \"\"\"\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper.__module__, view.__module__)\n        self.assertEqual(wrapper.__name__, view.__name__)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        self.assertEqual(wrapper.__discriminator__(None, None).resolve()[0],\n                         'view')\n\n    def test_add_view_view_callable_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        config.add_view(view='pyramid.tests.test_config.dummy_view',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_function_callable(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_function_callable_requestonly(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, name='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name='abc')\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name_unicode(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        name = text_(b'La Pe\\xc3\\xb1a', 'utf-8')\n        config.add_view(view=view, name=name, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name=name)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper(fn):\n            def inner(context, request):\n                return fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=view_wrapper,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator_tuple(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper1(fn):\n            def inner(context, request):\n                return 'wrapped1' + fn(context, request)\n            return inner\n        def view_wrapper2(fn):\n            def inner(context, request):\n                return 'wrapped2' + fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=(view_wrapper2, view_wrapper1),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'wrapped2wrapped1OK')\n\n    def test_add_view_with_http_cache(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return response\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, http_cache=(86400, {'public':True}))\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        request = testing.DummyRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(days=1)\n        result = wrapper(None, request)\n        self.assertEqual(result, response)\n        headers = dict(response.headerlist)\n        self.assertEqual(headers['Cache-Control'], 'max-age=86400, public')\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n\n    def test_add_view_as_instance(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, context, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instance_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_oldstyle_class(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, context, request):\n                self.context = context\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_as_oldstyle_class_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, request):\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_context_as_class(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_iface(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context='pyramid.tests.test_config.IDummy',\n                        view=view,  renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for__as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_='pyramid.tests.test_config.IDummy',\n                        view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_class(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_iface(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_trumps_for(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        class Foo:\n            pass\n        config.add_view(context=IDummy, for_=Foo, view=view,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_exception_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_mixed_case_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/HTML', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.media_views.items()),1)\n        self.assertFalse('text/HTML' in wrapper.media_views)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_views_with_accept_multiview_replaces_existing(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(len(wrapper.media_views['text/html']), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_view_exc_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, accept='text/html', context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_multiview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_mulview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_exc_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_multiview_context_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        class ISuper(Interface):\n            pass\n        class ISub(ISuper):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, ISuper), IView, name='')\n        config.add_view(view=view2, for_=ISub, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, ISuper, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n        wrapper = self._getViewCallable(config, ISub, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK2')\n\n    def test_add_view_multiview_exception_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        class Super(Exception):\n            pass\n        class Sub(Super):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Super), IView, name='')\n        config.registry.registerAdapter(\n            view, (IExceptionViewClassifier, IRequest, Super), IView, name='')\n        config.add_view(view=view2, for_=Sub, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, implementedBy(Super), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Super), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n        wrapper = self._getViewCallable(\n            config, implementedBy(Sub), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Sub), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK2')\n\n    def test_add_view_multiview_call_ordering(self):\n        from pyramid.renderers import null_renderer as nr\n        from zope.interface import directlyProvides\n        def view1(context, request): return 'view1'\n        def view2(context, request): return 'view2'\n        def view3(context, request): return 'view3'\n        def view4(context, request): return 'view4'\n        def view5(context, request): return 'view5'\n        def view6(context, request): return 'view6'\n        def view7(context, request): return 'view7'\n        def view8(context, request): return 'view8'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view1, renderer=nr)\n        config.add_view(view=view2, request_method='POST', renderer=nr)\n        config.add_view(view=view3,request_param='param', renderer=nr)\n        config.add_view(view=view4, containment=IDummy, renderer=nr)\n        config.add_view(view=view5, request_method='POST',\n                        request_param='param',  renderer=nr)\n        config.add_view(view=view6, request_method='POST', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view7, request_param='param', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view8, request_method='POST',request_param='param',\n                        containment=IDummy, renderer=nr)\n\n\n        wrapper = self._getViewCallable(config)\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view1')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view2')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {'param':'1'}\n        request.method = 'GET'\n        self.assertEqual(wrapper(ctx, request), 'view3')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view4')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view5')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view6')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view7')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view8')\n\n    def test_add_view_multiview___discriminator__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        class IFoo(Interface):\n            pass\n        class IBar(Interface):\n            pass\n        @implementer(IFoo)\n        class Foo(object):\n            pass\n        @implementer(IBar)\n        class Bar(object):\n            pass\n        foo = Foo()\n        bar = Bar()\n\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IFoo)\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IBar)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        request = self._makeRequest(config)\n        self.assertNotEqual(\n            wrapper.__discriminator__(foo, request),\n            wrapper.__discriminator__(bar, request),\n            )\n\n    def test_add_view_with_template_renderer(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=view, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_default_renderer(self):\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        class moo(object):\n            def __init__(self, *arg, **kw):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'moo'\n        config.add_renderer(None, moo)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'moo')\n\n    def test_add_view_with_template_renderer_no_callable(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=None, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_request_type_as_iface(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        def view(context, request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(request_type=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, None)\n        request = self._makeRequest(config)\n        directlyProvides(request, IDummy)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_request_type_as_noniface(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        self.assertRaises(ConfigurationError,\n                          config.add_view, view, '', None, None, object)\n\n    def test_add_view_with_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        self.assertNotEqual(request_iface, None)\n        wrapper = self._getViewCallable(config, request_iface=request_iface)\n        self.assertNotEqual(wrapper, None)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_nonexistant_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        self.assertRaises(ConfigurationExecutionError, config.commit)\n\n    def test_add_view_with_route_name_exception(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', context=RuntimeError,\n                        renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        wrapper_exc_view = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface, exception_view=True)\n        self.assertNotEqual(wrapper_exc_view, None)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n\n    def test_add_view_with_request_method_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_sequence_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_sequence_conflict(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        config.add_view(view=view, request_method=('GET', 'POST'),\n                        renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_request_method_sequence_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'HEAD'))\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_get_implies_head(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'HEAD'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_param_val_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':'123'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_val_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_xhr_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_xhr_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = False\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, header='Host:a\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_header_noval_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'whatever'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_noval_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NotHost':'whatever'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'1'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_val_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'abc'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_missing(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NoHost':'1'}\n        self.assertRaises(HTTPNotFound, wrapper, None, request)\n\n    def test_add_view_with_accept_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/xml']\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_accept_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/html']\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_containment_true(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_containment_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        self._assertNotFound(wrapper, context, None)\n\n    def test_add_view_with_containment_dottedname(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            containment='pyramid.tests.test_config.IDummy',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_path_info_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, path_info='\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_path_info_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_(b'/foo')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_path_info_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_('/')\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_custom_predicates_match(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return True\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates,\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_custom_predicates_nomatch(self):\n        import warnings\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return False\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_custom_predicate_bests_standard_predicate(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=(pred1,),\n                        renderer=null_renderer)\n            config.add_view(view=view2, request_method='GET',\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_custom_more_preds_first_bests_fewer_preds_last(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', xhr=True,\n                        renderer=null_renderer)\n        config.add_view(view=view2, request_method='GET',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_same_predicates(self):\n        view2 = lambda *arg: 'second'\n        view1 = lambda *arg: 'first'\n        config = self._makeOne()\n        config.add_view(view=view1)\n        config.add_view(view=view2)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, permission='view', renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               default_permission='view',\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_no_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        class DummyPolicy(object): pass # wont be called\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_mapper(self):\n        from pyramid.renderers import null_renderer\n        class Mapper(object):\n            def __init__(self, **kw):\n                self.__class__.kw = kw\n            def __call__(self, view):\n                return view\n        config = self._makeOne(autocommit=True)\n        def view(context, request): return 'OK'\n        config.add_view(view=view, mapper=Mapper, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        self.assertEqual(view(None, None), 'OK')\n        self.assertEqual(Mapper.kw['mapper'], Mapper)\n\n    def test_add_view_with_view_defaults(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_kwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view='pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            'pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_config_and_view_defaults_doesnt_conflict(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IFactory'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        config.commit() # does not raise\n\n    def test_add_view_with_view_config_and_view_defaults_conflicts(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_derive_view_function(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        result = config.derive_view(view, renderer=null_renderer)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne()\n        result = config.derive_view(\n            'pyramid.tests.test_config.dummy_view',\n            renderer=null_renderer)\n        self.assertFalse(result is dummy_view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_with_default_renderer_no_explicit_renderer(self):\n        config = self._makeOne()\n        class moo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return 'moo'\n        config.add_renderer(None, moo)\n        config.commit()\n        def view(request):\n            return 'OK'\n        result = config.derive_view(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None).body, b'moo')\n\n    def test_derive_view_with_default_renderer_with_explicit_renderer(self):\n        class moo(object): pass\n        class foo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'foo'\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        config.add_renderer(None, moo)\n        config.add_renderer('foo', foo)\n        config.commit()\n        result = config.derive_view(view, renderer='foo')\n        self.assertFalse(result is view)\n        request = self._makeRequest(config)\n        self.assertEqual(result(None, request).body, b'foo')\n\n    def test_add_static_view_here_no_utility_registered(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        config = self._makeOne(autocommit=True)\n        config.add_static_view('static', 'files', renderer=null_renderer)\n        request_type = self._getRouteRequestIface(config, '__static/')\n        self._assertRoute(config, '__static/', 'static/*subpath')\n        wrapped = config.registry.adapters.lookup(\n            (IViewClassifier, request_type, Interface), IView, name='')\n        from pyramid.request import Request\n        request = Request.blank('/static/minimal.txt')\n        request.subpath = ('minimal.txt', )\n        result = wrapped(None, request)\n        self.assertEqual(result.status, '200 OK')\n        self.assertTrue(result.body.startswith(b'<div'))\n\n    def test_add_static_view_package_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static',\n                               'pyramid.tests.test_config:files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_package_here_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static', 'files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_absolute(self):\n        import os\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        here = os.path.dirname(__file__)\n        static_path = os.path.join(here, 'files')\n        config.add_static_view('static', static_path)\n        self.assertEqual(info.added,\n                         [(config, 'static', static_path, {})])\n\n    def test_add_forbidden_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        config.add_forbidden_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_forbidden_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_forbidden_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_forbidden_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, name='foo')\n\n    def test_add_forbidden_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, permission='foo')\n\n    def test_add_forbidden_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, context='foo')\n\n    def test_add_forbidden_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, for_='foo')\n\n    def test_add_forbidden_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, http_cache='foo')\n\n    def test_add_forbidden_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPForbidden\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_forbidden_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPForbidden),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_notfound_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: arg\n        config.add_notfound_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, (None, request))\n\n    def test_add_notfound_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_notfound_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_notfound_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, name='foo')\n\n    def test_add_notfound_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, permission='foo')\n\n    def test_add_notfound_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, context='foo')\n\n    def test_add_notfound_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, for_='foo')\n\n    def test_add_notfound_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, http_cache='foo')\n\n    def test_add_notfound_view_append_slash(self):\n        from pyramid.response import Response\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/foo/')\n        def view(request): return Response('OK')\n        config.add_notfound_view(view, renderer=null_renderer,append_slash=True)\n        request = self._makeRequest(config)\n        request.environ['PATH_INFO'] = '/foo'\n        request.query_string = 'a=1&b=2'\n        request.path = '/scriptname/foo'\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result.location, '/scriptname/foo/?a=1&b=2')\n\n    def test_add_notfound_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPNotFound\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_notfound_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPNotFound),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    # Since Python 3 has to be all cool and fancy and different...\n    def _assertBody(self, response, value):\n        from pyramid.compat import text_type\n        if isinstance(value, text_type): # pragma: nocover\n            self.assertEqual(response.text, value)\n        else: # pragma: nocover\n            self.assertEqual(response.body, value)\n\n    def test_add_notfound_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_notfound_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_add_forbidden_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_forbidden_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_set_view_mapper(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        mapper = object()\n        config.set_view_mapper(mapper)\n        result = config.registry.getUtility(IViewMapperFactory)\n        self.assertEqual(result, mapper)\n\n    def test_set_view_mapper_dottedname(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        config.set_view_mapper('pyramid.tests.test_config')\n        result = config.registry.getUtility(IViewMapperFactory)\n        from pyramid.tests import test_config\n        self.assertEqual(result, test_config)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 16,
                                "end_lineno": 2001,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 1882,
                            "length": 6
                        },
                        "new_range": {
                            "start": 1912,
                            "length": 36
                        },
                        "section": "class TestViewsConfigurationMixin(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        result = view(None, request)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(result.location, '/scriptname/foo/?a=1&b=2')",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_add_notfound_view_with_view_defaults(self):",
                                "type": "added"
                            },
                            {
                                "content": "        from pyramid.interfaces import IRequest",
                                "type": "added"
                            },
                            {
                                "content": "        from pyramid.renderers import null_renderer",
                                "type": "added"
                            },
                            {
                                "content": "        from pyramid.exceptions import PredicateMismatch",
                                "type": "added"
                            },
                            {
                                "content": "        from pyramid.httpexceptions import HTTPNotFound",
                                "type": "added"
                            },
                            {
                                "content": "        from zope.interface import directlyProvides",
                                "type": "added"
                            },
                            {
                                "content": "        from zope.interface import implementedBy",
                                "type": "added"
                            },
                            {
                                "content": "        class view(object):",
                                "type": "added"
                            },
                            {
                                "content": "            __view_defaults__ = {",
                                "type": "added"
                            },
                            {
                                "content": "                'containment':'pyramid.tests.test_config.IDummy'",
                                "type": "added"
                            },
                            {
                                "content": "                }",
                                "type": "added"
                            },
                            {
                                "content": "            def __init__(self, request):",
                                "type": "added"
                            },
                            {
                                "content": "                pass",
                                "type": "added"
                            },
                            {
                                "content": "            def __call__(self):",
                                "type": "added"
                            },
                            {
                                "content": "                return 'OK'",
                                "type": "added"
                            },
                            {
                                "content": "        config = self._makeOne(autocommit=True)",
                                "type": "added"
                            },
                            {
                                "content": "        config.add_notfound_view(",
                                "type": "added"
                            },
                            {
                                "content": "            view=view,",
                                "type": "added"
                            },
                            {
                                "content": "            renderer=null_renderer)",
                                "type": "added"
                            },
                            {
                                "content": "        wrapper = self._getViewCallable(",
                                "type": "added"
                            },
                            {
                                "content": "            config, ctx_iface=implementedBy(HTTPNotFound),",
                                "type": "added"
                            },
                            {
                                "content": "            request_iface=IRequest)",
                                "type": "added"
                            },
                            {
                                "content": "        context = DummyContext()",
                                "type": "added"
                            },
                            {
                                "content": "        directlyProvides(context, IDummy)",
                                "type": "added"
                            },
                            {
                                "content": "        request = self._makeRequest(config)",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(wrapper(context, request), 'OK')",
                                "type": "added"
                            },
                            {
                                "content": "        context = DummyContext()",
                                "type": "added"
                            },
                            {
                                "content": "        request = self._makeRequest(config)",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertRaises(PredicateMismatch, wrapper, context, request)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    # Since Python 3 has to be all cool and fancy and different...",
                                "type": "context"
                            },
                            {
                                "content": "    def _assertBody(self, response, value):",
                                "type": "context"
                            },
                            {
                                "content": "        from pyramid.compat import text_type",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "pyramid/tests/test_config/test_views.py",
                            "type": "class",
                            "name": "TestViewsConfigurationMixin",
                            "content": "class TestViewsConfigurationMixin(unittest.TestCase):\n    def _makeOne(self, *arg, **kw):\n        from pyramid.config import Configurator\n        config = Configurator(*arg, **kw)\n        return config\n\n    def _getViewCallable(self, config, ctx_iface=None, request_iface=None,\n                         name='', exception_view=False):\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        if exception_view:\n            classifier = IExceptionViewClassifier\n        else:\n            classifier = IViewClassifier\n        if ctx_iface is None:\n            ctx_iface = Interface\n        if request_iface is None:\n            request_iface = IRequest\n        return config.registry.adapters.lookup(\n            (classifier, request_iface, ctx_iface), IView, name=name,\n            default=None)\n\n    def _registerRenderer(self, config, name='.txt'):\n        from pyramid.interfaces import IRendererFactory\n        class Renderer:\n            def __init__(self, info):\n                self.__class__.info = info\n            def __call__(self, *arg):\n                return b'Hello!'\n        config.registry.registerUtility(Renderer, IRendererFactory, name=name)\n        return Renderer\n\n    def _makeRequest(self, config):\n        request = DummyRequest()\n        request.registry = config.registry\n        return request\n\n    def _assertNotFound(self, wrapper, *arg):\n        from pyramid.httpexceptions import HTTPNotFound\n        self.assertRaises(HTTPNotFound, wrapper, *arg)\n\n    def _getRouteRequestIface(self, config, name):\n        from pyramid.interfaces import IRouteRequest\n        iface = config.registry.getUtility(IRouteRequest, name)\n        return iface\n\n    def _assertRoute(self, config, name, path, num_predicates=0):\n        from pyramid.interfaces import IRoutesMapper\n        mapper = config.registry.getUtility(IRoutesMapper)\n        routes = mapper.get_routes()\n        route = routes[0]\n        self.assertEqual(len(routes), 1)\n        self.assertEqual(route.name, name)\n        self.assertEqual(route.path, path)\n        self.assertEqual(len(routes[0].predicates), num_predicates)\n        return route\n\n    def test_add_view_view_callable_None_no_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError, config.add_view)\n\n    def test_add_view_with_request_type_and_route_name(self):\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        self.assertRaises(ConfigurationError, config.add_view, view, '', None,\n                          None, True, True)\n\n    def test_add_view_with_request_type(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        from pyramid.interfaces import IRequest\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view,\n                        request_type='pyramid.interfaces.IRequest',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = DummyRequest()\n        self._assertNotFound(wrapper, None, request)\n        directlyProvides(request, IRequest)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_view_callable_None_with_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self._registerRenderer(config, name='dummy')\n        config.add_view(renderer='dummy')\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n\n    def test_add_view_with_tmpl_renderer_factory_introspector_missing(self):\n        config = self._makeOne(autocommit=True)\n        config.introspection = False\n        config.introspector = None\n        config.add_view(renderer='dummy.pt')\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n        \n    def test_add_view_with_tmpl_renderer_factory_no_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector()\n        config.introspector = introspector\n        config.add_view(renderer='dummy.pt')\n        self.assertFalse(('renderer factories', '.pt') in\n                         introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n\n    def test_add_view_with_tmpl_renderer_factory_with_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector(True)\n        config.introspector = introspector\n        def dummy_factory(helper):\n            return lambda val, system_vals: 'Hello!'\n        config.add_renderer('.pt', dummy_factory)\n        config.add_view(renderer='dummy.pt')\n        self.assertTrue(\n            ('renderer factories', '.pt') in introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n        \n    def test_add_view_wrapped_view_is_decorated(self):\n        def view(request): # request-only wrapper\n            \"\"\" \"\"\"\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper.__module__, view.__module__)\n        self.assertEqual(wrapper.__name__, view.__name__)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        self.assertEqual(wrapper.__discriminator__(None, None).resolve()[0],\n                         'view')\n\n    def test_add_view_view_callable_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        config.add_view(view='pyramid.tests.test_config.dummy_view',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_function_callable(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_function_callable_requestonly(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, name='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name='abc')\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name_unicode(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        name = text_(b'La Pe\\xc3\\xb1a', 'utf-8')\n        config.add_view(view=view, name=name, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name=name)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper(fn):\n            def inner(context, request):\n                return fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=view_wrapper,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator_tuple(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper1(fn):\n            def inner(context, request):\n                return 'wrapped1' + fn(context, request)\n            return inner\n        def view_wrapper2(fn):\n            def inner(context, request):\n                return 'wrapped2' + fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=(view_wrapper2, view_wrapper1),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'wrapped2wrapped1OK')\n\n    def test_add_view_with_http_cache(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return response\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, http_cache=(86400, {'public':True}))\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        request = testing.DummyRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(days=1)\n        result = wrapper(None, request)\n        self.assertEqual(result, response)\n        headers = dict(response.headerlist)\n        self.assertEqual(headers['Cache-Control'], 'max-age=86400, public')\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n\n    def test_add_view_as_instance(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, context, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instance_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_oldstyle_class(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, context, request):\n                self.context = context\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_as_oldstyle_class_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, request):\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_context_as_class(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_iface(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context='pyramid.tests.test_config.IDummy',\n                        view=view,  renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for__as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_='pyramid.tests.test_config.IDummy',\n                        view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_class(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_iface(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_trumps_for(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        class Foo:\n            pass\n        config.add_view(context=IDummy, for_=Foo, view=view,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_exception_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_mixed_case_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/HTML', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.media_views.items()),1)\n        self.assertFalse('text/HTML' in wrapper.media_views)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_views_with_accept_multiview_replaces_existing(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(len(wrapper.media_views['text/html']), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_view_exc_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, accept='text/html', context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_multiview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_mulview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_exc_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_multiview_context_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        class ISuper(Interface):\n            pass\n        class ISub(ISuper):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, ISuper), IView, name='')\n        config.add_view(view=view2, for_=ISub, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, ISuper, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n        wrapper = self._getViewCallable(config, ISub, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK2')\n\n    def test_add_view_multiview_exception_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        class Super(Exception):\n            pass\n        class Sub(Super):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Super), IView, name='')\n        config.registry.registerAdapter(\n            view, (IExceptionViewClassifier, IRequest, Super), IView, name='')\n        config.add_view(view=view2, for_=Sub, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, implementedBy(Super), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Super), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n        wrapper = self._getViewCallable(\n            config, implementedBy(Sub), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Sub), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK2')\n\n    def test_add_view_multiview_call_ordering(self):\n        from pyramid.renderers import null_renderer as nr\n        from zope.interface import directlyProvides\n        def view1(context, request): return 'view1'\n        def view2(context, request): return 'view2'\n        def view3(context, request): return 'view3'\n        def view4(context, request): return 'view4'\n        def view5(context, request): return 'view5'\n        def view6(context, request): return 'view6'\n        def view7(context, request): return 'view7'\n        def view8(context, request): return 'view8'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view1, renderer=nr)\n        config.add_view(view=view2, request_method='POST', renderer=nr)\n        config.add_view(view=view3,request_param='param', renderer=nr)\n        config.add_view(view=view4, containment=IDummy, renderer=nr)\n        config.add_view(view=view5, request_method='POST',\n                        request_param='param',  renderer=nr)\n        config.add_view(view=view6, request_method='POST', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view7, request_param='param', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view8, request_method='POST',request_param='param',\n                        containment=IDummy, renderer=nr)\n\n\n        wrapper = self._getViewCallable(config)\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view1')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view2')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {'param':'1'}\n        request.method = 'GET'\n        self.assertEqual(wrapper(ctx, request), 'view3')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view4')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view5')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view6')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view7')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view8')\n\n    def test_add_view_multiview___discriminator__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        class IFoo(Interface):\n            pass\n        class IBar(Interface):\n            pass\n        @implementer(IFoo)\n        class Foo(object):\n            pass\n        @implementer(IBar)\n        class Bar(object):\n            pass\n        foo = Foo()\n        bar = Bar()\n\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IFoo)\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IBar)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        request = self._makeRequest(config)\n        self.assertNotEqual(\n            wrapper.__discriminator__(foo, request),\n            wrapper.__discriminator__(bar, request),\n            )\n\n    def test_add_view_with_template_renderer(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=view, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_default_renderer(self):\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        class moo(object):\n            def __init__(self, *arg, **kw):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'moo'\n        config.add_renderer(None, moo)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'moo')\n\n    def test_add_view_with_template_renderer_no_callable(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=None, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_request_type_as_iface(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        def view(context, request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(request_type=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, None)\n        request = self._makeRequest(config)\n        directlyProvides(request, IDummy)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_request_type_as_noniface(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        self.assertRaises(ConfigurationError,\n                          config.add_view, view, '', None, None, object)\n\n    def test_add_view_with_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        self.assertNotEqual(request_iface, None)\n        wrapper = self._getViewCallable(config, request_iface=request_iface)\n        self.assertNotEqual(wrapper, None)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_nonexistant_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        self.assertRaises(ConfigurationExecutionError, config.commit)\n\n    def test_add_view_with_route_name_exception(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', context=RuntimeError,\n                        renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        wrapper_exc_view = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface, exception_view=True)\n        self.assertNotEqual(wrapper_exc_view, None)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n\n    def test_add_view_with_request_method_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_sequence_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_sequence_conflict(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        config.add_view(view=view, request_method=('GET', 'POST'),\n                        renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_request_method_sequence_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'HEAD'))\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_get_implies_head(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'HEAD'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_param_val_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':'123'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_val_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_xhr_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_xhr_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = False\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, header='Host:a\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_header_noval_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'whatever'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_noval_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NotHost':'whatever'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'1'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_val_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'abc'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_missing(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NoHost':'1'}\n        self.assertRaises(HTTPNotFound, wrapper, None, request)\n\n    def test_add_view_with_accept_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/xml']\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_accept_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/html']\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_containment_true(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_containment_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        self._assertNotFound(wrapper, context, None)\n\n    def test_add_view_with_containment_dottedname(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            containment='pyramid.tests.test_config.IDummy',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_path_info_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, path_info='\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_path_info_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_(b'/foo')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_path_info_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_('/')\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_custom_predicates_match(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return True\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates,\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_custom_predicates_nomatch(self):\n        import warnings\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return False\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_custom_predicate_bests_standard_predicate(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=(pred1,),\n                        renderer=null_renderer)\n            config.add_view(view=view2, request_method='GET',\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_custom_more_preds_first_bests_fewer_preds_last(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', xhr=True,\n                        renderer=null_renderer)\n        config.add_view(view=view2, request_method='GET',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_same_predicates(self):\n        view2 = lambda *arg: 'second'\n        view1 = lambda *arg: 'first'\n        config = self._makeOne()\n        config.add_view(view=view1)\n        config.add_view(view=view2)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, permission='view', renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               default_permission='view',\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_no_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        class DummyPolicy(object): pass # wont be called\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_mapper(self):\n        from pyramid.renderers import null_renderer\n        class Mapper(object):\n            def __init__(self, **kw):\n                self.__class__.kw = kw\n            def __call__(self, view):\n                return view\n        config = self._makeOne(autocommit=True)\n        def view(context, request): return 'OK'\n        config.add_view(view=view, mapper=Mapper, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        self.assertEqual(view(None, None), 'OK')\n        self.assertEqual(Mapper.kw['mapper'], Mapper)\n\n    def test_add_view_with_view_defaults(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_kwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view='pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            'pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_config_and_view_defaults_doesnt_conflict(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IFactory'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        config.commit() # does not raise\n\n    def test_add_view_with_view_config_and_view_defaults_conflicts(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_derive_view_function(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        result = config.derive_view(view, renderer=null_renderer)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne()\n        result = config.derive_view(\n            'pyramid.tests.test_config.dummy_view',\n            renderer=null_renderer)\n        self.assertFalse(result is dummy_view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_with_default_renderer_no_explicit_renderer(self):\n        config = self._makeOne()\n        class moo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return 'moo'\n        config.add_renderer(None, moo)\n        config.commit()\n        def view(request):\n            return 'OK'\n        result = config.derive_view(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None).body, b'moo')\n\n    def test_derive_view_with_default_renderer_with_explicit_renderer(self):\n        class moo(object): pass\n        class foo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'foo'\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        config.add_renderer(None, moo)\n        config.add_renderer('foo', foo)\n        config.commit()\n        result = config.derive_view(view, renderer='foo')\n        self.assertFalse(result is view)\n        request = self._makeRequest(config)\n        self.assertEqual(result(None, request).body, b'foo')\n\n    def test_add_static_view_here_no_utility_registered(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        config = self._makeOne(autocommit=True)\n        config.add_static_view('static', 'files', renderer=null_renderer)\n        request_type = self._getRouteRequestIface(config, '__static/')\n        self._assertRoute(config, '__static/', 'static/*subpath')\n        wrapped = config.registry.adapters.lookup(\n            (IViewClassifier, request_type, Interface), IView, name='')\n        from pyramid.request import Request\n        request = Request.blank('/static/minimal.txt')\n        request.subpath = ('minimal.txt', )\n        result = wrapped(None, request)\n        self.assertEqual(result.status, '200 OK')\n        self.assertTrue(result.body.startswith(b'<div'))\n\n    def test_add_static_view_package_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static',\n                               'pyramid.tests.test_config:files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_package_here_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static', 'files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_absolute(self):\n        import os\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        here = os.path.dirname(__file__)\n        static_path = os.path.join(here, 'files')\n        config.add_static_view('static', static_path)\n        self.assertEqual(info.added,\n                         [(config, 'static', static_path, {})])\n\n    def test_add_forbidden_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        config.add_forbidden_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_forbidden_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_forbidden_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_forbidden_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, name='foo')\n\n    def test_add_forbidden_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, permission='foo')\n\n    def test_add_forbidden_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, context='foo')\n\n    def test_add_forbidden_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, for_='foo')\n\n    def test_add_forbidden_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, http_cache='foo')\n\n    def test_add_forbidden_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPForbidden\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_forbidden_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPForbidden),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_notfound_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: arg\n        config.add_notfound_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, (None, request))\n\n    def test_add_notfound_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_notfound_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_notfound_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, name='foo')\n\n    def test_add_notfound_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, permission='foo')\n\n    def test_add_notfound_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, context='foo')\n\n    def test_add_notfound_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, for_='foo')\n\n    def test_add_notfound_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, http_cache='foo')\n\n    def test_add_notfound_view_append_slash(self):\n        from pyramid.response import Response\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/foo/')\n        def view(request): return Response('OK')\n        config.add_notfound_view(view, renderer=null_renderer,append_slash=True)\n        request = self._makeRequest(config)\n        request.environ['PATH_INFO'] = '/foo'\n        request.query_string = 'a=1&b=2'\n        request.path = '/scriptname/foo'\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result.location, '/scriptname/foo/?a=1&b=2')\n\n    def test_add_notfound_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPNotFound\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_notfound_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPNotFound),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    # Since Python 3 has to be all cool and fancy and different...\n    def _assertBody(self, response, value):\n        from pyramid.compat import text_type\n        if isinstance(value, text_type): # pragma: nocover\n            self.assertEqual(response.text, value)\n        else: # pragma: nocover\n            self.assertEqual(response.body, value)\n\n    def test_add_notfound_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_notfound_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_add_forbidden_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_forbidden_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_set_view_mapper(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        mapper = object()\n        config.set_view_mapper(mapper)\n        result = config.registry.getUtility(IViewMapperFactory)\n        self.assertEqual(result, mapper)\n\n    def test_set_view_mapper_dottedname(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        config.set_view_mapper('pyramid.tests.test_config')\n        result = config.registry.getUtility(IViewMapperFactory)\n        from pyramid.tests import test_config\n        self.assertEqual(result, test_config)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 16,
                            "end_lineno": 2001,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "pyramid/tests/test_config/test_views.py",
                            "type": "method",
                            "name": "TestViewsConfigurationMixin.test_add_notfound_view_with_view_defaults",
                            "content": "class TestViewsConfigurationMixin(unittest.TestCase):\n    def _makeOne(self, *arg, **kw):\n        from pyramid.config import Configurator\n        config = Configurator(*arg, **kw)\n        return config\n\n    def _getViewCallable(self, config, ctx_iface=None, request_iface=None,\n                         name='', exception_view=False):\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        if exception_view:\n            classifier = IExceptionViewClassifier\n        else:\n            classifier = IViewClassifier\n        if ctx_iface is None:\n            ctx_iface = Interface\n        if request_iface is None:\n            request_iface = IRequest\n        return config.registry.adapters.lookup(\n            (classifier, request_iface, ctx_iface), IView, name=name,\n            default=None)\n\n    def _registerRenderer(self, config, name='.txt'):\n        from pyramid.interfaces import IRendererFactory\n        class Renderer:\n            def __init__(self, info):\n                self.__class__.info = info\n            def __call__(self, *arg):\n                return b'Hello!'\n        config.registry.registerUtility(Renderer, IRendererFactory, name=name)\n        return Renderer\n\n    def _makeRequest(self, config):\n        request = DummyRequest()\n        request.registry = config.registry\n        return request\n\n    def _assertNotFound(self, wrapper, *arg):\n        from pyramid.httpexceptions import HTTPNotFound\n        self.assertRaises(HTTPNotFound, wrapper, *arg)\n\n    def _getRouteRequestIface(self, config, name):\n        from pyramid.interfaces import IRouteRequest\n        iface = config.registry.getUtility(IRouteRequest, name)\n        return iface\n\n    def _assertRoute(self, config, name, path, num_predicates=0):\n        from pyramid.interfaces import IRoutesMapper\n        mapper = config.registry.getUtility(IRoutesMapper)\n        routes = mapper.get_routes()\n        route = routes[0]\n        self.assertEqual(len(routes), 1)\n        self.assertEqual(route.name, name)\n        self.assertEqual(route.path, path)\n        self.assertEqual(len(routes[0].predicates), num_predicates)\n        return route\n\n    def test_add_view_view_callable_None_no_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError, config.add_view)\n\n    def test_add_view_with_request_type_and_route_name(self):\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        self.assertRaises(ConfigurationError, config.add_view, view, '', None,\n                          None, True, True)\n\n    def test_add_view_with_request_type(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        from pyramid.interfaces import IRequest\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view,\n                        request_type='pyramid.interfaces.IRequest',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = DummyRequest()\n        self._assertNotFound(wrapper, None, request)\n        directlyProvides(request, IRequest)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_view_callable_None_with_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self._registerRenderer(config, name='dummy')\n        config.add_view(renderer='dummy')\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n\n    def test_add_view_with_tmpl_renderer_factory_introspector_missing(self):\n        config = self._makeOne(autocommit=True)\n        config.introspection = False\n        config.introspector = None\n        config.add_view(renderer='dummy.pt')\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n        \n    def test_add_view_with_tmpl_renderer_factory_no_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector()\n        config.introspector = introspector\n        config.add_view(renderer='dummy.pt')\n        self.assertFalse(('renderer factories', '.pt') in\n                         introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n\n    def test_add_view_with_tmpl_renderer_factory_with_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector(True)\n        config.introspector = introspector\n        def dummy_factory(helper):\n            return lambda val, system_vals: 'Hello!'\n        config.add_renderer('.pt', dummy_factory)\n        config.add_view(renderer='dummy.pt')\n        self.assertTrue(\n            ('renderer factories', '.pt') in introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n        \n    def test_add_view_wrapped_view_is_decorated(self):\n        def view(request): # request-only wrapper\n            \"\"\" \"\"\"\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper.__module__, view.__module__)\n        self.assertEqual(wrapper.__name__, view.__name__)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        self.assertEqual(wrapper.__discriminator__(None, None).resolve()[0],\n                         'view')\n\n    def test_add_view_view_callable_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        config.add_view(view='pyramid.tests.test_config.dummy_view',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_function_callable(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_function_callable_requestonly(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, name='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name='abc')\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name_unicode(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        name = text_(b'La Pe\\xc3\\xb1a', 'utf-8')\n        config.add_view(view=view, name=name, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name=name)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper(fn):\n            def inner(context, request):\n                return fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=view_wrapper,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator_tuple(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper1(fn):\n            def inner(context, request):\n                return 'wrapped1' + fn(context, request)\n            return inner\n        def view_wrapper2(fn):\n            def inner(context, request):\n                return 'wrapped2' + fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=(view_wrapper2, view_wrapper1),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'wrapped2wrapped1OK')\n\n    def test_add_view_with_http_cache(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return response\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, http_cache=(86400, {'public':True}))\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        request = testing.DummyRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(days=1)\n        result = wrapper(None, request)\n        self.assertEqual(result, response)\n        headers = dict(response.headerlist)\n        self.assertEqual(headers['Cache-Control'], 'max-age=86400, public')\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n\n    def test_add_view_as_instance(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, context, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instance_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_oldstyle_class(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, context, request):\n                self.context = context\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_as_oldstyle_class_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, request):\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_context_as_class(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_iface(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context='pyramid.tests.test_config.IDummy',\n                        view=view,  renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for__as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_='pyramid.tests.test_config.IDummy',\n                        view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_class(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_iface(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_trumps_for(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        class Foo:\n            pass\n        config.add_view(context=IDummy, for_=Foo, view=view,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_exception_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_mixed_case_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/HTML', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.media_views.items()),1)\n        self.assertFalse('text/HTML' in wrapper.media_views)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_views_with_accept_multiview_replaces_existing(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(len(wrapper.media_views['text/html']), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_view_exc_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, accept='text/html', context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_multiview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_mulview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_exc_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_multiview_context_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        class ISuper(Interface):\n            pass\n        class ISub(ISuper):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, ISuper), IView, name='')\n        config.add_view(view=view2, for_=ISub, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, ISuper, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n        wrapper = self._getViewCallable(config, ISub, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK2')\n\n    def test_add_view_multiview_exception_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        class Super(Exception):\n            pass\n        class Sub(Super):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Super), IView, name='')\n        config.registry.registerAdapter(\n            view, (IExceptionViewClassifier, IRequest, Super), IView, name='')\n        config.add_view(view=view2, for_=Sub, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, implementedBy(Super), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Super), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n        wrapper = self._getViewCallable(\n            config, implementedBy(Sub), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Sub), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK2')\n\n    def test_add_view_multiview_call_ordering(self):\n        from pyramid.renderers import null_renderer as nr\n        from zope.interface import directlyProvides\n        def view1(context, request): return 'view1'\n        def view2(context, request): return 'view2'\n        def view3(context, request): return 'view3'\n        def view4(context, request): return 'view4'\n        def view5(context, request): return 'view5'\n        def view6(context, request): return 'view6'\n        def view7(context, request): return 'view7'\n        def view8(context, request): return 'view8'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view1, renderer=nr)\n        config.add_view(view=view2, request_method='POST', renderer=nr)\n        config.add_view(view=view3,request_param='param', renderer=nr)\n        config.add_view(view=view4, containment=IDummy, renderer=nr)\n        config.add_view(view=view5, request_method='POST',\n                        request_param='param',  renderer=nr)\n        config.add_view(view=view6, request_method='POST', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view7, request_param='param', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view8, request_method='POST',request_param='param',\n                        containment=IDummy, renderer=nr)\n\n\n        wrapper = self._getViewCallable(config)\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view1')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view2')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {'param':'1'}\n        request.method = 'GET'\n        self.assertEqual(wrapper(ctx, request), 'view3')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view4')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view5')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view6')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view7')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view8')\n\n    def test_add_view_multiview___discriminator__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        class IFoo(Interface):\n            pass\n        class IBar(Interface):\n            pass\n        @implementer(IFoo)\n        class Foo(object):\n            pass\n        @implementer(IBar)\n        class Bar(object):\n            pass\n        foo = Foo()\n        bar = Bar()\n\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IFoo)\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IBar)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        request = self._makeRequest(config)\n        self.assertNotEqual(\n            wrapper.__discriminator__(foo, request),\n            wrapper.__discriminator__(bar, request),\n            )\n\n    def test_add_view_with_template_renderer(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=view, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_default_renderer(self):\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        class moo(object):\n            def __init__(self, *arg, **kw):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'moo'\n        config.add_renderer(None, moo)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'moo')\n\n    def test_add_view_with_template_renderer_no_callable(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=None, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_request_type_as_iface(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        def view(context, request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(request_type=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, None)\n        request = self._makeRequest(config)\n        directlyProvides(request, IDummy)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_request_type_as_noniface(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        self.assertRaises(ConfigurationError,\n                          config.add_view, view, '', None, None, object)\n\n    def test_add_view_with_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        self.assertNotEqual(request_iface, None)\n        wrapper = self._getViewCallable(config, request_iface=request_iface)\n        self.assertNotEqual(wrapper, None)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_nonexistant_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        self.assertRaises(ConfigurationExecutionError, config.commit)\n\n    def test_add_view_with_route_name_exception(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', context=RuntimeError,\n                        renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        wrapper_exc_view = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface, exception_view=True)\n        self.assertNotEqual(wrapper_exc_view, None)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n\n    def test_add_view_with_request_method_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_sequence_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_sequence_conflict(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        config.add_view(view=view, request_method=('GET', 'POST'),\n                        renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_request_method_sequence_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'HEAD'))\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_get_implies_head(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'HEAD'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_param_val_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':'123'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_val_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_xhr_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_xhr_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = False\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, header='Host:a\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_header_noval_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'whatever'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_noval_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NotHost':'whatever'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'1'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_val_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'abc'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_missing(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NoHost':'1'}\n        self.assertRaises(HTTPNotFound, wrapper, None, request)\n\n    def test_add_view_with_accept_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/xml']\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_accept_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/html']\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_containment_true(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_containment_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        self._assertNotFound(wrapper, context, None)\n\n    def test_add_view_with_containment_dottedname(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            containment='pyramid.tests.test_config.IDummy',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_path_info_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, path_info='\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_path_info_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_(b'/foo')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_path_info_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_('/')\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_custom_predicates_match(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return True\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates,\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_custom_predicates_nomatch(self):\n        import warnings\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return False\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_custom_predicate_bests_standard_predicate(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=(pred1,),\n                        renderer=null_renderer)\n            config.add_view(view=view2, request_method='GET',\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_custom_more_preds_first_bests_fewer_preds_last(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', xhr=True,\n                        renderer=null_renderer)\n        config.add_view(view=view2, request_method='GET',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_same_predicates(self):\n        view2 = lambda *arg: 'second'\n        view1 = lambda *arg: 'first'\n        config = self._makeOne()\n        config.add_view(view=view1)\n        config.add_view(view=view2)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, permission='view', renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               default_permission='view',\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_no_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        class DummyPolicy(object): pass # wont be called\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_mapper(self):\n        from pyramid.renderers import null_renderer\n        class Mapper(object):\n            def __init__(self, **kw):\n                self.__class__.kw = kw\n            def __call__(self, view):\n                return view\n        config = self._makeOne(autocommit=True)\n        def view(context, request): return 'OK'\n        config.add_view(view=view, mapper=Mapper, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        self.assertEqual(view(None, None), 'OK')\n        self.assertEqual(Mapper.kw['mapper'], Mapper)\n\n    def test_add_view_with_view_defaults(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_kwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view='pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            'pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_config_and_view_defaults_doesnt_conflict(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IFactory'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        config.commit() # does not raise\n\n    def test_add_view_with_view_config_and_view_defaults_conflicts(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_derive_view_function(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        result = config.derive_view(view, renderer=null_renderer)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne()\n        result = config.derive_view(\n            'pyramid.tests.test_config.dummy_view',\n            renderer=null_renderer)\n        self.assertFalse(result is dummy_view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_with_default_renderer_no_explicit_renderer(self):\n        config = self._makeOne()\n        class moo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return 'moo'\n        config.add_renderer(None, moo)\n        config.commit()\n        def view(request):\n            return 'OK'\n        result = config.derive_view(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None).body, b'moo')\n\n    def test_derive_view_with_default_renderer_with_explicit_renderer(self):\n        class moo(object): pass\n        class foo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'foo'\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        config.add_renderer(None, moo)\n        config.add_renderer('foo', foo)\n        config.commit()\n        result = config.derive_view(view, renderer='foo')\n        self.assertFalse(result is view)\n        request = self._makeRequest(config)\n        self.assertEqual(result(None, request).body, b'foo')\n\n    def test_add_static_view_here_no_utility_registered(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        config = self._makeOne(autocommit=True)\n        config.add_static_view('static', 'files', renderer=null_renderer)\n        request_type = self._getRouteRequestIface(config, '__static/')\n        self._assertRoute(config, '__static/', 'static/*subpath')\n        wrapped = config.registry.adapters.lookup(\n            (IViewClassifier, request_type, Interface), IView, name='')\n        from pyramid.request import Request\n        request = Request.blank('/static/minimal.txt')\n        request.subpath = ('minimal.txt', )\n        result = wrapped(None, request)\n        self.assertEqual(result.status, '200 OK')\n        self.assertTrue(result.body.startswith(b'<div'))\n\n    def test_add_static_view_package_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static',\n                               'pyramid.tests.test_config:files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_package_here_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static', 'files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_absolute(self):\n        import os\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        here = os.path.dirname(__file__)\n        static_path = os.path.join(here, 'files')\n        config.add_static_view('static', static_path)\n        self.assertEqual(info.added,\n                         [(config, 'static', static_path, {})])\n\n    def test_add_forbidden_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        config.add_forbidden_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_forbidden_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_forbidden_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_forbidden_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, name='foo')\n\n    def test_add_forbidden_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, permission='foo')\n\n    def test_add_forbidden_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, context='foo')\n\n    def test_add_forbidden_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, for_='foo')\n\n    def test_add_forbidden_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, http_cache='foo')\n\n    def test_add_forbidden_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPForbidden\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_forbidden_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPForbidden),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_notfound_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: arg\n        config.add_notfound_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, (None, request))\n\n    def test_add_notfound_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_notfound_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_notfound_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, name='foo')\n\n    def test_add_notfound_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, permission='foo')\n\n    def test_add_notfound_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, context='foo')\n\n    def test_add_notfound_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, for_='foo')\n\n    def test_add_notfound_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, http_cache='foo')\n\n    def test_add_notfound_view_append_slash(self):\n        from pyramid.response import Response\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/foo/')\n        def view(request): return Response('OK')\n        config.add_notfound_view(view, renderer=null_renderer,append_slash=True)\n        request = self._makeRequest(config)\n        request.environ['PATH_INFO'] = '/foo'\n        request.query_string = 'a=1&b=2'\n        request.path = '/scriptname/foo'\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result.location, '/scriptname/foo/?a=1&b=2')\n\n    def test_add_notfound_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPNotFound\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_notfound_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPNotFound),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    # Since Python 3 has to be all cool and fancy and different...\n    def _assertBody(self, response, value):\n        from pyramid.compat import text_type\n        if isinstance(value, text_type): # pragma: nocover\n            self.assertEqual(response.text, value)\n        else: # pragma: nocover\n            self.assertEqual(response.body, value)\n\n    def test_add_notfound_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_notfound_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_add_forbidden_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_forbidden_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_set_view_mapper(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        mapper = object()\n        config.set_view_mapper(mapper)\n        result = config.registry.getUtility(IViewMapperFactory)\n        self.assertEqual(result, mapper)\n\n    def test_set_view_mapper_dottedname(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        config.set_view_mapper('pyramid.tests.test_config')\n        result = config.registry.getUtility(IViewMapperFactory)\n        from pyramid.tests import test_config\n        self.assertEqual(result, test_config)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 1915,
                            "end_lineno": 1943,
                            "parent": {
                                "file_name": "pyramid/tests/test_config/test_views.py",
                                "type": "class",
                                "name": "TestViewsConfigurationMixin",
                                "content": "class TestViewsConfigurationMixin(unittest.TestCase):\n    def _makeOne(self, *arg, **kw):\n        from pyramid.config import Configurator\n        config = Configurator(*arg, **kw)\n        return config\n\n    def _getViewCallable(self, config, ctx_iface=None, request_iface=None,\n                         name='', exception_view=False):\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        if exception_view:\n            classifier = IExceptionViewClassifier\n        else:\n            classifier = IViewClassifier\n        if ctx_iface is None:\n            ctx_iface = Interface\n        if request_iface is None:\n            request_iface = IRequest\n        return config.registry.adapters.lookup(\n            (classifier, request_iface, ctx_iface), IView, name=name,\n            default=None)\n\n    def _registerRenderer(self, config, name='.txt'):\n        from pyramid.interfaces import IRendererFactory\n        class Renderer:\n            def __init__(self, info):\n                self.__class__.info = info\n            def __call__(self, *arg):\n                return b'Hello!'\n        config.registry.registerUtility(Renderer, IRendererFactory, name=name)\n        return Renderer\n\n    def _makeRequest(self, config):\n        request = DummyRequest()\n        request.registry = config.registry\n        return request\n\n    def _assertNotFound(self, wrapper, *arg):\n        from pyramid.httpexceptions import HTTPNotFound\n        self.assertRaises(HTTPNotFound, wrapper, *arg)\n\n    def _getRouteRequestIface(self, config, name):\n        from pyramid.interfaces import IRouteRequest\n        iface = config.registry.getUtility(IRouteRequest, name)\n        return iface\n\n    def _assertRoute(self, config, name, path, num_predicates=0):\n        from pyramid.interfaces import IRoutesMapper\n        mapper = config.registry.getUtility(IRoutesMapper)\n        routes = mapper.get_routes()\n        route = routes[0]\n        self.assertEqual(len(routes), 1)\n        self.assertEqual(route.name, name)\n        self.assertEqual(route.path, path)\n        self.assertEqual(len(routes[0].predicates), num_predicates)\n        return route\n\n    def test_add_view_view_callable_None_no_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError, config.add_view)\n\n    def test_add_view_with_request_type_and_route_name(self):\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        self.assertRaises(ConfigurationError, config.add_view, view, '', None,\n                          None, True, True)\n\n    def test_add_view_with_request_type(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        from pyramid.interfaces import IRequest\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view,\n                        request_type='pyramid.interfaces.IRequest',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = DummyRequest()\n        self._assertNotFound(wrapper, None, request)\n        directlyProvides(request, IRequest)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_view_callable_None_with_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self._registerRenderer(config, name='dummy')\n        config.add_view(renderer='dummy')\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n\n    def test_add_view_with_tmpl_renderer_factory_introspector_missing(self):\n        config = self._makeOne(autocommit=True)\n        config.introspection = False\n        config.introspector = None\n        config.add_view(renderer='dummy.pt')\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n        \n    def test_add_view_with_tmpl_renderer_factory_no_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector()\n        config.introspector = introspector\n        config.add_view(renderer='dummy.pt')\n        self.assertFalse(('renderer factories', '.pt') in\n                         introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n\n    def test_add_view_with_tmpl_renderer_factory_with_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector(True)\n        config.introspector = introspector\n        def dummy_factory(helper):\n            return lambda val, system_vals: 'Hello!'\n        config.add_renderer('.pt', dummy_factory)\n        config.add_view(renderer='dummy.pt')\n        self.assertTrue(\n            ('renderer factories', '.pt') in introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n        \n    def test_add_view_wrapped_view_is_decorated(self):\n        def view(request): # request-only wrapper\n            \"\"\" \"\"\"\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper.__module__, view.__module__)\n        self.assertEqual(wrapper.__name__, view.__name__)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        self.assertEqual(wrapper.__discriminator__(None, None).resolve()[0],\n                         'view')\n\n    def test_add_view_view_callable_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        config.add_view(view='pyramid.tests.test_config.dummy_view',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_function_callable(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_function_callable_requestonly(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, name='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name='abc')\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name_unicode(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        name = text_(b'La Pe\\xc3\\xb1a', 'utf-8')\n        config.add_view(view=view, name=name, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name=name)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper(fn):\n            def inner(context, request):\n                return fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=view_wrapper,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator_tuple(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper1(fn):\n            def inner(context, request):\n                return 'wrapped1' + fn(context, request)\n            return inner\n        def view_wrapper2(fn):\n            def inner(context, request):\n                return 'wrapped2' + fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=(view_wrapper2, view_wrapper1),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'wrapped2wrapped1OK')\n\n    def test_add_view_with_http_cache(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return response\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, http_cache=(86400, {'public':True}))\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        request = testing.DummyRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(days=1)\n        result = wrapper(None, request)\n        self.assertEqual(result, response)\n        headers = dict(response.headerlist)\n        self.assertEqual(headers['Cache-Control'], 'max-age=86400, public')\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n\n    def test_add_view_as_instance(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, context, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instance_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_oldstyle_class(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, context, request):\n                self.context = context\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_as_oldstyle_class_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, request):\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_context_as_class(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_iface(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context='pyramid.tests.test_config.IDummy',\n                        view=view,  renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for__as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_='pyramid.tests.test_config.IDummy',\n                        view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_class(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_iface(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_trumps_for(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        class Foo:\n            pass\n        config.add_view(context=IDummy, for_=Foo, view=view,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_exception_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_mixed_case_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/HTML', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.media_views.items()),1)\n        self.assertFalse('text/HTML' in wrapper.media_views)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_views_with_accept_multiview_replaces_existing(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(len(wrapper.media_views['text/html']), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_view_exc_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, accept='text/html', context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_multiview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_mulview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_exc_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_multiview_context_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        class ISuper(Interface):\n            pass\n        class ISub(ISuper):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, ISuper), IView, name='')\n        config.add_view(view=view2, for_=ISub, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, ISuper, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n        wrapper = self._getViewCallable(config, ISub, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK2')\n\n    def test_add_view_multiview_exception_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        class Super(Exception):\n            pass\n        class Sub(Super):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Super), IView, name='')\n        config.registry.registerAdapter(\n            view, (IExceptionViewClassifier, IRequest, Super), IView, name='')\n        config.add_view(view=view2, for_=Sub, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, implementedBy(Super), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Super), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n        wrapper = self._getViewCallable(\n            config, implementedBy(Sub), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Sub), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK2')\n\n    def test_add_view_multiview_call_ordering(self):\n        from pyramid.renderers import null_renderer as nr\n        from zope.interface import directlyProvides\n        def view1(context, request): return 'view1'\n        def view2(context, request): return 'view2'\n        def view3(context, request): return 'view3'\n        def view4(context, request): return 'view4'\n        def view5(context, request): return 'view5'\n        def view6(context, request): return 'view6'\n        def view7(context, request): return 'view7'\n        def view8(context, request): return 'view8'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view1, renderer=nr)\n        config.add_view(view=view2, request_method='POST', renderer=nr)\n        config.add_view(view=view3,request_param='param', renderer=nr)\n        config.add_view(view=view4, containment=IDummy, renderer=nr)\n        config.add_view(view=view5, request_method='POST',\n                        request_param='param',  renderer=nr)\n        config.add_view(view=view6, request_method='POST', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view7, request_param='param', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view8, request_method='POST',request_param='param',\n                        containment=IDummy, renderer=nr)\n\n\n        wrapper = self._getViewCallable(config)\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view1')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view2')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {'param':'1'}\n        request.method = 'GET'\n        self.assertEqual(wrapper(ctx, request), 'view3')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view4')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view5')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view6')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view7')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view8')\n\n    def test_add_view_multiview___discriminator__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        class IFoo(Interface):\n            pass\n        class IBar(Interface):\n            pass\n        @implementer(IFoo)\n        class Foo(object):\n            pass\n        @implementer(IBar)\n        class Bar(object):\n            pass\n        foo = Foo()\n        bar = Bar()\n\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IFoo)\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IBar)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        request = self._makeRequest(config)\n        self.assertNotEqual(\n            wrapper.__discriminator__(foo, request),\n            wrapper.__discriminator__(bar, request),\n            )\n\n    def test_add_view_with_template_renderer(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=view, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_default_renderer(self):\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        class moo(object):\n            def __init__(self, *arg, **kw):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'moo'\n        config.add_renderer(None, moo)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'moo')\n\n    def test_add_view_with_template_renderer_no_callable(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=None, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_request_type_as_iface(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        def view(context, request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(request_type=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, None)\n        request = self._makeRequest(config)\n        directlyProvides(request, IDummy)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_request_type_as_noniface(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        self.assertRaises(ConfigurationError,\n                          config.add_view, view, '', None, None, object)\n\n    def test_add_view_with_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        self.assertNotEqual(request_iface, None)\n        wrapper = self._getViewCallable(config, request_iface=request_iface)\n        self.assertNotEqual(wrapper, None)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_nonexistant_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        self.assertRaises(ConfigurationExecutionError, config.commit)\n\n    def test_add_view_with_route_name_exception(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', context=RuntimeError,\n                        renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        wrapper_exc_view = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface, exception_view=True)\n        self.assertNotEqual(wrapper_exc_view, None)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n\n    def test_add_view_with_request_method_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_sequence_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_sequence_conflict(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        config.add_view(view=view, request_method=('GET', 'POST'),\n                        renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_request_method_sequence_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'HEAD'))\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_get_implies_head(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'HEAD'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_param_val_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':'123'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_val_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_xhr_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_xhr_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = False\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, header='Host:a\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_header_noval_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'whatever'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_noval_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NotHost':'whatever'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'1'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_val_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'abc'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_missing(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NoHost':'1'}\n        self.assertRaises(HTTPNotFound, wrapper, None, request)\n\n    def test_add_view_with_accept_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/xml']\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_accept_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/html']\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_containment_true(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_containment_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        self._assertNotFound(wrapper, context, None)\n\n    def test_add_view_with_containment_dottedname(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            containment='pyramid.tests.test_config.IDummy',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_path_info_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, path_info='\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_path_info_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_(b'/foo')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_path_info_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_('/')\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_custom_predicates_match(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return True\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates,\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_custom_predicates_nomatch(self):\n        import warnings\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return False\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_custom_predicate_bests_standard_predicate(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=(pred1,),\n                        renderer=null_renderer)\n            config.add_view(view=view2, request_method='GET',\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_custom_more_preds_first_bests_fewer_preds_last(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', xhr=True,\n                        renderer=null_renderer)\n        config.add_view(view=view2, request_method='GET',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_same_predicates(self):\n        view2 = lambda *arg: 'second'\n        view1 = lambda *arg: 'first'\n        config = self._makeOne()\n        config.add_view(view=view1)\n        config.add_view(view=view2)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, permission='view', renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               default_permission='view',\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_no_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        class DummyPolicy(object): pass # wont be called\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_mapper(self):\n        from pyramid.renderers import null_renderer\n        class Mapper(object):\n            def __init__(self, **kw):\n                self.__class__.kw = kw\n            def __call__(self, view):\n                return view\n        config = self._makeOne(autocommit=True)\n        def view(context, request): return 'OK'\n        config.add_view(view=view, mapper=Mapper, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        self.assertEqual(view(None, None), 'OK')\n        self.assertEqual(Mapper.kw['mapper'], Mapper)\n\n    def test_add_view_with_view_defaults(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_kwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view='pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            'pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_config_and_view_defaults_doesnt_conflict(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IFactory'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        config.commit() # does not raise\n\n    def test_add_view_with_view_config_and_view_defaults_conflicts(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_derive_view_function(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        result = config.derive_view(view, renderer=null_renderer)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne()\n        result = config.derive_view(\n            'pyramid.tests.test_config.dummy_view',\n            renderer=null_renderer)\n        self.assertFalse(result is dummy_view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_with_default_renderer_no_explicit_renderer(self):\n        config = self._makeOne()\n        class moo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return 'moo'\n        config.add_renderer(None, moo)\n        config.commit()\n        def view(request):\n            return 'OK'\n        result = config.derive_view(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None).body, b'moo')\n\n    def test_derive_view_with_default_renderer_with_explicit_renderer(self):\n        class moo(object): pass\n        class foo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'foo'\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        config.add_renderer(None, moo)\n        config.add_renderer('foo', foo)\n        config.commit()\n        result = config.derive_view(view, renderer='foo')\n        self.assertFalse(result is view)\n        request = self._makeRequest(config)\n        self.assertEqual(result(None, request).body, b'foo')\n\n    def test_add_static_view_here_no_utility_registered(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        config = self._makeOne(autocommit=True)\n        config.add_static_view('static', 'files', renderer=null_renderer)\n        request_type = self._getRouteRequestIface(config, '__static/')\n        self._assertRoute(config, '__static/', 'static/*subpath')\n        wrapped = config.registry.adapters.lookup(\n            (IViewClassifier, request_type, Interface), IView, name='')\n        from pyramid.request import Request\n        request = Request.blank('/static/minimal.txt')\n        request.subpath = ('minimal.txt', )\n        result = wrapped(None, request)\n        self.assertEqual(result.status, '200 OK')\n        self.assertTrue(result.body.startswith(b'<div'))\n\n    def test_add_static_view_package_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static',\n                               'pyramid.tests.test_config:files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_package_here_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static', 'files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_absolute(self):\n        import os\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        here = os.path.dirname(__file__)\n        static_path = os.path.join(here, 'files')\n        config.add_static_view('static', static_path)\n        self.assertEqual(info.added,\n                         [(config, 'static', static_path, {})])\n\n    def test_add_forbidden_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        config.add_forbidden_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_forbidden_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_forbidden_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_forbidden_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, name='foo')\n\n    def test_add_forbidden_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, permission='foo')\n\n    def test_add_forbidden_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, context='foo')\n\n    def test_add_forbidden_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, for_='foo')\n\n    def test_add_forbidden_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, http_cache='foo')\n\n    def test_add_forbidden_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPForbidden\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_forbidden_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPForbidden),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_notfound_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: arg\n        config.add_notfound_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, (None, request))\n\n    def test_add_notfound_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_notfound_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_notfound_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, name='foo')\n\n    def test_add_notfound_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, permission='foo')\n\n    def test_add_notfound_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, context='foo')\n\n    def test_add_notfound_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, for_='foo')\n\n    def test_add_notfound_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, http_cache='foo')\n\n    def test_add_notfound_view_append_slash(self):\n        from pyramid.response import Response\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/foo/')\n        def view(request): return Response('OK')\n        config.add_notfound_view(view, renderer=null_renderer,append_slash=True)\n        request = self._makeRequest(config)\n        request.environ['PATH_INFO'] = '/foo'\n        request.query_string = 'a=1&b=2'\n        request.path = '/scriptname/foo'\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result.location, '/scriptname/foo/?a=1&b=2')\n\n    def test_add_notfound_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPNotFound\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_notfound_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPNotFound),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    # Since Python 3 has to be all cool and fancy and different...\n    def _assertBody(self, response, value):\n        from pyramid.compat import text_type\n        if isinstance(value, text_type): # pragma: nocover\n            self.assertEqual(response.text, value)\n        else: # pragma: nocover\n            self.assertEqual(response.body, value)\n\n    def test_add_notfound_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_notfound_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_add_forbidden_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_forbidden_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_set_view_mapper(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        mapper = object()\n        config.set_view_mapper(mapper)\n        result = config.registry.getUtility(IViewMapperFactory)\n        self.assertEqual(result, mapper)\n\n    def test_set_view_mapper_dottedname(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        config.set_view_mapper('pyramid.tests.test_config')\n        result = config.registry.getUtility(IViewMapperFactory)\n        from pyramid.tests import test_config\n        self.assertEqual(result, test_config)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 16,
                                "end_lineno": 2001,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "7c96246eb6e14f5cd9414ddd61de089fe1f073d1^",
    "new_commit_hash": "7c96246eb6e14f5cd9414ddd61de089fe1f073d1",
    "commit_message": "notfound and forbidden decorators were ignoring view_defaults\n\nThis could be fixed in other ways but the basic problem is that because\nconfig.add_notfound_view and config.add_forbidden_view have actual\nsignatures instead of *args, **kwargs, the arguments are squashing the\nview_defaults which are applied later on the call to config.add_view.\n\nBasically, by the time the args get to config.add_view, they look\nexplicit when they are not.\n\nfix #1173",
    "commit_date": "2013-10-20T21:13:49-05:00",
    "metadata": {}
}
{
    "repo_name": "pyramid",
    "new_commit_hash": "7c96246eb6e14f5cd9414ddd61de089fe1f073d1",
    "test_file_codes": [
        "import unittest\nfrom pyramid import testing\n\nfrom pyramid.tests.test_config import IDummy\n\nfrom pyramid.tests.test_config import dummy_view\n\nfrom pyramid.compat import (\n    im_func,\n    text_,\n    )\nfrom pyramid.exceptions import ConfigurationError\nfrom pyramid.exceptions import ConfigurationExecutionError\nfrom pyramid.exceptions import ConfigurationConflictError\n\nclass TestViewsConfigurationMixin(unittest.TestCase):\n    def _makeOne(self, *arg, **kw):\n        from pyramid.config import Configurator\n        config = Configurator(*arg, **kw)\n        return config\n\n    def _getViewCallable(self, config, ctx_iface=None, request_iface=None,\n                         name='', exception_view=False):\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        if exception_view:\n            classifier = IExceptionViewClassifier\n        else:\n            classifier = IViewClassifier\n        if ctx_iface is None:\n            ctx_iface = Interface\n        if request_iface is None:\n            request_iface = IRequest\n        return config.registry.adapters.lookup(\n            (classifier, request_iface, ctx_iface), IView, name=name,\n            default=None)\n\n    def _registerRenderer(self, config, name='.txt'):\n        from pyramid.interfaces import IRendererFactory\n        class Renderer:\n            def __init__(self, info):\n                self.__class__.info = info\n            def __call__(self, *arg):\n                return b'Hello!'\n        config.registry.registerUtility(Renderer, IRendererFactory, name=name)\n        return Renderer\n\n    def _makeRequest(self, config):\n        request = DummyRequest()\n        request.registry = config.registry\n        return request\n\n    def _assertNotFound(self, wrapper, *arg):\n        from pyramid.httpexceptions import HTTPNotFound\n        self.assertRaises(HTTPNotFound, wrapper, *arg)\n\n    def _getRouteRequestIface(self, config, name):\n        from pyramid.interfaces import IRouteRequest\n        iface = config.registry.getUtility(IRouteRequest, name)\n        return iface\n\n    def _assertRoute(self, config, name, path, num_predicates=0):\n        from pyramid.interfaces import IRoutesMapper\n        mapper = config.registry.getUtility(IRoutesMapper)\n        routes = mapper.get_routes()\n        route = routes[0]\n        self.assertEqual(len(routes), 1)\n        self.assertEqual(route.name, name)\n        self.assertEqual(route.path, path)\n        self.assertEqual(len(routes[0].predicates), num_predicates)\n        return route\n\n    def test_add_view_view_callable_None_no_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError, config.add_view)\n\n    def test_add_view_with_request_type_and_route_name(self):\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        self.assertRaises(ConfigurationError, config.add_view, view, '', None,\n                          None, True, True)\n\n    def test_add_view_with_request_type(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        from pyramid.interfaces import IRequest\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view,\n                        request_type='pyramid.interfaces.IRequest',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = DummyRequest()\n        self._assertNotFound(wrapper, None, request)\n        directlyProvides(request, IRequest)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_view_callable_None_with_renderer(self):\n        config = self._makeOne(autocommit=True)\n        self._registerRenderer(config, name='dummy')\n        config.add_view(renderer='dummy')\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n\n    def test_add_view_with_tmpl_renderer_factory_introspector_missing(self):\n        config = self._makeOne(autocommit=True)\n        config.introspection = False\n        config.introspector = None\n        config.add_view(renderer='dummy.pt')\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n        \n    def test_add_view_with_tmpl_renderer_factory_no_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector()\n        config.introspector = introspector\n        config.add_view(renderer='dummy.pt')\n        self.assertFalse(('renderer factories', '.pt') in\n                         introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertRaises(ValueError, view, None, None)\n\n    def test_add_view_with_tmpl_renderer_factory_with_renderer_factory(self):\n        config = self._makeOne(autocommit=True)\n        introspector = DummyIntrospector(True)\n        config.introspector = introspector\n        def dummy_factory(helper):\n            return lambda val, system_vals: 'Hello!'\n        config.add_renderer('.pt', dummy_factory)\n        config.add_view(renderer='dummy.pt')\n        self.assertTrue(\n            ('renderer factories', '.pt') in introspector.related[-1])\n        view = self._getViewCallable(config)\n        self.assertTrue(b'Hello!' in view(None, None).body)\n        \n    def test_add_view_wrapped_view_is_decorated(self):\n        def view(request): # request-only wrapper\n            \"\"\" \"\"\"\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper.__module__, view.__module__)\n        self.assertEqual(wrapper.__name__, view.__name__)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        self.assertEqual(wrapper.__discriminator__(None, None).resolve()[0],\n                         'view')\n\n    def test_add_view_view_callable_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        config.add_view(view='pyramid.tests.test_config.dummy_view',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_function_callable(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_function_callable_requestonly(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, name='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name='abc')\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_name_unicode(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        name = text_(b'La Pe\\xc3\\xb1a', 'utf-8')\n        config.add_view(view=view, name=name, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, name=name)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper(fn):\n            def inner(context, request):\n                return fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=view_wrapper,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_decorator_tuple(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return 'OK'\n        def view_wrapper1(fn):\n            def inner(context, request):\n                return 'wrapped1' + fn(context, request)\n            return inner\n        def view_wrapper2(fn):\n            def inner(context, request):\n                return 'wrapped2' + fn(context, request)\n            return inner\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, decorator=(view_wrapper2, view_wrapper1),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'wrapped2wrapped1OK')\n\n    def test_add_view_with_http_cache(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def view(request):\n            \"\"\" ABC \"\"\"\n            return response\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, http_cache=(86400, {'public':True}))\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(wrapper is view)\n        self.assertEqual(wrapper.__doc__, view.__doc__)\n        request = testing.DummyRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(days=1)\n        result = wrapper(None, request)\n        self.assertEqual(result, response)\n        headers = dict(response.headerlist)\n        self.assertEqual(headers['Cache-Control'], 'max-age=86400, public')\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n\n    def test_add_view_as_instance(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, context, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instancemethod_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class View:\n            def index(self, request):\n                return 'OK'\n        view = View()\n        config=self._makeOne(autocommit=True)\n        config.add_view(view=view.index, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_instance_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class AView:\n            def __call__(self, request):\n                \"\"\" \"\"\"\n                return 'OK'\n        view = AView()\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        result = wrapper(None, None)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_as_oldstyle_class(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, context, request):\n                self.context = context\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_as_oldstyle_class_requestonly(self):\n        from pyramid.renderers import null_renderer\n        class view:\n            def __init__(self, request):\n                self.request = request\n\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_add_view_context_as_class(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_iface(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(context='pyramid.tests.test_config.IDummy',\n                        view=view,  renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for__as_dottedname(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_='pyramid.tests.test_config.IDummy',\n                        view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_class(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        class Foo:\n            pass\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=Foo, view=view, renderer=null_renderer)\n        foo = implementedBy(Foo)\n        wrapper = self._getViewCallable(config, foo)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_for_as_iface(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(for_=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_context_trumps_for(self):\n        # ``for_`` is older spelling for ``context``\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        class Foo:\n            pass\n        config.add_view(context=IDummy, for_=Foo, view=view,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config, IDummy)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_exception_register_secured_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__call_permissive__ = view\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = config.registry.adapters.lookup(\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='', default=None)\n        self.assertEqual(wrapper, view)\n\n    def test_add_view_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_same_phash_overrides_existing_single_view(self):\n        from pyramid.renderers import null_renderer\n        from hashlib import md5\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        phash = md5()\n        phash.update(b'xhr = True')\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = phash.hexdigest()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, xhr=True, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_no_phash(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_default_phash_overrides_default_phash(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.config.util import DEFAULT_PHASH\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'NOT OK'\n        view.__phash__ = DEFAULT_PHASH\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        def newview(context, request):\n            return 'OK'\n        config.add_view(view=newview, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        request = DummyRequest()\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IExceptionViewClassifier\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            ISecuredView, name='')\n        config.add_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_exc_multiview_replaces_existing_securedview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import ISecuredView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            ISecuredView, name='')\n        config.add_view(view=view, context=RuntimeError, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_mixed_case_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/HTML', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.media_views.items()),1)\n        self.assertFalse('text/HTML' in wrapper.media_views)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_views_with_accept_multiview_replaces_existing(self):\n        from pyramid.renderers import null_renderer\n        def view(context, request): return 'OK'\n        def view2(context, request): return 'OK2'\n        def view3(context, request): return 'OK3'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, renderer=null_renderer)\n        config.add_view(view=view2, accept='text/html', renderer=null_renderer)\n        config.add_view(view=view3, accept='text/html', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertEqual(len(wrapper.media_views['text/html']), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK3')\n\n    def test_add_view_exc_with_accept_multiview_replaces_existing_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, accept='text/html', context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/html')\n        self.assertEqual(wrapper(None, request), 'OK2')\n\n    def test_add_view_multiview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_exc_mulview_replaces_existing_view_with___accept__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        def view(context, request):\n            return 'OK'\n        def view2(context, request):\n            return 'OK2'\n        view.__accept__ = 'text/html'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IView, name='')\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual(len(wrapper.views), 1)\n        self.assertEqual(len(wrapper.media_views), 1)\n        self.assertEqual(wrapper(None, None), 'OK2')\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_exc_multiview_replaces_multiview(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        view = DummyMultiView()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view,\n            (IViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        config.registry.registerAdapter(\n            view,\n            (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),\n            IMultiView, name='')\n        view2 = lambda *arg: 'OK2'\n        config.add_view(view=view2, context=RuntimeError,\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError), exception_view=True)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])\n        self.assertEqual(wrapper(None, None), 'OK1')\n\n    def test_add_view_multiview_context_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        class ISuper(Interface):\n            pass\n        class ISub(ISuper):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, ISuper), IView, name='')\n        config.add_view(view=view2, for_=ISub, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, ISuper, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK')\n        wrapper = self._getViewCallable(config, ISub, IRequest)\n        self.assertFalse(IMultiView.providedBy(wrapper))\n        self.assertEqual(wrapper(None, None), 'OK2')\n\n    def test_add_view_multiview_exception_superclass_then_subclass(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IMultiView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IExceptionViewClassifier\n        class Super(Exception):\n            pass\n        class Sub(Super):\n            pass\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'OK2'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Super), IView, name='')\n        config.registry.registerAdapter(\n            view, (IExceptionViewClassifier, IRequest, Super), IView, name='')\n        config.add_view(view=view2, for_=Sub, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, implementedBy(Super), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Super), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n        wrapper = self._getViewCallable(\n            config, implementedBy(Sub), IRequest)\n        wrapper_exc_view = self._getViewCallable(\n            config, implementedBy(Sub), IRequest, exception_view=True)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertFalse(IMultiView.providedBy(wrapper_exc_view))\n        self.assertEqual(wrapper_exc_view(None, None), 'OK2')\n\n    def test_add_view_multiview_call_ordering(self):\n        from pyramid.renderers import null_renderer as nr\n        from zope.interface import directlyProvides\n        def view1(context, request): return 'view1'\n        def view2(context, request): return 'view2'\n        def view3(context, request): return 'view3'\n        def view4(context, request): return 'view4'\n        def view5(context, request): return 'view5'\n        def view6(context, request): return 'view6'\n        def view7(context, request): return 'view7'\n        def view8(context, request): return 'view8'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view1, renderer=nr)\n        config.add_view(view=view2, request_method='POST', renderer=nr)\n        config.add_view(view=view3,request_param='param', renderer=nr)\n        config.add_view(view=view4, containment=IDummy, renderer=nr)\n        config.add_view(view=view5, request_method='POST',\n                        request_param='param',  renderer=nr)\n        config.add_view(view=view6, request_method='POST', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view7, request_param='param', containment=IDummy,\n                        renderer=nr)\n        config.add_view(view=view8, request_method='POST',request_param='param',\n                        containment=IDummy, renderer=nr)\n\n\n        wrapper = self._getViewCallable(config)\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view1')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view2')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.params = {'param':'1'}\n        request.method = 'GET'\n        self.assertEqual(wrapper(ctx, request), 'view3')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {}\n        self.assertEqual(wrapper(ctx, request), 'view4')\n\n        ctx = DummyContext()\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view5')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.params = {}\n        request.method = 'POST'\n        self.assertEqual(wrapper(ctx, request), 'view6')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view7')\n\n        ctx = DummyContext()\n        directlyProvides(ctx, IDummy)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        request.params = {'param':'1'}\n        self.assertEqual(wrapper(ctx, request), 'view8')\n\n    def test_add_view_multiview___discriminator__(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        class IFoo(Interface):\n            pass\n        class IBar(Interface):\n            pass\n        @implementer(IFoo)\n        class Foo(object):\n            pass\n        @implementer(IBar)\n        class Bar(object):\n            pass\n        foo = Foo()\n        bar = Bar()\n\n        from pyramid.interfaces import IRequest\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        from pyramid.interfaces import IMultiView\n        view = lambda *arg: 'OK'\n        view.__phash__ = 'abc'\n        config = self._makeOne(autocommit=True)\n        config.registry.registerAdapter(\n            view, (IViewClassifier, IRequest, Interface), IView, name='')\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IFoo)\n        config.add_view(view=view, renderer=null_renderer,\n                        containment=IBar)\n        wrapper = self._getViewCallable(config)\n        self.assertTrue(IMultiView.providedBy(wrapper))\n        request = self._makeRequest(config)\n        self.assertNotEqual(\n            wrapper.__discriminator__(foo, request),\n            wrapper.__discriminator__(bar, request),\n            )\n\n    def test_add_view_with_template_renderer(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=view, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_default_renderer(self):\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n\n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        class moo(object):\n            def __init__(self, *arg, **kw):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'moo'\n        config.add_renderer(None, moo)\n        config.add_view(view=view)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'moo')\n\n    def test_add_view_with_template_renderer_no_callable(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=None, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n        self.assertEqual(result.package, test_config)\n        self.assertEqual(result.name, fixture)\n        self.assertEqual(result.settings, settings)\n\n    def test_add_view_with_request_type_as_iface(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        def view(context, request):\n            return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(request_type=IDummy, view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(config, None)\n        request = self._makeRequest(config)\n        directlyProvides(request, IDummy)\n        result = wrapper(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_view_with_request_type_as_noniface(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        self.assertRaises(ConfigurationError,\n                          config.add_view, view, '', None, None, object)\n\n    def test_add_view_with_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        self.assertNotEqual(request_iface, None)\n        wrapper = self._getViewCallable(config, request_iface=request_iface)\n        self.assertNotEqual(wrapper, None)\n        self.assertEqual(wrapper(None, None), 'OK')\n\n    def test_add_view_with_nonexistant_route_name(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, route_name='foo', renderer=null_renderer)\n        self.assertRaises(ConfigurationExecutionError, config.commit)\n\n    def test_add_view_with_route_name_exception(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(view=view, route_name='foo', context=RuntimeError,\n                        renderer=null_renderer)\n        request_iface = self._getRouteRequestIface(config, 'foo')\n        wrapper_exc_view = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface, exception_view=True)\n        self.assertNotEqual(wrapper_exc_view, None)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(RuntimeError),\n            request_iface=request_iface)\n        self.assertEqual(wrapper_exc_view, wrapper)\n        self.assertEqual(wrapper_exc_view(None, None), 'OK')\n\n    def test_add_view_with_request_method_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='POST')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_sequence_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'POST'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_method_sequence_conflict(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view=view, request_method=('POST', 'GET'),\n                        renderer=null_renderer)\n        config.add_view(view=view, request_method=('GET', 'POST'),\n                        renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_request_method_sequence_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method=('POST', 'HEAD'))\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_method_get_implies_head(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'HEAD'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_noval_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_request_param_val_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':'123'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_request_param_val_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_param='abc=123')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.params = {'abc':''}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_xhr_true(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_xhr_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, xhr=True)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.is_xhr = False\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, header='Host:a\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_header_noval_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'whatever'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_noval_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header='Host')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NotHost':'whatever'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'1'}\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_header_val_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'Host':'abc'}\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_header_val_missing(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, header=r'Host:\\d')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.headers = {'NoHost':'1'}\n        self.assertRaises(HTTPNotFound, wrapper, None, request)\n\n    def test_add_view_with_accept_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/xml']\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_accept_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, accept='text/xml')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.accept = ['text/html']\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_containment_true(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy, renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_containment_false(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, containment=IDummy)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        self._assertNotFound(wrapper, context, None)\n\n    def test_add_view_with_containment_dottedname(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import directlyProvides\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            containment='pyramid.tests.test_config.IDummy',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        self.assertEqual(wrapper(context, None), 'OK')\n\n    def test_add_view_with_path_info_badregex(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne()\n        config.add_view(view, path_info='\\\\')\n        self.assertRaises(ConfigurationError, config.commit)\n\n    def test_add_view_with_path_info_match(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo', renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_(b'/foo')\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_path_info_nomatch(self):\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, path_info='/foo')\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.upath_info = text_('/')\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_with_custom_predicates_match(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return True\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates,\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_with_custom_predicates_nomatch(self):\n        import warnings\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return False\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self._assertNotFound(wrapper, None, request)\n\n    def test_add_view_custom_predicate_bests_standard_predicate(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=(pred1,),\n                        renderer=null_renderer)\n            config.add_view(view=view2, request_method='GET',\n                            renderer=null_renderer)\n            self.assertEqual(len(w), 1)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_custom_more_preds_first_bests_fewer_preds_last(self):\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, request_method='GET', xhr=True,\n                        renderer=null_renderer)\n        config.add_view(view=view2, request_method='GET',\n                        renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        request.method = 'GET'\n        request.is_xhr = True\n        self.assertEqual(wrapper(None, request), 'OK')\n\n    def test_add_view_same_predicates(self):\n        view2 = lambda *arg: 'second'\n        view1 = lambda *arg: 'first'\n        config = self._makeOne()\n        config.add_view(view=view1)\n        config.add_view(view=view2)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_add_view_with_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, permission='view', renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        outerself = self\n        class DummyPolicy(object):\n            def effective_principals(self, r):\n                outerself.assertEqual(r, request)\n                return ['abc']\n            def permits(self, context, principals, permission):\n                outerself.assertEqual(context, None)\n                outerself.assertEqual(principals, ['abc'])\n                outerself.assertEqual(permission, 'view')\n                return True\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               default_permission='view',\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_no_default_permission_no_explicit_permission(self):\n        from pyramid.renderers import null_renderer\n        view1 = lambda *arg: 'OK'\n        class DummyPolicy(object): pass # wont be called\n        policy = DummyPolicy()\n        config = self._makeOne(authorization_policy=policy,\n                               authentication_policy=policy,\n                               autocommit=True)\n        config.add_view(view=view1, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        self.assertEqual(view(None, request), 'OK')\n\n    def test_add_view_with_mapper(self):\n        from pyramid.renderers import null_renderer\n        class Mapper(object):\n            def __init__(self, **kw):\n                self.__class__.kw = kw\n            def __call__(self, view):\n                return view\n        config = self._makeOne(autocommit=True)\n        def view(context, request): return 'OK'\n        config.add_view(view=view, mapper=Mapper, renderer=null_renderer)\n        view = self._getViewCallable(config)\n        self.assertEqual(view(None, None), 'OK')\n        self.assertEqual(Mapper.kw['mapper'], Mapper)\n\n    def test_add_view_with_view_defaults(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_kwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view='pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg(self):\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from zope.interface import directlyProvides\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            'pyramid.tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_view_with_view_config_and_view_defaults_doesnt_conflict(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IFactory'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        config.commit() # does not raise\n\n    def test_add_view_with_view_config_and_view_defaults_conflicts(self):\n        from pyramid.renderers import null_renderer\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        class view2(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n        config = self._makeOne(autocommit=False)\n        config.add_view(\n            view=view,\n            renderer=null_renderer)\n        config.add_view(\n            view=view2,\n            renderer=null_renderer)\n        self.assertRaises(ConfigurationConflictError, config.commit)\n\n    def test_derive_view_function(self):\n        from pyramid.renderers import null_renderer\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        result = config.derive_view(view, renderer=null_renderer)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_dottedname(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne()\n        result = config.derive_view(\n            'pyramid.tests.test_config.dummy_view',\n            renderer=null_renderer)\n        self.assertFalse(result is dummy_view)\n        self.assertEqual(result(None, None), 'OK')\n\n    def test_derive_view_with_default_renderer_no_explicit_renderer(self):\n        config = self._makeOne()\n        class moo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return 'moo'\n        config.add_renderer(None, moo)\n        config.commit()\n        def view(request):\n            return 'OK'\n        result = config.derive_view(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None).body, b'moo')\n\n    def test_derive_view_with_default_renderer_with_explicit_renderer(self):\n        class moo(object): pass\n        class foo(object):\n            def __init__(self, view):\n                pass\n            def __call__(self, *arg, **kw):\n                return b'foo'\n        def view(request):\n            return 'OK'\n        config = self._makeOne()\n        config.add_renderer(None, moo)\n        config.add_renderer('foo', foo)\n        config.commit()\n        result = config.derive_view(view, renderer='foo')\n        self.assertFalse(result is view)\n        request = self._makeRequest(config)\n        self.assertEqual(result(None, request).body, b'foo')\n\n    def test_add_static_view_here_no_utility_registered(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        config = self._makeOne(autocommit=True)\n        config.add_static_view('static', 'files', renderer=null_renderer)\n        request_type = self._getRouteRequestIface(config, '__static/')\n        self._assertRoute(config, '__static/', 'static/*subpath')\n        wrapped = config.registry.adapters.lookup(\n            (IViewClassifier, request_type, Interface), IView, name='')\n        from pyramid.request import Request\n        request = Request.blank('/static/minimal.txt')\n        request.subpath = ('minimal.txt', )\n        result = wrapped(None, request)\n        self.assertEqual(result.status, '200 OK')\n        self.assertTrue(result.body.startswith(b'<div'))\n\n    def test_add_static_view_package_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static',\n                               'pyramid.tests.test_config:files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_package_here_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static', 'files')\n        self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\n\n    def test_add_static_view_absolute(self):\n        import os\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        here = os.path.dirname(__file__)\n        static_path = os.path.join(here, 'files')\n        config.add_static_view('static', static_path)\n        self.assertEqual(info.added,\n                         [(config, 'static', static_path, {})])\n\n    def test_add_forbidden_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: 'OK'\n        config.add_forbidden_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, 'OK')\n\n    def test_add_forbidden_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_forbidden_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_forbidden_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, name='foo')\n\n    def test_add_forbidden_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, permission='foo')\n\n    def test_add_forbidden_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, context='foo')\n\n    def test_add_forbidden_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, for_='foo')\n\n    def test_add_forbidden_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_forbidden_view, http_cache='foo')\n\n    def test_add_forbidden_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPForbidden\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_forbidden_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPForbidden),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    def test_add_notfound_view(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: arg\n        config.add_notfound_view(view, renderer=null_renderer)\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result, (None, request))\n\n    def test_add_notfound_view_allows_other_predicates(self):\n        from pyramid.renderers import null_renderer\n        config = self._makeOne(autocommit=True)\n        # doesnt blow up\n        config.add_view_predicate('dummy', DummyPredicate)\n        config.add_notfound_view(renderer=null_renderer, dummy='abc')\n\n    def test_add_notfound_view_disallows_name(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, name='foo')\n\n    def test_add_notfound_view_disallows_permission(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, permission='foo')\n\n    def test_add_notfound_view_disallows_context(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, context='foo')\n\n    def test_add_notfound_view_disallows_for_(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, for_='foo')\n\n    def test_add_notfound_view_disallows_http_cache(self):\n        config = self._makeOne(autocommit=True)\n        self.assertRaises(ConfigurationError,\n                          config.add_notfound_view, http_cache='foo')\n\n    def test_add_notfound_view_append_slash(self):\n        from pyramid.response import Response\n        from pyramid.renderers import null_renderer\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        config.add_route('foo', '/foo/')\n        def view(request): return Response('OK')\n        config.add_notfound_view(view, renderer=null_renderer,append_slash=True)\n        request = self._makeRequest(config)\n        request.environ['PATH_INFO'] = '/foo'\n        request.query_string = 'a=1&b=2'\n        request.path = '/scriptname/foo'\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self.assertEqual(result.location, '/scriptname/foo/?a=1&b=2')\n\n    def test_add_notfound_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPNotFound\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_notfound_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPNotFound),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n        self.assertRaises(PredicateMismatch, wrapper, context, request)\n\n    # Since Python 3 has to be all cool and fancy and different...\n    def _assertBody(self, response, value):\n        from pyramid.compat import text_type\n        if isinstance(value, text_type): # pragma: nocover\n            self.assertEqual(response.text, value)\n        else: # pragma: nocover\n            self.assertEqual(response.body, value)\n\n    def test_add_notfound_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPNotFound\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_notfound_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPNotFound),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_add_forbidden_view_with_renderer(self):\n        from zope.interface import implementedBy\n        from pyramid.interfaces import IRequest\n        from pyramid.httpexceptions import HTTPForbidden\n        config = self._makeOne(autocommit=True)\n        view = lambda *arg: {}\n        config.introspection = False\n        config.add_forbidden_view(\n            view,\n            renderer='json')\n        request = self._makeRequest(config)\n        view = self._getViewCallable(config,\n                                     ctx_iface=implementedBy(HTTPForbidden),\n                                     request_iface=IRequest)\n        result = view(None, request)\n        self._assertBody(result, '{}')\n\n    def test_set_view_mapper(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        mapper = object()\n        config.set_view_mapper(mapper)\n        result = config.registry.getUtility(IViewMapperFactory)\n        self.assertEqual(result, mapper)\n\n    def test_set_view_mapper_dottedname(self):\n        from pyramid.interfaces import IViewMapperFactory\n        config = self._makeOne(autocommit=True)\n        config.set_view_mapper('pyramid.tests.test_config')\n        result = config.registry.getUtility(IViewMapperFactory)\n        from pyramid.tests import test_config\n        self.assertEqual(result, test_config)\n\nclass Test_requestonly(unittest.TestCase):\n    def _callFUT(self, view, attr=None):\n        from pyramid.config.views import requestonly\n        return requestonly(view, attr=attr)\n\n    def test_defaults(self):\n        def aview(request, a=1, b=2): pass\n        self.assertTrue(self._callFUT(aview))\n\n    def test_otherattr(self):\n        class AView(object):\n            def __init__(self, request, a=1, b=2): pass\n            def bleh(self): pass\n        self.assertTrue(self._callFUT(AView, 'bleh'))\n\nclass Test_isexception(unittest.TestCase):\n    def _callFUT(self, ob):\n        from pyramid.config.views import isexception\n        return isexception(ob)\n\n    def test_is_exception_instance(self):\n        class E(Exception):\n            pass\n        e = E()\n        self.assertEqual(self._callFUT(e), True)\n\n    def test_is_exception_class(self):\n        class E(Exception):\n            pass\n        self.assertEqual(self._callFUT(E), True)\n\n    def test_is_IException(self):\n        from pyramid.interfaces import IException\n        self.assertEqual(self._callFUT(IException), True)\n\n    def test_is_IException_subinterface(self):\n        from pyramid.interfaces import IException\n        class ISubException(IException):\n            pass\n        self.assertEqual(self._callFUT(ISubException), True)\n\nclass TestMultiView(unittest.TestCase):\n    def _getTargetClass(self):\n        from pyramid.config.views import MultiView\n        return MultiView\n\n    def _makeOne(self, name='name'):\n        return self._getTargetClass()(name)\n\n    def test_class_implements_ISecuredView(self):\n        from zope.interface.verify import verifyClass\n        from pyramid.interfaces import ISecuredView\n        verifyClass(ISecuredView, self._getTargetClass())\n\n    def test_instance_implements_ISecuredView(self):\n        from zope.interface.verify import verifyObject\n        from pyramid.interfaces import ISecuredView\n        verifyObject(ISecuredView, self._makeOne())\n\n    def test_add(self):\n        mv = self._makeOne()\n        mv.add('view', 100)\n        self.assertEqual(mv.views, [(100, 'view', None)])\n        mv.add('view2', 99)\n        self.assertEqual(mv.views, [(99, 'view2', None), (100, 'view', None)])\n        mv.add('view3', 100, 'text/html')\n        self.assertEqual(mv.media_views['text/html'], [(100, 'view3', None)])\n        mv.add('view4', 99, 'text/html', 'abc')\n        self.assertEqual(mv.media_views['text/html'],\n                         [(99, 'view4', 'abc'), (100, 'view3', None)])\n        mv.add('view5', 100, 'text/xml')\n        self.assertEqual(mv.media_views['text/xml'], [(100, 'view5', None)])\n        self.assertEqual(set(mv.accepts), set(['text/xml', 'text/html']))\n        self.assertEqual(mv.views, [(99, 'view2', None), (100, 'view', None)])\n        mv.add('view6', 98, 'text/*')\n        self.assertEqual(mv.views, [(98, 'view6', None),\n                                    (99, 'view2', None),\n                                    (100, 'view', None)])\n\n    def test_add_with_phash(self):\n        mv = self._makeOne()\n        mv.add('view', 100, phash='abc')\n        self.assertEqual(mv.views, [(100, 'view', 'abc')])\n        mv.add('view', 100, phash='abc')\n        self.assertEqual(mv.views, [(100, 'view', 'abc')])\n        mv.add('view', 100, phash='def')\n        self.assertEqual(mv.views, [(100, 'view', 'abc'),\n                                    (100, 'view', 'def')])\n        mv.add('view', 100, phash='abc')\n        self.assertEqual(mv.views, [(100, 'view', 'abc'),\n                                    (100, 'view', 'def')])\n\n    def test_add_with_phash_override_accept(self):\n        mv = self._makeOne()\n        def view1(): pass\n        def view2(): pass\n        def view3(): pass\n        mv.add(view1, 100, accept='text/html', phash='abc')\n        mv.add(view2, 100, accept='text/html', phash='abc')\n        mv.add(view3, 99, accept='text/html', phash='def')\n        self.assertEqual(mv.media_views['text/html'],\n                         [(99, view3, 'def'), (100, view2, 'abc')])\n\n    def test_add_with_phash_override_accept2(self):\n        mv = self._makeOne()\n        def view1(): pass\n        def view2(): pass\n        def view3(): pass\n        mv.add(view1, 100, accept='text/html', phash='abc')\n        mv.add(view2, 100, accept='text/html', phash='def')\n        mv.add(view3, 99, accept='text/html', phash='ghi')\n        self.assertEqual(mv.media_views['text/html'],\n                         [(99, view3, 'ghi'),\n                          (100, view1, 'abc'),\n                          (100, view2, 'def')]\n                         )\n\n    def test_multiple_with_functions_as_views(self):\n        # this failed on py3 at one point, because functions aren't orderable\n        # and we were sorting the views via a plain sort() rather than\n        # sort(key=itemgetter(0)).\n        def view1(request): pass\n        def view2(request): pass\n        mv = self._makeOne()\n        mv.add(view1, 100, None)\n        self.assertEqual(mv.views, [(100, view1, None)])\n        mv.add(view2, 100, None)\n        self.assertEqual(mv.views, [(100, view1, None), (100, view2, None)])\n\n    def test_get_views_request_has_no_accept(self):\n        request = DummyRequest()\n        mv = self._makeOne()\n        mv.views = [(99, lambda *arg: None)]\n        self.assertEqual(mv.get_views(request), mv.views)\n\n    def test_get_views_no_self_accepts(self):\n        request = DummyRequest()\n        request.accept = True\n        mv = self._makeOne()\n        mv.accepts = []\n        mv.views = [(99, lambda *arg: None)]\n        self.assertEqual(mv.get_views(request), mv.views)\n\n    def test_get_views(self):\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html')\n        mv = self._makeOne()\n        mv.accepts = ['text/html']\n        mv.views = [(99, lambda *arg: None)]\n        html_views = [(98, lambda *arg: None)]\n        mv.media_views['text/html'] = html_views\n        self.assertEqual(mv.get_views(request), html_views + mv.views)\n\n    def test_get_views_best_match_returns_None(self):\n        request = DummyRequest()\n        request.accept = DummyAccept(None)\n        mv = self._makeOne()\n        mv.accepts = ['text/html']\n        mv.views = [(99, lambda *arg: None)]\n        self.assertEqual(mv.get_views(request), mv.views)\n\n    def test_match_not_found(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv.match, context, request)\n\n    def test_match_predicate_fails(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        def view(context, request):\n            \"\"\" \"\"\"\n        view.__predicated__ = lambda *arg: False\n        mv.views = [(100, view, None)]\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv.match, context, request)\n\n    def test_match_predicate_succeeds(self):\n        mv = self._makeOne()\n        def view(context, request):\n            \"\"\" \"\"\"\n        view.__predicated__ = lambda *arg: True\n        mv.views = [(100, view, None)]\n        context = DummyContext()\n        request = DummyRequest()\n        result = mv.match(context, request)\n        self.assertEqual(result, view)\n\n    def test_permitted_no_views(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv.__permitted__, context, request)\n\n    def test_permitted_no_match_with__permitted__(self):\n        mv = self._makeOne()\n        def view(context, request):\n            \"\"\" \"\"\"\n        mv.views = [(100, view, None)]\n        self.assertEqual(mv.__permitted__(None, None), True)\n\n    def test_permitted(self):\n        mv = self._makeOne()\n        def view(context, request):\n            \"\"\" \"\"\"\n        def permitted(context, request):\n            return False\n        view.__permitted__ = permitted\n        mv.views = [(100, view, None)]\n        context = DummyContext()\n        request = DummyRequest()\n        result = mv.__permitted__(context, request)\n        self.assertEqual(result, False)\n\n    def test__call__not_found(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv, context, request)\n\n    def test___call__intermediate_not_found(self):\n        from pyramid.exceptions import PredicateMismatch\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        expected_response = DummyResponse()\n        def view1(context, request):\n            raise PredicateMismatch\n        def view2(context, request):\n            return expected_response\n        mv.views = [(100, view1, None), (99, view2, None)]\n        response = mv(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test___call__raise_not_found_isnt_interpreted_as_pred_mismatch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        def view1(context, request):\n            raise  HTTPNotFound\n        def view2(context, request):\n            \"\"\" \"\"\"\n        mv.views = [(100, view1, None), (99, view2, None)]\n        self.assertRaises(HTTPNotFound, mv, context, request)\n\n    def test___call__(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        expected_response = DummyResponse()\n        def view(context, request):\n            return expected_response\n        mv.views = [(100, view, None)]\n        response = mv(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test__call_permissive__not_found(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        self.assertRaises(HTTPNotFound, mv, context, request)\n\n    def test___call_permissive_has_call_permissive(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        expected_response = DummyResponse()\n        def view(context, request):\n            \"\"\" \"\"\"\n        def permissive(context, request):\n            return expected_response\n        view.__call_permissive__ = permissive\n        mv.views = [(100, view, None)]\n        response = mv.__call_permissive__(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test___call_permissive_has_no_call_permissive(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.view_name = ''\n        expected_response = DummyResponse()\n        def view(context, request):\n            return expected_response\n        mv.views = [(100, view, None)]\n        response = mv.__call_permissive__(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test__call__with_accept_match(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.accept = DummyAccept('text/html', 'text/xml')\n        expected_response = DummyResponse()\n        def view(context, request):\n            return expected_response\n        mv.views = [(100, None)]\n        mv.media_views['text/xml'] = [(100, view, None)]\n        mv.accepts = ['text/xml']\n        response = mv(context, request)\n        self.assertEqual(response, expected_response)\n\n    def test__call__with_accept_miss(self):\n        mv = self._makeOne()\n        context = DummyContext()\n        request = DummyRequest()\n        request.accept = DummyAccept('text/plain', 'text/html')\n        expected_response = DummyResponse()\n        def view(context, request):\n            return expected_response\n        mv.views = [(100, view, None)]\n        mv.media_views['text/xml'] = [(100, None, None)]\n        mv.accepts = ['text/xml']\n        response = mv(context, request)\n        self.assertEqual(response, expected_response)\n\nclass TestViewDeriver(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n\n    def tearDown(self):\n        self.config = None\n\n    def _makeOne(self, **kw):\n        kw['registry'] = self.config.registry\n        from pyramid.config.views import ViewDeriver\n        return ViewDeriver(**kw)\n\n    def _makeRequest(self):\n        request = DummyRequest()\n        request.registry = self.config.registry\n        return request\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n        logger = DummyLogger()\n        self.config.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSecurityPolicy(self, permissive):\n        from pyramid.interfaces import IAuthenticationPolicy\n        from pyramid.interfaces import IAuthorizationPolicy\n        policy = DummySecurityPolicy(permissive)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n\n    def test_function_returns_non_adaptable(self):\n        def view(request):\n            return None\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n            self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable function '\n                'pyramid.tests.test_config.test_views.view into a response '\n                'object. The value returned was None. You may have forgotten '\n                'to return a value from the view callable.'\n                )\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_function_returns_non_adaptable_dict(self):\n        def view(request):\n            return {'a':1}\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n            self.assertEqual(\n                e.args[0],\n                \"Could not convert return value of the view callable function \"\n                \"pyramid.tests.test_config.test_views.view into a response \"\n                \"object. The value returned was {'a': 1}. You may have \"\n                \"forgotten to define a renderer in the view configuration.\"\n                )\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_instance_returns_non_adaptable(self):\n        class AView(object):\n            def __call__(self, request):\n                return None\n        view = AView()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n            msg = e.args[0]\n            self.assertTrue(msg.startswith(\n                'Could not convert return value of the view callable object '\n                '<pyramid.tests.test_config.test_views.'))\n            self.assertTrue(msg.endswith(\n                '> into a response object. The value returned was None. You '\n                'may have forgotten to return a value from the view callable.'))\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_function_returns_true_Response_no_renderer(self):\n        from pyramid.response import Response\n        r = Response('Hello')\n        def view(request):\n            return r\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        response = result(None, None)\n        self.assertEqual(response, r)\n\n    def test_function_returns_true_Response_with_renderer(self):\n        from pyramid.response import Response\n        r = Response('Hello')\n        def view(request):\n            return r\n        renderer = object()\n        deriver = self._makeOne(renderer=renderer)\n        result = deriver(view)\n        self.assertFalse(result is view)\n        response = result(None, None)\n        self.assertEqual(response, r)\n\n    def test_requestonly_default_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return None\n        deriver = self._makeOne()\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n            result(None, request)\n        except ValueError as e:\n            self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable '\n                'method __call__ of '\n                'class pyramid.tests.test_config.test_views.AView into a '\n                'response object. The value returned was None. You may have '\n                'forgotten to return a value from the view callable.'\n                )\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_requestonly_nondefault_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def theviewmethod(self):\n                return None\n        deriver = self._makeOne(attr='theviewmethod')\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n            result(None, request)\n        except ValueError as e:\n            self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable '\n                'method theviewmethod of '\n                'class pyramid.tests.test_config.test_views.AView into a '\n                'response object. The value returned was None. You may have '\n                'forgotten to return a value from the view callable.'\n                )\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_requestonly_function(self):\n        response = DummyResponse()\n        def view(request):\n            return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result(None, None), response)\n\n    def test_requestonly_function_with_renderer(self):\n        response = DummyResponse()\n        class moo(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, 'OK')\n                self.assertEqual(view_inst, view)\n                self.assertEqual(ctx, context)\n                return response\n        def view(request):\n            return 'OK'\n        deriver = self._makeOne(renderer=moo())\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_requestonly_function_with_renderer_request_override(self):\n        def moo(info):\n            def inner(value, system):\n                self.assertEqual(value, 'OK')\n                self.assertEqual(system['request'], request)\n                self.assertEqual(system['context'], context)\n                return b'moo'\n            return inner\n        def view(request):\n            return 'OK'\n        self.config.add_renderer('moo', moo)\n        deriver = self._makeOne(renderer='string')\n        result = deriver(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        request.override_renderer = 'moo'\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request).body, b'moo')\n\n    def test_requestonly_function_with_renderer_request_has_view(self):\n        response = DummyResponse()\n        class moo(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, 'OK')\n                self.assertEqual(view_inst, 'view')\n                self.assertEqual(ctx, context)\n                return response\n        def view(request):\n            return 'OK'\n        deriver = self._makeOne(renderer=moo())\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        request = self._makeRequest()\n        request.__view__ = 'view'\n        context = testing.DummyResource()\n        r = result(context, request)\n        self.assertEqual(r, response)\n        self.assertFalse(hasattr(request, '__view__'))\n\n    def test_class_without_attr(self):\n        response = DummyResponse()\n        class View(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(View)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, View)\n\n    def test_class_with_attr(self):\n        response = DummyResponse()\n        class View(object):\n            def __init__(self, request):\n                pass\n            def another(self):\n                return response\n        deriver = self._makeOne(attr='another')\n        result = deriver(View)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, View)\n\n    def test_as_function_context_and_request(self):\n        def view(context, request):\n            return 'OK'\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertTrue(result.__wraps__ is view)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        self.assertEqual(view(None, None), 'OK')\n\n    def test_as_function_requestonly(self):\n        response = DummyResponse()\n        def view(request):\n            return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        self.assertEqual(result(None, None), response)\n\n    def test_as_newstyle_class_context_and_request(self):\n        response = DummyResponse()\n        class view(object):\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_as_newstyle_class_requestonly(self):\n        response = DummyResponse()\n        class view(object):\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_as_oldstyle_class_context_and_request(self):\n        response = DummyResponse()\n        class view:\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_as_oldstyle_class_requestonly(self):\n        response = DummyResponse()\n        class view:\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return response\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(request.__view__.__class__, view)\n\n    def test_as_instance_context_and_request(self):\n        response = DummyResponse()\n        class View:\n            def __call__(self, context, request):\n                return response\n        view = View()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertTrue(result.__wraps__ is view)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        self.assertEqual(result(None, None), response)\n\n    def test_as_instance_requestonly(self):\n        response = DummyResponse()\n        class View:\n            def __call__(self, request):\n                return response\n        view = View()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertTrue('test_views' in result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        self.assertEqual(result(None, None), response)\n\n    def test_with_debug_authorization_no_authpol(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): Allowed \"\n                         \"(no authorization policy in use)\")\n\n    def test_with_debug_authorization_authn_policy_no_authz_policy(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(debug_authorization=True)\n        from pyramid.interfaces import IAuthenticationPolicy\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        logger = self._registerLogger()\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): Allowed \"\n                         \"(no authorization policy in use)\")\n\n    def test_with_debug_authorization_authz_policy_no_authn_policy(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(debug_authorization=True)\n        from pyramid.interfaces import IAuthorizationPolicy\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n        logger = self._registerLogger()\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): Allowed \"\n                         \"(no authorization policy in use)\")\n\n    def test_with_debug_authorization_no_permission(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        self._registerSecurityPolicy(True)\n        logger = self._registerLogger()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): Allowed (\"\n                         \"no permission registered)\")\n\n    def test_debug_auth_permission_authpol_permitted(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        self._registerSecurityPolicy(True)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertEqual(result.__call_permissive__.__wraps__, view)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): True\")\n\n    def test_debug_auth_permission_authpol_permitted_no_request(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        self._registerSecurityPolicy(True)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertEqual(result.__call_permissive__.__wraps__, view)\n        self.assertEqual(result(None, None), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url None (view name \"\n                         \"None against context None): True\")\n\n    def test_debug_auth_permission_authpol_denied(self):\n        from pyramid.httpexceptions import HTTPForbidden\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        self._registerSecurityPolicy(False)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertEqual(result.__call_permissive__.__wraps__, view)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertRaises(HTTPForbidden, result, None, request)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): False\")\n\n    def test_debug_auth_permission_authpol_denied2(self):\n        view = lambda *arg: 'OK'\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        self._registerLogger()\n        self._registerSecurityPolicy(False)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        permitted = result.__permitted__(None, None)\n        self.assertEqual(permitted, False)\n\n    def test_debug_auth_permission_authpol_overridden(self):\n        from pyramid.security import NO_PERMISSION_REQUIRED\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = dict(\n            debug_authorization=True, reload_templates=True)\n        logger = self._registerLogger()\n        self._registerSecurityPolicy(False)\n        deriver = self._makeOne(permission=NO_PERMISSION_REQUIRED)\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(logger.messages[0],\n                         \"debug_authorization of url url (view name \"\n                         \"'view_name' against context None): \"\n                         \"Allowed (NO_PERMISSION_REQUIRED)\")\n\n    def test_secured_view_authn_policy_no_authz_policy(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = {}\n        from pyramid.interfaces import IAuthenticationPolicy\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n\n    def test_secured_view_authz_policy_no_authn_policy(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = {}\n        from pyramid.interfaces import IAuthorizationPolicy\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n        self.assertEqual(view.__name__, result.__name__)\n        self.assertFalse(hasattr(result, '__call_permissive__'))\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        self.assertEqual(result(None, request), response)\n\n    def test_secured_view_raises_forbidden_no_name(self):\n        from pyramid.interfaces import IAuthenticationPolicy\n        from pyramid.interfaces import IAuthorizationPolicy\n        from pyramid.httpexceptions import HTTPForbidden\n        response = DummyResponse()\n        view = lambda *arg: response\n        self.config.registry.settings = {}\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n        deriver = self._makeOne(permission='view')\n        result = deriver(view)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        try:\n            result(None, request)\n        except HTTPForbidden as e:\n            self.assertEqual(e.message,\n                             'Unauthorized: <lambda> failed permission check')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_secured_view_raises_forbidden_with_name(self):\n        from pyramid.interfaces import IAuthenticationPolicy\n        from pyramid.interfaces import IAuthorizationPolicy\n        from pyramid.httpexceptions import HTTPForbidden\n        def myview(request): pass\n        self.config.registry.settings = {}\n        policy = DummySecurityPolicy(False)\n        self.config.registry.registerUtility(policy, IAuthenticationPolicy)\n        self.config.registry.registerUtility(policy, IAuthorizationPolicy)\n        deriver = self._makeOne(permission='view')\n        result = deriver(myview)\n        request = self._makeRequest()\n        request.view_name = 'view_name'\n        request.url = 'url'\n        try:\n            result(None, request)\n        except HTTPForbidden as e:\n            self.assertEqual(e.message,\n                             'Unauthorized: myview failed permission check')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_predicate_mismatch_view_has_no_name(self):\n        from pyramid.exceptions import PredicateMismatch\n        response = DummyResponse()\n        view = lambda *arg: response\n        def predicate1(context, request):\n            return False\n        predicate1.text = lambda *arg: 'text'\n        deriver = self._makeOne(predicates=[predicate1])\n        result = deriver(view)\n        request = self._makeRequest()\n        request.method = 'POST'\n        try:\n            result(None, None)\n        except PredicateMismatch as e:\n            self.assertEqual(e.detail,\n                             'predicate mismatch for view <lambda> (text)')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_predicate_mismatch_view_has_name(self):\n        from pyramid.exceptions import PredicateMismatch\n        def myview(request): pass\n        def predicate1(context, request):\n            return False\n        predicate1.text = lambda *arg: 'text'\n        deriver = self._makeOne(predicates=[predicate1])\n        result = deriver(myview)\n        request = self._makeRequest()\n        request.method = 'POST'\n        try:\n            result(None, None)\n        except PredicateMismatch as e:\n            self.assertEqual(e.detail,\n                             'predicate mismatch for view myview (text)')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_predicate_mismatch_exception_has_text_in_detail(self):\n        from pyramid.exceptions import PredicateMismatch\n        def myview(request): pass\n        def predicate1(context, request):\n            return True\n        predicate1.text = lambda *arg: 'pred1'\n        def predicate2(context, request):\n            return False\n        predicate2.text = lambda *arg: 'pred2'\n        deriver = self._makeOne(predicates=[predicate1, predicate2])\n        result = deriver(myview)\n        request = self._makeRequest()\n        request.method = 'POST'\n        try:\n            result(None, None)\n        except PredicateMismatch as e:\n            self.assertEqual(e.detail,\n                             'predicate mismatch for view myview (pred2)')\n        else: # pragma: no cover\n            raise AssertionError\n\n    def test_with_predicates_all(self):\n        response = DummyResponse()\n        view = lambda *arg: response\n        predicates = []\n        def predicate1(context, request):\n            predicates.append(True)\n            return True\n        def predicate2(context, request):\n            predicates.append(True)\n            return True\n        deriver = self._makeOne(predicates=[predicate1, predicate2])\n        result = deriver(view)\n        request = self._makeRequest()\n        request.method = 'POST'\n        next = result(None, None)\n        self.assertEqual(next, response)\n        self.assertEqual(predicates, [True, True])\n\n    def test_with_predicates_checker(self):\n        view = lambda *arg: 'OK'\n        predicates = []\n        def predicate1(context, request):\n            predicates.append(True)\n            return True\n        def predicate2(context, request):\n            predicates.append(True)\n            return True\n        deriver = self._makeOne(predicates=[predicate1, predicate2])\n        result = deriver(view)\n        request = self._makeRequest()\n        request.method = 'POST'\n        next = result.__predicated__(None, None)\n        self.assertEqual(next, True)\n        self.assertEqual(predicates, [True, True])\n\n    def test_with_predicates_notall(self):\n        from pyramid.httpexceptions import HTTPNotFound\n        view = lambda *arg: 'OK'\n        predicates = []\n        def predicate1(context, request):\n            predicates.append(True)\n            return True\n        predicate1.text = lambda *arg: 'text'\n        def predicate2(context, request):\n            predicates.append(True)\n            return False\n        predicate2.text = lambda *arg: 'text'\n        deriver = self._makeOne(predicates=[predicate1, predicate2])\n        result = deriver(view)\n        request = self._makeRequest()\n        request.method = 'POST'\n        self.assertRaises(HTTPNotFound, result, None, None)\n        self.assertEqual(predicates, [True, True])\n\n    def test_with_wrapper_viewname(self):\n        from pyramid.response import Response\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        inner_response = Response('OK')\n        def inner_view(context, request):\n            return inner_response\n        def outer_view(context, request):\n            self.assertEqual(request.wrapped_response, inner_response)\n            self.assertEqual(request.wrapped_body, inner_response.body)\n            self.assertEqual(request.wrapped_view.__original_view__,\n                             inner_view)\n            return Response(b'outer ' + request.wrapped_body)\n        self.config.registry.registerAdapter(\n            outer_view, (IViewClassifier, None, None), IView, 'owrap')\n        deriver = self._makeOne(viewname='inner',\n                                wrapper_viewname='owrap')\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        response = result(None, request)\n        self.assertEqual(response.body, b'outer OK')\n\n    def test_with_wrapper_viewname_notfound(self):\n        from pyramid.response import Response\n        inner_response = Response('OK')\n        def inner_view(context, request):\n            return inner_response\n        deriver = self._makeOne(viewname='inner', wrapper_viewname='owrap')\n        wrapped = deriver(inner_view)\n        request = self._makeRequest()\n        self.assertRaises(ValueError, wrapped, None, request)\n\n    def test_as_newstyle_class_context_and_request_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst.__class__, View)\n                self.assertEqual(ctx, context)\n                return response\n        class View(object):\n            def __init__(self, context, request):\n                pass\n            def index(self):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        result = deriver(View)\n        self.assertFalse(result is View)\n        self.assertEqual(result.__module__, View.__module__)\n        self.assertEqual(result.__doc__, View.__doc__)\n        self.assertEqual(result.__name__, View.__name__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_newstyle_class_requestonly_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst.__class__, View)\n                self.assertEqual(ctx, context)\n                return response\n        class View(object):\n            def __init__(self, request):\n                pass\n            def index(self):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        result = deriver(View)\n        self.assertFalse(result is View)\n        self.assertEqual(result.__module__, View.__module__)\n        self.assertEqual(result.__doc__, View.__doc__)\n        self.assertEqual(result.__name__, View.__name__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_oldstyle_cls_context_request_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst.__class__, View)\n                self.assertEqual(ctx, context)\n                return response\n        class View:\n            def __init__(self, context, request):\n                pass\n            def index(self):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        result = deriver(View)\n        self.assertFalse(result is View)\n        self.assertEqual(result.__module__, View.__module__)\n        self.assertEqual(result.__doc__, View.__doc__)\n        self.assertEqual(result.__name__, View.__name__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_oldstyle_cls_requestonly_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst.__class__, View)\n                self.assertEqual(ctx, context)\n                return response\n        class View:\n            def __init__(self, request):\n                pass\n            def index(self):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        result = deriver(View)\n        self.assertFalse(result is View)\n        self.assertEqual(result.__module__, View.__module__)\n        self.assertEqual(result.__doc__, View.__doc__)\n        self.assertEqual(result.__name__, View.__name__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_instance_context_and_request_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst, view)\n                self.assertEqual(ctx, context)\n                return response\n        class View:\n            def index(self, context, request):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        view = View()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result.__module__, view.__module__)\n        self.assertEqual(result.__doc__, view.__doc__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_as_instance_requestonly_attr_and_renderer(self):\n        response = DummyResponse()\n        class renderer(object):\n            def render_view(inself, req, resp, view_inst, ctx):\n                self.assertEqual(req, request)\n                self.assertEqual(resp, {'a':'1'})\n                self.assertEqual(view_inst, view)\n                self.assertEqual(ctx, context)\n                return response\n        class View:\n            def index(self, request):\n                return {'a':'1'}\n        deriver = self._makeOne(renderer=renderer(), attr='index')\n        view = View()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(result.__module__, view.__module__)\n        self.assertEqual(result.__doc__, view.__doc__)\n        request = self._makeRequest()\n        context = testing.DummyResource()\n        self.assertEqual(result(context, request), response)\n\n    def test_with_view_mapper_config_specified(self):\n        response = DummyResponse()\n        class mapper(object):\n            def __init__(self, **kw):\n                self.kw = kw\n            def __call__(self, view):\n                def wrapped(context, request):\n                    return response\n                return wrapped\n        def view(context, request): return 'NOTOK'\n        deriver = self._makeOne(mapper=mapper)\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        self.assertEqual(result(None, None), response)\n\n    def test_with_view_mapper_view_specified(self):\n        from pyramid.response import Response\n        response = Response()\n        def mapper(**kw):\n            def inner(view):\n                def superinner(context, request):\n                    self.assertEqual(request, None)\n                    return response\n                return superinner\n            return inner\n        def view(context, request): return 'NOTOK'\n        view.__view_mapper__ = mapper\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        self.assertEqual(result(None, None), response)\n\n    def test_with_view_mapper_default_mapper_specified(self):\n        from pyramid.response import Response\n        response = Response()\n        def mapper(**kw):\n            def inner(view):\n                def superinner(context, request):\n                    self.assertEqual(request, None)\n                    return  response\n                return superinner\n            return inner\n        self.config.set_view_mapper(mapper)\n        def view(context, request): return 'NOTOK'\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result.__wraps__ is view)\n        self.assertEqual(result(None, None), response)\n\n    def test_attr_wrapped_view_branching_default_phash(self):\n        from pyramid.config.util import DEFAULT_PHASH\n        def view(context, request): pass\n        deriver = self._makeOne(phash=DEFAULT_PHASH)\n        result = deriver(view)\n        self.assertEqual(result.__wraps__, view)\n\n    def test_attr_wrapped_view_branching_nondefault_phash(self):\n        def view(context, request): pass\n        deriver = self._makeOne(phash='nondefault')\n        result = deriver(view)\n        self.assertNotEqual(result, view)\n\n    def test_http_cached_view_integer(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=3600)\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(hours=1)\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n        self.assertEqual(headers['Cache-Control'], 'max-age=3600')\n\n    def test_http_cached_view_timedelta(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=datetime.timedelta(hours=1))\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(hours=1)\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n        self.assertEqual(headers['Cache-Control'], 'max-age=3600')\n\n    def test_http_cached_view_tuple(self):\n        import datetime\n        from pyramid.response import Response\n        response = Response('OK')\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=(3600, {'public':True}))\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        when = datetime.datetime.utcnow() + datetime.timedelta(hours=1)\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        expires = parse_httpdate(headers['Expires'])\n        assert_similar_datetime(expires, when)\n        self.assertEqual(headers['Cache-Control'], 'max-age=3600, public')\n\n    def test_http_cached_view_tuple_seconds_None(self):\n        from pyramid.response import Response\n        response = Response('OK')\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=(None, {'public':True}))\n        result = deriver(inner_view)\n        self.assertFalse(result is inner_view)\n        self.assertEqual(inner_view.__module__, result.__module__)\n        self.assertEqual(inner_view.__doc__, result.__doc__)\n        request = self._makeRequest()\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        self.assertFalse('Expires' in headers)\n        self.assertEqual(headers['Cache-Control'], 'public')\n\n    def test_http_cached_view_prevent_auto_set(self):\n        from pyramid.response import Response\n        response = Response()\n        response.cache_control.prevent_auto = True\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=3600)\n        result = deriver(inner_view)\n        request = self._makeRequest()\n        result = result(None, request)\n        self.assertEqual(result, response) # doesn't blow up\n        headers = dict(result.headerlist)\n        self.assertFalse('Expires' in headers)\n        self.assertFalse('Cache-Control' in headers)\n\n    def test_http_cached_prevent_http_cache_in_settings(self):\n        self.config.registry.settings['prevent_http_cache'] = True\n        from pyramid.response import Response\n        response = Response()\n        def inner_view(context, request):\n            return response\n        deriver = self._makeOne(http_cache=3600)\n        result = deriver(inner_view)\n        request = self._makeRequest()\n        result = result(None, request)\n        self.assertEqual(result, response)\n        headers = dict(result.headerlist)\n        self.assertFalse('Expires' in headers)\n        self.assertFalse('Cache-Control' in headers)\n\n    def test_http_cached_view_bad_tuple(self):\n        deriver = self._makeOne(http_cache=(None,))\n        def view(request): pass\n        self.assertRaises(ConfigurationError, deriver, view)\n\nclass TestDefaultViewMapper(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        del self.registry\n        testing.tearDown()\n\n    def _makeOne(self, **kw):\n        from pyramid.config.views import DefaultViewMapper\n        kw['registry'] = self.registry\n        return DefaultViewMapper(**kw)\n\n    def _makeRequest(self):\n        request = DummyRequest()\n        request.registry = self.registry\n        return request\n\n    def test_view_as_function_context_and_request(self):\n        def view(context, request):\n            return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertTrue(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test__view_as_function_with_attr(self):\n        def view(context, request):\n            \"\"\" \"\"\"\n        mapper = self._makeOne(attr='__name__')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertRaises(TypeError, result, None, request)\n\n    def test_view_as_function_requestonly(self):\n        def view(request):\n            return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_function_requestonly_with_attr(self):\n        def view(request):\n            \"\"\" \"\"\"\n        mapper = self._makeOne(attr='__name__')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertRaises(TypeError, result, None, request)\n\n    def test_view_as_newstyle_class_context_and_request(self):\n        class view(object):\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_newstyle_class_context_and_request_with_attr(self):\n        class view(object):\n            def __init__(self, context, request):\n                pass\n            def index(self):\n                return 'OK'\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_newstyle_class_requestonly(self):\n        class view(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_newstyle_class_requestonly_with_attr(self):\n        class view(object):\n            def __init__(self, request):\n                pass\n            def index(self):\n                return 'OK'\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_oldstyle_class_context_and_request(self):\n        class view:\n            def __init__(self, context, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_oldstyle_class_context_and_request_with_attr(self):\n        class view:\n            def __init__(self, context, request):\n                pass\n            def index(self):\n                return 'OK'\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_oldstyle_class_requestonly(self):\n        class view:\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_oldstyle_class_requestonly_with_attr(self):\n        class view:\n            def __init__(self, request):\n                pass\n            def index(self):\n                return 'OK'\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_instance_context_and_request(self):\n        class View:\n            def __call__(self, context, request):\n                return 'OK'\n        view = View()\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertTrue(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_instance_context_and_request_and_attr(self):\n        class View:\n            def index(self, context, request):\n                return 'OK'\n        view = View()\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_instance_requestonly(self):\n        class View:\n            def __call__(self, request):\n                return 'OK'\n        view = View()\n        mapper = self._makeOne()\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\n    def test_view_as_instance_requestonly_with_attr(self):\n        class View:\n            def index(self, request):\n                return 'OK'\n        view = View()\n        mapper = self._makeOne(attr='index')\n        result = mapper(view)\n        self.assertFalse(result is view)\n        request = self._makeRequest()\n        self.assertEqual(result(None, request), 'OK')\n\nclass Test_preserve_view_attrs(unittest.TestCase):\n    def _callFUT(self, view, wrapped_view):\n        from pyramid.config.views import preserve_view_attrs\n        return preserve_view_attrs(view, wrapped_view)\n\n    def test_it_same(self):\n        def view(context, request):\n            \"\"\" \"\"\"\n        result = self._callFUT(view, view)\n        self.assertTrue(result is view)\n\n    def test_it_view_is_None(self):\n        def view(context, request):\n            \"\"\" \"\"\"\n        result = self._callFUT(None, view)\n        self.assertTrue(result is view)\n\n    def test_it_different_with_existing_original_view(self):\n        def view1(context, request): pass\n        view1.__original_view__ = 'abc'\n        def view2(context, request): pass\n        result = self._callFUT(view1, view2)\n        self.assertEqual(result.__original_view__, 'abc')\n        self.assertFalse(result is view1)\n\n    def test_it_different(self):\n        class DummyView1:\n            \"\"\" 1 \"\"\"\n            __name__ = '1'\n            __module__ = '1'\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n            def __call_permissive__(self, context, request):\n                \"\"\" \"\"\"\n            def __predicated__(self, context, request):\n                \"\"\" \"\"\"\n            def __permitted__(self, context, request):\n                \"\"\" \"\"\"\n        class DummyView2:\n            \"\"\" 2 \"\"\"\n            __name__ = '2'\n            __module__ = '2'\n            def __call__(self, context, request):\n                \"\"\" \"\"\"\n            def __call_permissive__(self, context, request):\n                \"\"\" \"\"\"\n            def __predicated__(self, context, request):\n                \"\"\" \"\"\"\n            def __permitted__(self, context, request):\n                \"\"\" \"\"\"\n        view1 = DummyView1()\n        view2 = DummyView2()\n        result = self._callFUT(view2, view1)\n        self.assertEqual(result, view1)\n        self.assertTrue(view1.__original_view__ is view2)\n        self.assertTrue(view1.__doc__ is view2.__doc__)\n        self.assertTrue(view1.__module__ is view2.__module__)\n        self.assertTrue(view1.__name__ is view2.__name__)\n        self.assertTrue(getattr(view1.__call_permissive__, im_func) is\n                        getattr(view2.__call_permissive__, im_func))\n        self.assertTrue(getattr(view1.__permitted__, im_func) is\n                        getattr(view2.__permitted__, im_func))\n        self.assertTrue(getattr(view1.__predicated__, im_func) is\n                        getattr(view2.__predicated__, im_func))\n\n\nclass TestStaticURLInfo(unittest.TestCase):\n    def _getTargetClass(self):\n        from pyramid.config.views import StaticURLInfo\n        return StaticURLInfo\n\n    def _makeOne(self):\n        return self._getTargetClass()()\n\n    def _makeConfig(self, registrations=None):\n        config = DummyConfig()\n        registry = DummyRegistry()\n        if registrations is not None:\n            registry._static_url_registrations = registrations\n        config.registry = registry\n        return config\n\n    def _makeRequest(self):\n        request = DummyRequest()\n        request.registry = DummyRegistry()\n        return request\n\n    def _assertRegistrations(self, config, expected):\n        self.assertEqual(config.registry._static_url_registrations, expected)\n\n    def test_verifyClass(self):\n        from pyramid.interfaces import IStaticURLInfo\n        from zope.interface.verify import verifyClass\n        verifyClass(IStaticURLInfo, self._getTargetClass())\n\n    def test_verifyObject(self):\n        from pyramid.interfaces import IStaticURLInfo\n        from zope.interface.verify import verifyObject\n        verifyObject(IStaticURLInfo, self._makeOne())\n\n    def test_generate_missing(self):\n        inst = self._makeOne()\n        request = self._makeRequest()\n        self.assertRaises(ValueError, inst.generate, 'path', request)\n\n    def test_generate_registration_miss(self):\n        inst = self._makeOne()\n        registrations = [(None, 'spec', 'route_name'),\n                         ('http://example.com/foo/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        result = inst.generate('package:path/abc', request)\n        self.assertEqual(result, 'http://example.com/foo/abc')\n\n    def test_generate_registration_no_registry_on_request(self):\n        inst = self._makeOne()\n        registrations = [('http://example.com/foo/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        del request.registry\n        result = inst.generate('package:path/abc', request)\n        self.assertEqual(result, 'http://example.com/foo/abc')\n\n    def test_generate_slash_in_name1(self):\n        inst = self._makeOne()\n        registrations = [('http://example.com/foo/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        result = inst.generate('package:path/abc', request)\n        self.assertEqual(result, 'http://example.com/foo/abc')\n\n    def test_generate_slash_in_name2(self):\n        inst = self._makeOne()\n        registrations = [('http://example.com/foo/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        result = inst.generate('package:path/', request)\n        self.assertEqual(result, 'http://example.com/foo/')\n\n    def test_generate_quoting(self):\n        config = testing.setUp()\n        try:\n            config.add_static_view('images', path='mypkg:templates')\n            inst = self._makeOne()\n            request = testing.DummyRequest()\n            request.registry = config.registry\n            result = inst.generate('mypkg:templates/foo%2Fbar', request)\n            self.assertEqual(result, 'http://example.com/images/foo%252Fbar')\n        finally:\n            testing.tearDown()\n\n    def test_generate_route_url(self):\n        inst = self._makeOne()\n        registrations = [(None, 'package:path/', '__viewname/')]\n        inst._get_registrations = lambda *x: registrations\n        def route_url(n, **kw):\n            self.assertEqual(n, '__viewname/')\n            self.assertEqual(kw, {'subpath':'abc', 'a':1})\n            return 'url'\n        request = self._makeRequest()\n        request.route_url = route_url\n        result = inst.generate('package:path/abc', request, a=1)\n        self.assertEqual(result, 'url')\n\n    def test_generate_url_unquoted_local(self):\n        inst = self._makeOne()\n        registrations = [(None, 'package:path/', '__viewname/')]\n        inst._get_registrations = lambda *x: registrations\n        def route_url(n, **kw):\n            self.assertEqual(n, '__viewname/')\n            self.assertEqual(kw, {'subpath':'abc def', 'a':1})\n            return 'url'\n        request = self._makeRequest()\n        request.route_url = route_url\n        result = inst.generate('package:path/abc def', request, a=1)\n        self.assertEqual(result, 'url')\n\n    def test_generate_url_quoted_remote(self):\n        inst = self._makeOne()\n        registrations = [('http://example.com/', 'package:path/', None)]\n        inst._get_registrations = lambda *x: registrations\n        request = self._makeRequest()\n        result = inst.generate('package:path/abc def', request, a=1)\n        self.assertEqual(result, 'http://example.com/abc%20def')\n\n    def test_add_already_exists(self):\n        inst = self._makeOne()\n        config = self._makeConfig(\n            [('http://example.com/', 'package:path/', None)])\n        inst.add(config, 'http://example.com', 'anotherpackage:path')\n        expected = [('http://example.com/',  'anotherpackage:path/', None)]\n        self._assertRegistrations(config, expected)\n\n    def test_add_url_withendslash(self):\n        inst = self._makeOne()\n        config = self._makeConfig()\n        inst.add(config, 'http://example.com/', 'anotherpackage:path')\n        expected = [('http://example.com/', 'anotherpackage:path/', None)]\n        self._assertRegistrations(config, expected)\n\n    def test_add_url_noendslash(self):\n        inst = self._makeOne()\n        config = self._makeConfig()\n        inst.add(config, 'http://example.com', 'anotherpackage:path')\n        expected = [('http://example.com/', 'anotherpackage:path/', None)]\n        self._assertRegistrations(config, expected)\n\n    def test_add_url_noscheme(self):\n        inst = self._makeOne()\n        config = self._makeConfig()\n        inst.add(config, '//example.com', 'anotherpackage:path')\n        expected = [('//example.com/', 'anotherpackage:path/', None)]\n        self._assertRegistrations(config, expected)\n\n    def test_add_viewname(self):\n        from pyramid.security import NO_PERMISSION_REQUIRED\n        from pyramid.static import static_view\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1)\n        expected = [(None, 'anotherpackage:path/', '__view/')]\n        self._assertRegistrations(config, expected)\n        self.assertEqual(config.route_args, ('__view/', 'view/*subpath'))\n        self.assertEqual(config.view_kw['permission'], NO_PERMISSION_REQUIRED)\n        self.assertEqual(config.view_kw['view'].__class__, static_view)\n\n    def test_add_viewname_with_route_prefix(self):\n        config = self._makeConfig()\n        config.route_prefix = '/abc'\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path',)\n        expected = [(None, 'anotherpackage:path/', '__/abc/view/')]\n        self._assertRegistrations(config, expected)\n        self.assertEqual(config.route_args, ('__/abc/view/', 'view/*subpath'))\n\n    def test_add_viewname_with_permission(self):\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1,\n                 permission='abc')\n        self.assertEqual(config.view_kw['permission'], 'abc')\n\n    def test_add_viewname_with_context(self):\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1,\n                 context=DummyContext)\n        self.assertEqual(config.view_kw['context'], DummyContext)\n        \n    def test_add_viewname_with_for_(self):\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1,\n                 for_=DummyContext)\n        self.assertEqual(config.view_kw['context'], DummyContext)\n\n    def test_add_viewname_with_renderer(self):\n        config = self._makeConfig()\n        inst = self._makeOne()\n        inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1,\n                 renderer='mypackage:templates/index.pt')\n        self.assertEqual(config.view_kw['renderer'],\n                         'mypackage:templates/index.pt')\n\nclass Test_view_description(unittest.TestCase):\n    def _callFUT(self, view):\n        from pyramid.config.views import view_description\n        return view_description(view)\n\n    def test_with_text(self):\n        def view(): pass\n        view.__text__ = 'some text'\n        result = self._callFUT(view)\n        self.assertEqual(result, 'some text')\n\n    def test_without_text(self):\n        def view(): pass\n        result = self._callFUT(view)\n        self.assertEqual(result,\n                         'function pyramid.tests.test_config.test_views.view')\n\n\nclass DummyRegistry:\n    pass\n\nfrom zope.interface import implementer\nfrom pyramid.interfaces import IResponse\n@implementer(IResponse)\nclass DummyResponse(object):\n    content_type = None\n    default_content_type = None\n    body = None\n\nclass DummyRequest:\n    subpath = ()\n    matchdict = None\n\n    def __init__(self, environ=None):\n        if environ is None:\n            environ = {}\n        self.environ = environ\n        self.params = {}\n        self.cookies = {}\n        self.response = DummyResponse()\n\nclass DummyContext:\n    pass\n\nclass DummyAccept(object):\n    def __init__(self, *matches):\n        self.matches = list(matches)\n\n    def best_match(self, offered):\n        if self.matches:\n            for match in self.matches:\n                if match in offered:\n                    self.matches.remove(match)\n                    return match\n    def __contains__(self, val):\n        return val in self.matches\n\nclass DummyLogger:\n    def __init__(self):\n        self.messages = []\n    def info(self, msg):\n        self.messages.append(msg)\n    warn = info\n    debug = info\n\nclass DummySecurityPolicy:\n    def __init__(self, permitted=True):\n        self.permitted = permitted\n\n    def effective_principals(self, request):\n        return []\n\n    def permits(self, context, principals, permission):\n        return self.permitted\n\nclass DummyConfig:\n    route_prefix = ''\n    def add_route(self, *args, **kw):\n        self.route_args = args\n        self.route_kw = kw\n\n    def add_view(self, *args, **kw):\n        self.view_args = args\n        self.view_kw = kw\n\n    def action(self, discriminator, callable, introspectables=()):\n        callable()\n\n    def introspectable(self, *arg):\n        return {}\n\nfrom zope.interface import implementer\nfrom pyramid.interfaces import IMultiView\n@implementer(IMultiView)\nclass DummyMultiView:\n    def __init__(self):\n        self.views = []\n        self.name = 'name'\n    def add(self, view, order, accept=None, phash=None):\n        self.views.append((view, accept, phash))\n    def __call__(self, context, request):\n        return 'OK1'\n    def __permitted__(self, context, request):\n        \"\"\" \"\"\"\n\ndef parse_httpdate(s):\n    import datetime\n    # cannot use %Z, must use literal GMT; Jython honors timezone\n    # but CPython does not\n    return datetime.datetime.strptime(s, \"%a, %d %b %Y %H:%M:%S GMT\")\n\ndef assert_similar_datetime(one, two):\n    for attr in ('year', 'month', 'day', 'hour', 'minute'):\n        one_attr = getattr(one, attr)\n        two_attr = getattr(two, attr)\n        if not one_attr == two_attr: # pragma: no cover\n            raise AssertionError('%r != %r in %s' % (one_attr, two_attr, attr))\n\nclass DummyStaticURLInfo:\n    def __init__(self):\n        self.added = []\n\n    def add(self, config, name, spec, **kw):\n        self.added.append((config, name, spec, kw))\n\nclass DummyViewDefaultsClass(object):\n    __view_defaults__ = {\n        'containment':'pyramid.tests.test_config.IDummy'\n        }\n    def __init__(self, request):\n        pass\n    def __call__(self):\n        return 'OK'\n\nclass DummyPredicate(object):\n    def __init__(self, val, config):\n        self.val = val\n\n    def text(self):\n        return 'dummy'\n\n    phash = text\n\nclass DummyIntrospector(object):\n    def __init__(self, getval=None):\n        self.related = []\n        self.introspectables = []\n        self.getval = getval\n    def add(self, introspectable):\n        self.introspectables.append(introspectable)\n    def get(self, name, discrim):\n        return self.getval\n    def relate(self, a, b):\n        self.related.append((a, b))\n"
    ],
    "test_file_names": [
        "test_1.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "",
    "setup_res_stderr": "Using CPython 3.8.20\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 9 packages in 595ms\nPrepared 1 package in 732ms\nInstalled 9 packages in 12ms\n + pastedeploy==3.1.0\n + pyramid==1.5a2 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1)\n + repoze-lru==0.7\n + setuptools==75.3.0\n + translationstring==1.4\n + venusian==3.1.1\n + webob==1.8.9\n + zope-deprecation==5.0\n + zope-interface==7.2\nResolved 21 packages in 16ms\nInstalled 12 packages in 11ms\n + beautifulsoup4==4.12.3\n + coverage==7.6.1\n + distlib==0.3.9\n + filelock==3.16.1\n + nose==1.3.7\n + nose-selecttests==0.5\n + platformdirs==4.3.6\n + six==1.17.0\n + soupsieve==2.6\n + virtualenv==20.29.0\n + waitress==3.0.0\n + webtest==3.0.1\nResolved 16 packages in 26ms\nInstalled 12 packages in 9ms\n + cachetools==5.5.0\n + chardet==5.2.0\n + colorama==0.4.6\n + exceptiongroup==1.2.2\n + iniconfig==2.0.0\n + packaging==24.2\n + pluggy==1.5.0\n + pyproject-api==1.8.0\n + pytest==8.3.4\n + tomli==2.2.1\n + tox==4.23.2\n + typing-extensions==4.12.2\n",
    "new_commit_res_code": 1,
    "new_commit_res_stdout": "============================= test session starts ==============================\nplatform linux -- Python 3.8.20, pytest-8.3.4, pluggy-1.5.0\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1\ncollected 1111 items\n\nr2e_tests/test_1.py ....................FF............F................. [  4%]\n..................FF......................................FF............ [ 11%]\n..........................................F..................FF......... [ 17%]\nF...F....F..........................................................F    [ 23%]\nr2e_tests/test_config/test_adapters.py .FF..............F...             [ 25%]\nr2e_tests/test_config/test_assets.py ...........FF...................... [ 28%]\n.....F..........................                                         [ 31%]\nr2e_tests/test_config/test_factories.py ..................               [ 33%]\nr2e_tests/test_config/test_i18n.py FFF.FF...                             [ 34%]\nr2e_tests/test_config/test_init.py ..................................... [ 37%]\n.F..F....................F...........F....................FF...FFF...... [ 44%]\n..............                                                           [ 45%]\nr2e_tests/test_config/test_predicates.py ............................... [ 48%]\n........................................                                 [ 51%]\nr2e_tests/test_config/test_rendering.py ...                              [ 51%]\nr2e_tests/test_config/test_routes.py ........................            [ 54%]\nr2e_tests/test_config/test_security.py ..........                        [ 54%]\nr2e_tests/test_config/test_settings.py .......................           [ 57%]\nr2e_tests/test_config/test_testing.py ............                       [ 58%]\nr2e_tests/test_config/test_tweens.py .................................   [ 61%]\nr2e_tests/test_config/test_util.py ..................................... [ 64%]\n.............                                                            [ 65%]\nr2e_tests/test_config/test_views.py .....................F............F. [ 68%]\n..................................FF.................................... [ 75%]\n..FF.................................................................... [ 81%]\n.....FF.........F...F....F.............................................. [ 88%]\n............F                                                            [ 89%]\nr2e_tests/test_scripts/test_common.py ...                                [ 89%]\nr2e_tests/test_scripts/test_pcreate.py ..........                        [ 90%]\nr2e_tests/test_scripts/test_pdistreport.py ..                            [ 90%]\nr2e_tests/test_scripts/test_prequest.py F.FFFFFFFFF.F.FFF.               [ 92%]\nr2e_tests/test_scripts/test_proutes.py ...........                       [ 93%]\nr2e_tests/test_scripts/test_pserve.py ............................       [ 95%]\nr2e_tests/test_scripts/test_pshell.py .................                  [ 97%]\nr2e_tests/test_scripts/test_ptweens.py .....                             [ 97%]\nr2e_tests/test_scripts/test_pviews.py ................F......            [100%]\n\n=================================== FAILURES ===================================\n_ TestViewsConfigurationMixin.test_add_static_view_here_no_utility_registered __\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_static_view_here_no_utility_registered>\n\n    def test_add_static_view_here_no_utility_registered(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        config = self._makeOne(autocommit=True)\n        config.add_static_view('static', 'files', renderer=null_renderer)\n        request_type = self._getRouteRequestIface(config, '__static/')\n        self._assertRoute(config, '__static/', 'static/*subpath')\n        wrapped = config.registry.adapters.lookup(\n            (IViewClassifier, request_type, Interface), IView, name='')\n        from pyramid.request import Request\n        request = Request.blank('/static/minimal.txt')\n        request.subpath = ('minimal.txt', )\n>       result = wrapped(None, request)\n\nr2e_tests/test_1.py:1734: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <pyramid.static.static_view object at 0x7af6f041c460>, context = None\nrequest = <Request at 0x7af6f041c940 GET http://localhost/static/minimal.txt>\n\n    def __call__(self, context, request):\n        if self.use_subpath:\n            path_tuple = request.subpath\n        else:\n            path_tuple = traversal_path_info(request.environ['PATH_INFO'])\n    \n        path = _secure_path(path_tuple)\n    \n        if path is None:\n            raise HTTPNotFound('Out of bounds: %s' % request.url)\n    \n        if self.package_name: # package resource\n    \n            resource_path ='%s/%s' % (self.docroot.rstrip('/'), path)\n            if resource_isdir(self.package_name, resource_path):\n                if not request.path_url.endswith('/'):\n                    self.add_slash_redirect(request)\n                resource_path = '%s/%s' % (resource_path.rstrip('/'),self.index)\n            if not resource_exists(self.package_name, resource_path):\n>               raise HTTPNotFound(request.url)\nE               pyramid.httpexceptions.HTTPNotFound: http://localhost/static/minimal.txt\n\npyramid/static.py:114: HTTPNotFound\n____ TestViewsConfigurationMixin.test_add_static_view_package_here_relative ____\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_static_view_package_here_relative>\n\n    def test_add_static_view_package_here_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static', 'files')\n>       self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\nE       AssertionError: Lists differ: [(<py[39 chars]af6f03720d0>, 'static', 'r2e_tests:files', {})] != [(<py[39 chars]af6f03720d0>, 'static', 'pyramid.tests.test_config:files', {})]\nE       \nE       First differing element 0:\nE       (<pyr[37 chars]7af6f03720d0>, 'static', 'r2e_tests:files', {})\nE       (<pyr[37 chars]7af6f03720d0>, 'static', 'pyramid.tests.test_config:files', {})\nE       \nE         [(<pyramid.config.Configurator object at 0x7af6f03720d0>,\nE           'static',\nE       -   'r2e_tests:files',\nE       +   'pyramid.tests.test_config:files',\nE           {})]\n\nr2e_tests/test_1.py:1755: AssertionError\n_ TestViewsConfigurationMixin.test_add_view_custom_predicate_bests_standard_predicate _\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_view_custom_predicate_bests_standard_predicate>\n\n    def test_add_view_custom_predicate_bests_standard_predicate(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=(pred1,),\n                        renderer=null_renderer)\n            config.add_view(view=view2, request_method='GET',\n                            renderer=null_renderer)\n>           self.assertEqual(len(w), 1)\nE           AssertionError: 3 != 1\n\nr2e_tests/test_1.py:1471: AssertionError\n____ TestViewsConfigurationMixin.test_add_view_with_custom_predicates_match ____\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_view_with_custom_predicates_match>\n\n    def test_add_view_with_custom_predicates_match(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return True\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates,\n                            renderer=null_renderer)\n>           self.assertEqual(len(w), 1)\nE           AssertionError: 2 != 1\n\nr2e_tests/test_1.py:1435: AssertionError\n___ TestViewsConfigurationMixin.test_add_view_with_custom_predicates_nomatch ___\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_view_with_custom_predicates_nomatch>\n\n    def test_add_view_with_custom_predicates_nomatch(self):\n        import warnings\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return False\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates)\n>           self.assertEqual(len(w), 1)\nE           AssertionError: 2 != 1\n\nr2e_tests/test_1.py:1452: AssertionError\n_______ TestViewsConfigurationMixin.test_add_view_with_template_renderer _______\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_view_with_template_renderer>\n\n    def test_add_view_with_template_renderer(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n    \n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=view, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n>       self.assertEqual(result.package, test_config)\nE       AssertionError: <module 'r2e_tests' from '/home/gcpuser/buckets/lo[93 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_1.py:1070: AssertionError\n_ TestViewsConfigurationMixin.test_add_view_with_template_renderer_no_callable _\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_view_with_template_renderer_no_callable>\n\n    def test_add_view_with_template_renderer_no_callable(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=None, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n>       self.assertEqual(result.package, test_config)\nE       AssertionError: <module 'r2e_tests' from '/home/gcpuser/buckets/lo[93 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_1.py:1111: AssertionError\n_________________ TestViewDeriver.test_as_instance_requestonly _________________\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_as_instance_requestonly>\n\n    def test_as_instance_requestonly(self):\n        response = DummyResponse()\n        class View:\n            def __call__(self, request):\n                return response\n        view = View()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n>       self.assertTrue('test_views' in result.__name__)\nE       AssertionError: False is not true\n\nr2e_tests/test_1.py:2699: AssertionError\n_____________ TestViewDeriver.test_function_returns_non_adaptable ______________\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_function_returns_non_adaptable>\n\n    def test_function_returns_non_adaptable(self):\n        def view(request):\n            return None\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n>           result(None, None)\n\nr2e_tests/test_1.py:2366: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None, request = None\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable function r2e_tests.test_1.view into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_function_returns_non_adaptable>\n\n    def test_function_returns_non_adaptable(self):\n        def view(request):\n            return None\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable function '\n                'pyramid.tests.test_config.test_views.view into a response '\n                'object. The value returned was None. You may have forgotten '\n                'to return a value from the view callable.'\n                )\nE           AssertionError: 'Coul[52 chars]tion r2e_tests.test_1.view into a response obj[94 chars]ble.' != 'Coul[52 chars]tion pyramid.tests.test_config.test_views.view[114 chars]ble.'\nE           - Could not convert return value of the view callable function r2e_tests.test_1.view into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\nE           ?                                                              ^^^ ^^^^^      ^^^^^^^^^^^^^\nE           + Could not convert return value of the view callable function pyramid.tests.test_config.test_views.view into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\nE           ?                                                              ^^^^^^^^^^^^^^^^^^ ^^^^^^      ^^^^^^^^^^^^^^^^^\n\nr2e_tests/test_1.py:2368: AssertionError\n___________ TestViewDeriver.test_function_returns_non_adaptable_dict ___________\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_function_returns_non_adaptable_dict>\n\n    def test_function_returns_non_adaptable_dict(self):\n        def view(request):\n            return {'a':1}\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n>           result(None, None)\n\nr2e_tests/test_1.py:2385: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None, request = None\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable function r2e_tests.test_1.view into a response object. The value returned was {'a': 1}. You may have forgotten to define a renderer in the view configuration.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_function_returns_non_adaptable_dict>\n\n    def test_function_returns_non_adaptable_dict(self):\n        def view(request):\n            return {'a':1}\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                \"Could not convert return value of the view callable function \"\n                \"pyramid.tests.test_config.test_views.view into a response \"\n                \"object. The value returned was {'a': 1}. You may have \"\n                \"forgotten to define a renderer in the view configuration.\"\n                )\nE           AssertionError: \"Coul[52 chars]tion r2e_tests.test_1.view into a response obj[104 chars]ion.\" != \"Coul[52 chars]tion pyramid.tests.test_config.test_views.view[124 chars]ion.\"\nE           Diff is 651 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_1.py:2387: AssertionError\n_____________ TestViewDeriver.test_instance_returns_non_adaptable ______________\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_instance_returns_non_adaptable>\n\n    def test_instance_returns_non_adaptable(self):\n        class AView(object):\n            def __call__(self, request):\n                return None\n        view = AView()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n>           result(None, None)\n\nr2e_tests/test_1.py:2406: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None, request = None\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable object <r2e_tests.test_1.TestViewDeriver.test_instance_returns_non_adaptable.<locals>.AView object at 0x7af6efdef8e0> into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_instance_returns_non_adaptable>\n\n    def test_instance_returns_non_adaptable(self):\n        class AView(object):\n            def __call__(self, request):\n                return None\n        view = AView()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n            msg = e.args[0]\n>           self.assertTrue(msg.startswith(\n                'Could not convert return value of the view callable object '\n                '<pyramid.tests.test_config.test_views.'))\nE           AssertionError: False is not true\n\nr2e_tests/test_1.py:2409: AssertionError\n____ TestViewDeriver.test_requestonly_default_method_returns_non_adaptable _____\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_requestonly_default_method_returns_non_adaptable>\n\n    def test_requestonly_default_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return None\n        deriver = self._makeOne()\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n>           result(None, request)\n\nr2e_tests/test_1.py:2452: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None\nrequest = <r2e_tests.test_1.DummyRequest object at 0x7af6f11c1a90>\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable method __call__ of class r2e_tests.test_1.AView into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_requestonly_default_method_returns_non_adaptable>\n\n    def test_requestonly_default_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return None\n        deriver = self._makeOne()\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n            result(None, request)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable '\n                'method __call__ of '\n                'class pyramid.tests.test_config.test_views.AView into a '\n                'response object. The value returned was None. You may have '\n                'forgotten to return a value from the view callable.'\n                )\nE           AssertionError: 'Coul[68 chars]lass r2e_tests.test_1.AView into a response ob[95 chars]ble.' != 'Coul[68 chars]lass pyramid.tests.test_config.test_views.AVie[115 chars]ble.'\nE           Diff is 673 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_1.py:2454: AssertionError\n___ TestViewDeriver.test_requestonly_nondefault_method_returns_non_adaptable ___\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_requestonly_nondefault_method_returns_non_adaptable>\n\n    def test_requestonly_nondefault_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def theviewmethod(self):\n                return None\n        deriver = self._makeOne(attr='theviewmethod')\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n>           result(None, request)\n\nr2e_tests/test_1.py:2476: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None\nrequest = <r2e_tests.test_1.DummyRequest object at 0x7af6efe62be0>\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable method theviewmethod of class r2e_tests.test_1.AView into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_requestonly_nondefault_method_returns_non_adaptable>\n\n    def test_requestonly_nondefault_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def theviewmethod(self):\n                return None\n        deriver = self._makeOne(attr='theviewmethod')\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n            result(None, request)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable '\n                'method theviewmethod of '\n                'class pyramid.tests.test_config.test_views.AView into a '\n                'response object. The value returned was None. You may have '\n                'forgotten to return a value from the view callable.'\n                )\nE           AssertionError: 'Coul[73 chars]lass r2e_tests.test_1.AView into a response ob[95 chars]ble.' != 'Coul[73 chars]lass pyramid.tests.test_config.test_views.AVie[115 chars]ble.'\nE           Diff is 693 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_1.py:2478: AssertionError\n___________________ Test_view_description.test_without_text ____________________\n\nself = <r2e_tests.test_1.Test_view_description testMethod=test_without_text>\n\n    def test_without_text(self):\n        def view(): pass\n        result = self._callFUT(view)\n>       self.assertEqual(result,\n                         'function pyramid.tests.test_config.test_views.view')\nE       AssertionError: 'function r2e_tests.test_1.view' != 'function pyramid.tests.test_config.test_views.view'\nE       - function r2e_tests.test_1.view\nE       + function pyramid.tests.test_config.test_views.view\n\nr2e_tests/test_1.py:3916: AssertionError\n__ AdaptersConfiguratorMixinTests.test_add_resource_url_adapter_dotted_names ___\n\nself = <r2e_tests.test_config.test_adapters.AdaptersConfiguratorMixinTests testMethod=test_add_resource_url_adapter_dotted_names>\n\n    def test_add_resource_url_adapter_dotted_names(self):\n        from pyramid.interfaces import IResourceURL\n        config = self._makeOne(autocommit=True)\n        config.add_resource_url_adapter(\n            'pyramid.tests.test_config.test_adapters.DummyResourceURL',\n            'pyramid.tests.test_config.test_adapters.DummyIface',\n            )\n        iface = DummyIface()\n>       adapter = config.registry.getMultiAdapter((iface, iface),\n                                                    IResourceURL)\n\nr2e_tests/test_config/test_adapters.py:280: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <Registry r2e_tests.test_config>\nobjects = (<r2e_tests.test_config.test_adapters.DummyIface object at 0x7af6f0cd5eb0>, <r2e_tests.test_config.test_adapters.DummyIface object at 0x7af6f0cd5eb0>)\ninterface = <InterfaceClass pyramid.interfaces.IResourceURL>, name = ''\n\n    def getMultiAdapter(self, objects, interface, name=''):\n        adapter = self.adapters.queryMultiAdapter(objects, interface, name)\n        if adapter is None:\n>           raise ComponentLookupError(objects, interface, name)\nE           zope.interface.interfaces.ComponentLookupError: ((<r2e_tests.test_config.test_adapters.DummyIface object at 0x7af6f0cd5eb0>, <r2e_tests.test_config.test_adapters.DummyIface object at 0x7af6f0cd5eb0>), <InterfaceClass pyramid.interfaces.IResourceURL>, '')\n\n.venv/lib/python3.8/site-packages/zope/interface/registry.py:379: ComponentLookupError\n_ AdaptersConfiguratorMixinTests.test_add_resource_url_adapter_introspectables _\n\nself = <r2e_tests.test_config.test_adapters.AdaptersConfiguratorMixinTests testMethod=test_add_resource_url_adapter_introspectables>\n\n    def test_add_resource_url_adapter_introspectables(self):\n        config = self._makeOne()\n        config.add_resource_url_adapter(DummyResourceURL, DummyIface)\n        actions = config.action_state.actions\n        self.assertEqual(len(actions), 1)\n        intrs  = actions[0]['introspectables']\n        self.assertEqual(len(intrs), 1)\n        intr = intrs[0]\n        self.assertEqual(intr.type_name, 'resource url adapter')\n        self.assertEqual(intr.discriminator,\n                         ('resource url adapter', DummyIface))\n        self.assertEqual(intr.category_name, 'resource url adapters')\n>       self.assertEqual(\n            intr.title,\n            \"resource url adapter for resource iface \"\n            \"<class 'pyramid.tests.test_config.test_adapters.DummyIface'>\"\n            )\nE       AssertionError: \"reso[34 chars]e <class 'r2e_tests.test_config.test_adapters.DummyIface'>\" != \"reso[34 chars]e <class 'pyramid.tests.test_config.test_adapters.DummyIface'>\"\nE       - resource url adapter for resource iface <class 'r2e_tests.test_config.test_adapters.DummyIface'>\nE       ?                                                  ^^^\nE       + resource url adapter for resource iface <class 'pyramid.tests.test_config.test_adapters.DummyIface'>\nE       ?                                                 ++ ^^^^^\n\nr2e_tests/test_config/test_adapters.py:326: AssertionError\n________ AdaptersConfiguratorMixinTests.test_add_traverser_dotted_names ________\n\nself = <r2e_tests.test_config.test_adapters.AdaptersConfiguratorMixinTests testMethod=test_add_traverser_dotted_names>\n\n    def test_add_traverser_dotted_names(self):\n        from pyramid.interfaces import ITraverser\n        config = self._makeOne(autocommit=True)\n        config.add_traverser(\n            'pyramid.tests.test_config.test_adapters.DummyTraverser',\n            'pyramid.tests.test_config.test_adapters.DummyIface')\n        iface = DummyIface()\n>       traverser = config.registry.getAdapter(iface, ITraverser)\n\nr2e_tests/test_config/test_adapters.py:237: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <Registry r2e_tests.test_config>\nobject = <r2e_tests.test_config.test_adapters.DummyIface object at 0x7af6f02ad370>\ninterface = <InterfaceClass pyramid.interfaces.ITraverser>, name = ''\n\n    def getAdapter(self, object, interface, name=''):\n        adapter = self.adapters.queryAdapter(object, interface, name)\n        if adapter is None:\n>           raise ComponentLookupError(object, interface, name)\nE           zope.interface.interfaces.ComponentLookupError: (<r2e_tests.test_config.test_adapters.DummyIface object at 0x7af6f02ad370>, <InterfaceClass pyramid.interfaces.ITraverser>, '')\n\n.venv/lib/python3.8/site-packages/zope/interface/registry.py:368: ComponentLookupError\n_________ TestOverrideProvider.test_get_resource_filename_no_overrides _________\n\nself = <r2e_tests.test_config.test_assets.TestOverrideProvider testMethod=test_get_resource_filename_no_overrides>\n\n    def test_get_resource_filename_no_overrides(self):\n        import os\n        resource_name = 'test_assets.py'\n        import pyramid.tests.test_config\n        provider = self._makeOne(pyramid.tests.test_config)\n        here = os.path.dirname(os.path.abspath(__file__))\n        expected = os.path.join(here, resource_name)\n        result = provider.get_resource_filename(None, resource_name)\n>       self.assertEqual(result, expected)\nE       AssertionError: '/hom[73 chars]14ddd61de089fe1f073d1/pyramid/tests/test_config/test_assets.py' != '/hom[73 chars]14ddd61de089fe1f073d1/r2e_tests/test_config/test_assets.py'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/test_config/test_assets.py\nE       ?                                                                                                    -- ^^^^^\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/test_config/test_assets.py\nE       ?                                                                                                     ^^^\n\nr2e_tests/test_config/test_assets.py:158: AssertionError\n____ TestOverrideProvider.test_get_resource_filename_override_returns_None _____\n\nself = <r2e_tests.test_config.test_assets.TestOverrideProvider testMethod=test_get_resource_filename_override_returns_None>\n\n    def test_get_resource_filename_override_returns_None(self):\n        overrides = DummyOverrides(None)\n        self._registerOverrides(overrides)\n        import os\n        resource_name = 'test_assets.py'\n        import pyramid.tests.test_config\n        provider = self._makeOne(pyramid.tests.test_config)\n        here = os.path.dirname(os.path.abspath(__file__))\n        expected = os.path.join(here, resource_name)\n        result = provider.get_resource_filename(None, resource_name)\n>       self.assertEqual(result, expected)\nE       AssertionError: '/hom[73 chars]14ddd61de089fe1f073d1/pyramid/tests/test_config/test_assets.py' != '/hom[73 chars]14ddd61de089fe1f073d1/r2e_tests/test_config/test_assets.py'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/test_config/test_assets.py\nE       ?                                                                                                    -- ^^^^^\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/test_config/test_assets.py\nE       ?                                                                                                     ^^^\n\nr2e_tests/test_config/test_assets.py:212: AssertionError\n____________________ TestPackageOverrides.test_get_filename ____________________\n\nself = <r2e_tests.test_config.test_assets.TestPackageOverrides testMethod=test_get_filename>\n\n    def test_get_filename(self):\n        import os\n        overrides = [ DummyOverride(None), DummyOverride(\n            ('pyramid.tests.test_config', 'test_assets.py'))]\n        package = DummyPackage('package')\n        po = self._makeOne(package)\n        po.overrides= overrides\n        here = os.path.dirname(os.path.abspath(__file__))\n        expected = os.path.join(here, 'test_assets.py')\n>       self.assertEqual(po.get_filename('whatever'), expected)\nE       AssertionError: '/hom[73 chars]14ddd61de089fe1f073d1/pyramid/tests/test_config/test_assets.py' != '/hom[73 chars]14ddd61de089fe1f073d1/r2e_tests/test_config/test_assets.py'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/test_config/test_assets.py\nE       ?                                                                                                    -- ^^^^^\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/test_config/test_assets.py\nE       ?                                                                                                     ^^^\n\nr2e_tests/test_config/test_assets.py:425: AssertionError\n_________ TestI18NConfiguratorMixin.test_add_translation_dirs_abspath __________\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_abspath>\n\n    def test_add_translation_dirs_abspath(self):\n        from pyramid.interfaces import ITranslationDirectories\n        config = self._makeOne(autocommit=True)\n>       config.add_translation_dirs(locale)\n\nr2e_tests/test_config/test_i18n.py:86: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \npyramid/util.py:507: in wrapper\n    result = wrapped(self, *arg, **kw)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <pyramid.config.Configurator object at 0x7af6f0976460>\nspecs = ('/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale',)\nintrospectables = []\nspec = '/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale'\npackage_name = None\n\n    @action_method\n    def add_translation_dirs(self, *specs):\n        \"\"\" Add one or more :term:`translation directory` paths to the\n        current configuration state.  The ``specs`` argument is a\n        sequence that may contain absolute directory paths\n        (e.g. ``/usr/share/locale``) or :term:`asset specification`\n        names naming a directory path (e.g. ``some.package:locale``)\n        or a combination of the two.\n    \n        Example:\n    \n        .. code-block:: python\n    \n           config.add_translation_dirs('/usr/share/locale',\n                                       'some.package:locale')\n    \n        Later calls to ``add_translation_dir`` insert directories into the\n        beginning of the list of translation directories created by earlier\n        calls.  This means that the same translation found in a directory\n        added later in the configuration process will be found before one\n        added earlier in the configuration process.  However, if multiple\n        specs are provided in a single call to ``add_translation_dirs``, the\n        directories will be inserted into the beginning of the directory list\n        in the order they're provided in the ``*specs`` list argument (items\n        earlier in the list trump ones later in the list).\n        \"\"\"\n        directories = []\n        introspectables = []\n    \n        for spec in specs[::-1]: # reversed\n            package_name, filename = self._split_spec(spec)\n            if package_name is None: # absolute filename\n                directory = filename\n            else:\n                __import__(package_name)\n                package = sys.modules[package_name]\n                directory = os.path.join(package_path(package), filename)\n    \n            if not os.path.isdir(os.path.realpath(directory)):\n>               raise ConfigurationError('\"%s\" is not a directory' %\n                                         directory)\nE               pyramid.exceptions.ConfigurationError: \"/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale\" is not a directory\n\npyramid/config/i18n.py:86: ConfigurationError\n________ TestI18NConfiguratorMixin.test_add_translation_dirs_asset_spec ________\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_asset_spec>\n\n    def test_add_translation_dirs_asset_spec(self):\n        from pyramid.interfaces import ITranslationDirectories\n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale')\n>       self.assertEqual(config.registry.getUtility(ITranslationDirectories),\n                         [locale])\nE       AssertionError: Lists differ: ['/ho[70 chars]cd9414ddd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale'] != ['/ho[70 chars]cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale']\nE       \nE       First differing element 0:\nE       '/hom[68 chars]5cd9414ddd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale'\nE       '/hom[68 chars]5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale'\nE       \nE       - ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale']\nE       ?                                                                                                      -- ^^^^^\nE       \nE       + ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale']\nE       ?                                                                                                       ^^^\n\nr2e_tests/test_config/test_i18n.py:54: AssertionError\n_ TestI18NConfiguratorMixin.test_add_translation_dirs_asset_spec_existing_translation_dirs _\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_asset_spec_existing_translation_dirs>\n\n    def test_add_translation_dirs_asset_spec_existing_translation_dirs(self):\n        from pyramid.interfaces import ITranslationDirectories\n        config = self._makeOne(autocommit=True)\n        directories = ['abc']\n        config.registry.registerUtility(directories, ITranslationDirectories)\n        config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale')\n        result = config.registry.getUtility(ITranslationDirectories)\n>       self.assertEqual(result, [locale, 'abc'])\nE       AssertionError: Lists differ: ['/ho[77 chars]dd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale', 'abc'] != ['/ho[77 chars]dd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale', 'abc']\nE       \nE       First differing element 0:\nE       '/hom[68 chars]5cd9414ddd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale'\nE       '/hom[68 chars]5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale'\nE       \nE       - ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale',\nE       ?                                                                                                      -- ^^^^^\nE       \nE       + ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale',\nE       ?                                                                                                       ^^^\nE       \nE          'abc']\n\nr2e_tests/test_config/test_i18n.py:64: AssertionError\n______ TestI18NConfiguratorMixin.test_add_translation_dirs_multiple_specs ______\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_multiple_specs>\n\n    def test_add_translation_dirs_multiple_specs(self):\n        from pyramid.interfaces import ITranslationDirectories\n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale',\n                                    'pyramid.tests.pkgs.localeapp:locale2')\n>       self.assertEqual(config.registry.getUtility(ITranslationDirectories),\n                         [locale, locale2])\nE       AssertionError: Lists differ: ['/ho[91 chars]73d1/pyramid/tests/pkgs/localeapp/locale', '/h[130 chars]le2'] != ['/ho[91 chars]73d1/r2e_tests/pkgs/localeapp/locale', '/home/[122 chars]le2']\nE       \nE       First differing element 0:\nE       '/hom[68 chars]5cd9414ddd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale'\nE       '/hom[68 chars]5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale'\nE       \nE       Diff is 1002 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_i18n.py:71: AssertionError\n_ TestI18NConfiguratorMixin.test_add_translation_dirs_multiple_specs_multiple_calls _\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_multiple_specs_multiple_calls>\n\n    def test_add_translation_dirs_multiple_specs_multiple_calls(self):\n        from pyramid.interfaces import ITranslationDirectories\n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale',\n                                    'pyramid.tests.pkgs.localeapp:locale2')\n        config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale3')\n>       self.assertEqual(config.registry.getUtility(ITranslationDirectories),\n                         [locale3, locale, locale2])\nE       AssertionError: Lists differ: ['/ho[91 chars]73d1/pyramid/tests/pkgs/localeapp/locale3', '/[269 chars]le2'] != ['/ho[91 chars]73d1/r2e_tests/pkgs/localeapp/locale3', '/home[257 chars]le2']\nE       \nE       First differing element 0:\nE       '/hom[69 chars]cd9414ddd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale3'\nE       '/hom[69 chars]cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale3'\nE       \nE       Diff is 1504 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_i18n.py:80: AssertionError\n___________________ ConfiguratorTests.test_ctor_no_registry ____________________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_ctor_no_registry>\n\n    def test_ctor_no_registry(self):\n        import sys\n        from pyramid.interfaces import ISettings\n        from pyramid.config import Configurator\n        from pyramid.interfaces import IRendererFactory\n        config = Configurator()\n        this_pkg = sys.modules['pyramid.tests.test_config']\n        self.assertTrue(config.registry.getUtility(ISettings))\n>       self.assertEqual(config.package, this_pkg)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_config/test_init.py:67: AssertionError\n_________ ConfiguratorTests.test_ctor_noreg_debug_logger_None_default __________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_ctor_noreg_debug_logger_None_default>\n\n    def test_ctor_noreg_debug_logger_None_default(self):\n        from pyramid.interfaces import IDebugLogger\n        config = self._makeOne()\n        logger = config.registry.getUtility(IDebugLogger)\n>       self.assertEqual(logger.name, 'pyramid.tests.test_config')\nE       AssertionError: 'r2e_tests.test_config' != 'pyramid.tests.test_config'\nE       - r2e_tests.test_config\nE       ?  ^^^\nE       + pyramid.tests.test_config\nE       ? ++ ^^^^^\n\nr2e_tests/test_config/test_init.py:123: AssertionError\n_______________ ConfiguratorTests.test_scan_integration_conflict _______________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_scan_integration_conflict>\n\n    def test_scan_integration_conflict(self):\n        from pyramid.tests.test_config.pkgs import selfscan\n        from pyramid.config import Configurator\n        c = Configurator()\n        c.scan(selfscan)\n        c.scan(selfscan)\n        try:\n>           c.commit()\n\nr2e_tests/test_config/test_init.py:999: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \npyramid/config/__init__.py:606: in commit\n    self.action_state.execute_actions(introspector=self.introspector)\npyramid/config/__init__.py:1044: in execute_actions\n    for action in resolveConflicts(self.actions):\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nactions = []\n\n    def resolveConflicts(actions):\n        \"\"\"Resolve conflicting actions\n    \n        Given an actions list, identify and try to resolve conflicting actions.\n        Actions conflict if they have the same non-None discriminator.\n        Conflicting actions can be resolved if the include path of one of\n        the actions is a prefix of the includepaths of the other\n        conflicting actions and is unequal to the include paths in the\n        other conflicting actions.\n        \"\"\"\n    \n        def orderandpos(v):\n            n, v = v\n            if not isinstance(v, dict):\n                # old-style tuple action\n                v = expand_action(*v)\n            return (v['order'] or 0, n)\n    \n        sactions = sorted(enumerate(actions), key=orderandpos)\n    \n        def orderonly(v):\n            n, v = v\n            if not isinstance(v, dict):\n                # old-style tuple action\n                v = expand_action(*v)\n            return v['order'] or 0\n    \n        for order, actiongroup in itertools.groupby(sactions, orderonly):\n            # \"order\" is an integer grouping. Actions in a lower order will be\n            # executed before actions in a higher order.  All of the actions in\n            # one grouping will be executed (its callable, if any will be called)\n            # before any of the actions in the next.\n    \n            unique = {}\n            output = []\n    \n            for i, action in actiongroup:\n                # Within an order, actions are executed sequentially based on\n                # original action ordering (\"i\").\n    \n                if not isinstance(action, dict):\n                    # old-style tuple action\n                    action = expand_action(*action)\n    \n                # \"ainfo\" is a tuple of (order, i, action) where \"order\" is a\n                # user-supplied grouping, \"i\" is an integer expressing the relative\n                # position of this action in the action list being resolved, and\n                # \"action\" is an action dictionary.  The purpose of an ainfo is to\n                # associate an \"order\" and an \"i\" with a particular action; \"order\"\n                # and \"i\" exist for sorting purposes after conflict resolution.\n                ainfo = (order, i, action)\n    \n                discriminator = undefer(action['discriminator'])\n                action['discriminator'] = discriminator\n    \n                if discriminator is None:\n                    # The discriminator is None, so this action can never conflict.\n                    # We can add it directly to the result.\n                    output.append(ainfo)\n                    continue\n    \n                L = unique.setdefault(discriminator, [])\n                L.append(ainfo)\n    \n            # Check for conflicts\n            conflicts = {}\n    \n            for discriminator, ainfos in unique.items():\n                # We use (includepath, order, i) as a sort key because we need to\n                # sort the actions by the paths so that the shortest path with a\n                # given prefix comes first.  The \"first\" action is the one with the\n                # shortest include path.  We break sorting ties using \"order\", then\n                # \"i\".\n                def bypath(ainfo):\n                    path, order, i = ainfo[2]['includepath'], ainfo[0], ainfo[1]\n                    return path, order, i\n    \n                ainfos.sort(key=bypath)\n                ainfo, rest = ainfos[0], ainfos[1:]\n                output.append(ainfo)\n                _, _, action = ainfo\n                basepath, baseinfo, discriminator = (\n                    action['includepath'],\n                    action['info'],\n                    action['discriminator'],\n                    )\n    \n                for _, _, action in rest:\n                    includepath = action['includepath']\n                    # Test whether path is a prefix of opath\n                    if (includepath[:len(basepath)] != basepath # not a prefix\n                        or includepath == basepath):\n                        L = conflicts.setdefault(discriminator, [baseinfo])\n                        L.append(action['info'])\n    \n            if conflicts:\n>               raise ConfigurationConflictError(conflicts)\nE               pyramid.exceptions.ConfigurationConflictError: Conflicting configuration actions\nE                 For: ('view', None, '', None, 'd41d8cd98f00b204e9800998ecf8427e')\nE                   Line 4 of file /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/test_config/pkgs/selfscan/__init__.py:\nE                       def abc(request):\nE                   Line 4 of file /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/test_config/pkgs/selfscan/__init__.py:\nE                       def abc(request):\nE                 For: ('view', None, 'two', None, 'd41d8cd98f00b204e9800998ecf8427e')\nE                   Line 4 of file /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/test_config/pkgs/selfscan/another.py:\nE                       def two(request):\nE                   Line 4 of file /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/test_config/pkgs/selfscan/another.py:\nE                       def two(request):\n\npyramid/config/__init__.py:1172: ConfigurationConflictError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_scan_integration_conflict>\n\n    def test_scan_integration_conflict(self):\n        from pyramid.tests.test_config.pkgs import selfscan\n        from pyramid.config import Configurator\n        c = Configurator()\n        c.scan(selfscan)\n        c.scan(selfscan)\n        try:\n            c.commit()\n        except ConfigurationConflictError as why:\n            def scanconflicts(e):\n                conflicts = e._conflicts.values()\n                for conflict in conflicts:\n                    for confinst in conflict:\n                        yield confinst.src\n            which = list(scanconflicts(why))\n            self.assertEqual(len(which), 4)\n>           self.assertTrue(\"@view_config(renderer='string')\" in which)\nE           AssertionError: False is not true\n\nr2e_tests/test_config/test_init.py:1008: AssertionError\n_______ ConfiguratorTests.test_setup_registry_debug_logger_None_default ________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_setup_registry_debug_logger_None_default>\n\n    def test_setup_registry_debug_logger_None_default(self):\n        from pyramid.registry import Registry\n        from pyramid.interfaces import IDebugLogger\n        reg = Registry()\n        config = self._makeOne(reg)\n        config.setup_registry()\n        logger = reg.getUtility(IDebugLogger)\n>       self.assertEqual(logger.name, 'pyramid.tests.test_config')\nE       AssertionError: 'r2e_tests.test_config' != 'pyramid.tests.test_config'\nE       - r2e_tests.test_config\nE       ?  ^^^\nE       + pyramid.tests.test_config\nE       ? ++ ^^^^^\n\nr2e_tests/test_config/test_init.py:428: AssertionError\n____ TestConfigurator_add_directive.test_add_directive_with_custom_callable ____\n\nself = <r2e_tests.test_config.test_init.TestConfigurator_add_directive testMethod=test_add_directive_with_custom_callable>\n\n    def test_add_directive_with_custom_callable(self):\n        from pyramid.tests import test_config\n        config = self.config\n        config.add_directive(\n                'dummy_callable', 'pyramid.tests.test_config.dummy_callable')\n        self.assertTrue(hasattr(config, 'dummy_callable'))\n        config.dummy_callable('discrim')\n        after = config.action_state\n        action = after.actions[-1]\n        self.assertEqual(action['discriminator'], 'discrim')\n        self.assertEqual(action['callable'], None)\n>       self.assertEqual(action['args'], test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_config/test_init.py:1207: AssertionError\n________ TestConfigurator_add_directive.test_add_directive_with_partial ________\n\nself = <r2e_tests.test_config.test_init.TestConfigurator_add_directive testMethod=test_add_directive_with_partial>\n\n    def test_add_directive_with_partial(self):\n        from pyramid.tests import test_config\n        config = self.config\n        config.add_directive(\n                'dummy_partial', 'pyramid.tests.test_config.dummy_partial')\n        self.assertTrue(hasattr(config, 'dummy_partial'))\n        config.dummy_partial()\n        after = config.action_state\n        action = after.actions[-1]\n        self.assertEqual(action['discriminator'], 'partial')\n        self.assertEqual(action['callable'], None)\n>       self.assertEqual(action['args'], test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_config/test_init.py:1194: AssertionError\n_________ TestConfigurator_add_directive.test_extend_with_dotted_name __________\n\nself = <r2e_tests.test_config.test_init.TestConfigurator_add_directive testMethod=test_extend_with_dotted_name>\n\n    def test_extend_with_dotted_name(self):\n        from pyramid.tests import test_config\n        config = self.config\n        config.add_directive(\n            'dummy_extend', 'pyramid.tests.test_config.dummy_extend')\n        self.assertTrue(hasattr(config, 'dummy_extend'))\n        config.dummy_extend('discrim')\n        after = config.action_state\n        action = after.actions[-1]\n        self.assertEqual(action['discriminator'], 'discrim')\n        self.assertEqual(action['callable'], None)\n>       self.assertEqual(action['args'], test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_config/test_init.py:1181: AssertionError\n_______ TestConfigurator_add_directive.test_extend_with_python_callable ________\n\nself = <r2e_tests.test_config.test_init.TestConfigurator_add_directive testMethod=test_extend_with_python_callable>\n\n    def test_extend_with_python_callable(self):\n        from pyramid.tests import test_config\n        config = self.config\n        config.add_directive(\n            'dummy_extend', dummy_extend)\n        self.assertTrue(hasattr(config, 'dummy_extend'))\n        config.dummy_extend('discrim')\n        after = config.action_state\n        action = after.actions[-1]\n        self.assertEqual(action['discriminator'], 'discrim')\n        self.assertEqual(action['callable'], None)\n>       self.assertEqual(action['args'], test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_config/test_init.py:1220: AssertionError\n_________ TestConfigurator__add_predicate.test_factory_as_dotted_name __________\n\nself = <r2e_tests.test_config.test_init.TestConfigurator__add_predicate testMethod=test_factory_as_dotted_name>\n\n    def test_factory_as_dotted_name(self):\n        config = self._makeOne()\n    \n        def _fakeAction(discriminator, callable=None, args=(),\n                        kw=None, order=0, introspectables=(), **extra):\n            self.assertEqual(len(introspectables), 1)\n            self.assertEqual(introspectables[0]['name'], 'testing')\n            self.assertEqual(introspectables[0]['factory'], DummyPredicate)\n    \n        config.action = _fakeAction\n>       config._add_predicate(\n            'route',\n            'testing',\n            'pyramid.tests.test_config.test_init.DummyPredicate'\n            )\n\nr2e_tests/test_config/test_init.py:1284: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \npyramid/config/__init__.py:495: in _add_predicate\n    self.action(discriminator, register, introspectables=(intr,),\nr2e_tests/test_config/test_init.py:1281: in _fakeAction\n    self.assertEqual(introspectables[0]['factory'], DummyPredicate)\nE   AssertionError: <class 'pyramid.tests.test_config.test_init.DummyPredicate'> != <class 'r2e_tests.test_config.test_init.DummyPredicate'>\n____ TestViewsConfigurationMixin.test_add_static_view_package_here_relative ____\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_static_view_package_here_relative>\n\n    def test_add_static_view_package_here_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static', 'files')\n>       self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\nE       AssertionError: Lists differ: [(<py[39 chars]af6effbbe50>, 'static', 'r2e_tests.test_config:files', {})] != [(<py[39 chars]af6effbbe50>, 'static', 'pyramid.tests.test_config:files', {})]\nE       \nE       First differing element 0:\nE       (<pyr[37 chars]7af6effbbe50>, 'static', 'r2e_tests.test_config:files', {})\nE       (<pyr[37 chars]7af6effbbe50>, 'static', 'pyramid.tests.test_config:files', {})\nE       \nE         [(<pyramid.config.Configurator object at 0x7af6effbbe50>,\nE           'static',\nE       -   'r2e_tests.test_config:files',\nE       ?     ^^^\nE       \nE       +   'pyramid.tests.test_config:files',\nE       ?    ++ ^^^^^\nE       \nE           {})]\n\nr2e_tests/test_config/test_views.py:1755: AssertionError\n_ TestViewsConfigurationMixin.test_add_view_custom_predicate_bests_standard_predicate _\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_custom_predicate_bests_standard_predicate>\n\n    def test_add_view_custom_predicate_bests_standard_predicate(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=(pred1,),\n                        renderer=null_renderer)\n            config.add_view(view=view2, request_method='GET',\n                            renderer=null_renderer)\n>           self.assertEqual(len(w), 1)\nE           AssertionError: 3 != 1\n\nr2e_tests/test_config/test_views.py:1471: AssertionError\n____ TestViewsConfigurationMixin.test_add_view_with_custom_predicates_match ____\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_custom_predicates_match>\n\n    def test_add_view_with_custom_predicates_match(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return True\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates,\n                            renderer=null_renderer)\n>           self.assertEqual(len(w), 1)\nE           AssertionError: 2 != 1\n\nr2e_tests/test_config/test_views.py:1435: AssertionError\n___ TestViewsConfigurationMixin.test_add_view_with_custom_predicates_nomatch ___\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_custom_predicates_nomatch>\n\n    def test_add_view_with_custom_predicates_nomatch(self):\n        import warnings\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return False\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates)\n>           self.assertEqual(len(w), 1)\nE           AssertionError: 2 != 1\n\nr2e_tests/test_config/test_views.py:1452: AssertionError\n_______ TestViewsConfigurationMixin.test_add_view_with_template_renderer _______\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_template_renderer>\n\n    def test_add_view_with_template_renderer(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n    \n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=view, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n>       self.assertEqual(result.package, test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_config/test_views.py:1070: AssertionError\n_ TestViewsConfigurationMixin.test_add_view_with_template_renderer_no_callable _\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_template_renderer_no_callable>\n\n    def test_add_view_with_template_renderer_no_callable(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=None, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n>       self.assertEqual(result.package, test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_config/test_views.py:1111: AssertionError\n_____________ TestViewDeriver.test_function_returns_non_adaptable ______________\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_function_returns_non_adaptable>\n\n    def test_function_returns_non_adaptable(self):\n        def view(request):\n            return None\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n>           result(None, None)\n\nr2e_tests/test_config/test_views.py:2366: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None, request = None\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable function r2e_tests.test_config.test_views.view into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_function_returns_non_adaptable>\n\n    def test_function_returns_non_adaptable(self):\n        def view(request):\n            return None\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable function '\n                'pyramid.tests.test_config.test_views.view into a response '\n                'object. The value returned was None. You may have forgotten '\n                'to return a value from the view callable.'\n                )\nE           AssertionError: 'Coul[52 chars]tion r2e_tests.test_config.test_views.view int[110 chars]ble.' != 'Coul[52 chars]tion pyramid.tests.test_config.test_views.view[114 chars]ble.'\nE           Diff is 663 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_views.py:2368: AssertionError\n___________ TestViewDeriver.test_function_returns_non_adaptable_dict ___________\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_function_returns_non_adaptable_dict>\n\n    def test_function_returns_non_adaptable_dict(self):\n        def view(request):\n            return {'a':1}\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n>           result(None, None)\n\nr2e_tests/test_config/test_views.py:2385: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None, request = None\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable function r2e_tests.test_config.test_views.view into a response object. The value returned was {'a': 1}. You may have forgotten to define a renderer in the view configuration.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_function_returns_non_adaptable_dict>\n\n    def test_function_returns_non_adaptable_dict(self):\n        def view(request):\n            return {'a':1}\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                \"Could not convert return value of the view callable function \"\n                \"pyramid.tests.test_config.test_views.view into a response \"\n                \"object. The value returned was {'a': 1}. You may have \"\n                \"forgotten to define a renderer in the view configuration.\"\n                )\nE           AssertionError: \"Coul[52 chars]tion r2e_tests.test_config.test_views.view int[120 chars]ion.\" != \"Coul[52 chars]tion pyramid.tests.test_config.test_views.view[124 chars]ion.\"\nE           Diff is 683 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_views.py:2387: AssertionError\n_____________ TestViewDeriver.test_instance_returns_non_adaptable ______________\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_instance_returns_non_adaptable>\n\n    def test_instance_returns_non_adaptable(self):\n        class AView(object):\n            def __call__(self, request):\n                return None\n        view = AView()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n>           result(None, None)\n\nr2e_tests/test_config/test_views.py:2406: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None, request = None\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable object <r2e_tests.test_config.test_views.TestViewDeriver.test_instance_returns_non_adaptable.<locals>.AView object at 0x7af6f030fe80> into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_instance_returns_non_adaptable>\n\n    def test_instance_returns_non_adaptable(self):\n        class AView(object):\n            def __call__(self, request):\n                return None\n        view = AView()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n            msg = e.args[0]\n>           self.assertTrue(msg.startswith(\n                'Could not convert return value of the view callable object '\n                '<pyramid.tests.test_config.test_views.'))\nE           AssertionError: False is not true\n\nr2e_tests/test_config/test_views.py:2409: AssertionError\n____ TestViewDeriver.test_requestonly_default_method_returns_non_adaptable _____\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_requestonly_default_method_returns_non_adaptable>\n\n    def test_requestonly_default_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return None\n        deriver = self._makeOne()\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n>           result(None, request)\n\nr2e_tests/test_config/test_views.py:2452: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x7af6f0032b80>\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable method __call__ of class r2e_tests.test_config.test_views.AView into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_requestonly_default_method_returns_non_adaptable>\n\n    def test_requestonly_default_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return None\n        deriver = self._makeOne()\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n            result(None, request)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable '\n                'method __call__ of '\n                'class pyramid.tests.test_config.test_views.AView into a '\n                'response object. The value returned was None. You may have '\n                'forgotten to return a value from the view callable.'\n                )\nE           AssertionError: 'Coul[68 chars]lass r2e_tests.test_config.test_views.AView in[111 chars]ble.' != 'Coul[68 chars]lass pyramid.tests.test_config.test_views.AVie[115 chars]ble.'\nE           Diff is 649 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_views.py:2454: AssertionError\n___ TestViewDeriver.test_requestonly_nondefault_method_returns_non_adaptable ___\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_requestonly_nondefault_method_returns_non_adaptable>\n\n    def test_requestonly_nondefault_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def theviewmethod(self):\n                return None\n        deriver = self._makeOne(attr='theviewmethod')\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n>           result(None, request)\n\nr2e_tests/test_config/test_views.py:2476: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x7af6f037ee20>\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable method theviewmethod of class r2e_tests.test_config.test_views.AView into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_requestonly_nondefault_method_returns_non_adaptable>\n\n    def test_requestonly_nondefault_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def theviewmethod(self):\n                return None\n        deriver = self._makeOne(attr='theviewmethod')\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n            result(None, request)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable '\n                'method theviewmethod of '\n                'class pyramid.tests.test_config.test_views.AView into a '\n                'response object. The value returned was None. You may have '\n                'forgotten to return a value from the view callable.'\n                )\nE           AssertionError: 'Coul[73 chars]lass r2e_tests.test_config.test_views.AView in[111 chars]ble.' != 'Coul[73 chars]lass pyramid.tests.test_config.test_views.AVie[115 chars]ble.'\nE           Diff is 669 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_views.py:2478: AssertionError\n___________________ Test_view_description.test_without_text ____________________\n\nself = <r2e_tests.test_config.test_views.Test_view_description testMethod=test_without_text>\n\n    def test_without_text(self):\n        def view(): pass\n        result = self._callFUT(view)\n>       self.assertEqual(result,\n                         'function pyramid.tests.test_config.test_views.view')\nE       AssertionError: 'function r2e_tests.test_config.test_views.view' != 'function pyramid.tests.test_config.test_views.view'\nE       - function r2e_tests.test_config.test_views.view\nE       ?           ^^^\nE       + function pyramid.tests.test_config.test_views.view\nE       ?          ++ ^^^^^\n\nr2e_tests/test_config/test_views.py:3916: AssertionError\n_______________ TestPRequestCommand.test_command_display_headers _______________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_display_headers>\n\n    def test_command_display_headers(self):\n        command = self._makeOne(\n            ['', '--display-headers', 'development.ini', '/'])\n        command.run()\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(\n            self._out,\n            ['200 OK', 'Content-Type: text/html; charset=UTF-8', 'abc'])\nE       AssertionError: Lists differ: ['200 OK', b'abc'] != ['200 OK', 'Content-Type: text/html; charset=UTF-8', 'abc']\nE       \nE       First differing element 1:\nE       b'abc'\nE       'Content-Type: text/html; charset=UTF-8'\nE       \nE       Second list contains 1 additional elements.\nE       First extra element 2:\nE       'abc'\nE       \nE       - ['200 OK', b'abc']\nE       + ['200 OK', 'Content-Type: text/html; charset=UTF-8', 'abc']\n\nr2e_tests/test_scripts/test_prequest.py:202: AssertionError\n_________ TestPRequestCommand.test_command_has_content_type_header_var _________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_has_content_type_header_var>\n\n    def test_command_has_content_type_header_var(self):\n        command = self._makeOne(\n            ['', '--header=content-type:app/foo','development.ini', '/'])\n        command.run()\n        self.assertEqual(self._environ['CONTENT_TYPE'], 'app/foo')\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:92: AssertionError\n_____________ TestPRequestCommand.test_command_has_good_header_var _____________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_has_good_header_var>\n\n    def test_command_has_good_header_var(self):\n        command = self._makeOne(\n            ['', '--header=name:value','development.ini', '/'])\n        command.run()\n        self.assertEqual(self._environ['HTTP_NAME'], 'value')\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:69: AssertionError\n__________ TestPRequestCommand.test_command_has_multiple_header_vars ___________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_has_multiple_header_vars>\n\n    def test_command_has_multiple_header_vars(self):\n        command = self._makeOne(\n            ['',\n             '--header=name:value',\n             '--header=name2:value2',\n             'development.ini',\n             '/'])\n        command.run()\n        self.assertEqual(self._environ['HTTP_NAME'], 'value')\n        self.assertEqual(self._environ['HTTP_NAME2'], 'value2')\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:107: AssertionError\n_________________ TestPRequestCommand.test_command_method_get __________________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_method_get>\n\n    def test_command_method_get(self):\n        command = self._makeOne(['', '--method=GET', 'development.ini', '/'])\n        command.run()\n        self.assertEqual(self._environ['REQUEST_METHOD'], 'GET')\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:116: AssertionError\n_______________ TestPRequestCommand.test_command_method_options ________________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_method_options>\n\n    def test_command_method_options(self):\n        from pyramid.compat import NativeIO\n        command = self._makeOne(['', '--method=OPTIONS', 'development.ini',\n                                '/'])\n        stdin = NativeIO()\n        command.stdin = stdin\n        command.run()\n        self.assertEqual(self._environ['REQUEST_METHOD'], 'OPTIONS')\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:184: AssertionError\n________________ TestPRequestCommand.test_command_method_patch _________________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_method_patch>\n\n    def test_command_method_patch(self):\n        from pyramid.compat import NativeIO\n        command = self._makeOne(['', '--method=PATCH', 'development.ini', '/'])\n        stdin = NativeIO()\n        command.stdin = stdin\n        command.run()\n        self.assertEqual(self._environ['REQUEST_METHOD'], 'PATCH')\n        self.assertEqual(self._environ['CONTENT_LENGTH'], '-1')\n        self.assertEqual(self._environ['wsgi.input'], stdin)\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:158: AssertionError\n_________________ TestPRequestCommand.test_command_method_post _________________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_method_post>\n\n    def test_command_method_post(self):\n        from pyramid.compat import NativeIO\n        command = self._makeOne(['', '--method=POST', 'development.ini', '/'])\n        stdin = NativeIO()\n        command.stdin = stdin\n        command.run()\n        self.assertEqual(self._environ['REQUEST_METHOD'], 'POST')\n        self.assertEqual(self._environ['CONTENT_LENGTH'], '-1')\n        self.assertEqual(self._environ['wsgi.input'], stdin)\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:130: AssertionError\n_______________ TestPRequestCommand.test_command_method_propfind _______________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_method_propfind>\n\n    def test_command_method_propfind(self):\n        from pyramid.compat import NativeIO\n        command = self._makeOne(['', '--method=PROPFIND', 'development.ini',\n                                '/'])\n        stdin = NativeIO()\n        command.stdin = stdin\n        command.run()\n        self.assertEqual(self._environ['REQUEST_METHOD'], 'PROPFIND')\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:171: AssertionError\n_________________ TestPRequestCommand.test_command_method_put __________________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_method_put>\n\n    def test_command_method_put(self):\n        from pyramid.compat import NativeIO\n        command = self._makeOne(['', '--method=PUT', 'development.ini', '/'])\n        stdin = NativeIO()\n        command.stdin = stdin\n        command.run()\n        self.assertEqual(self._environ['REQUEST_METHOD'], 'PUT')\n        self.assertEqual(self._environ['CONTENT_LENGTH'], '-1')\n        self.assertEqual(self._environ['wsgi.input'], stdin)\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:144: AssertionError\n________ TestPRequestCommand.test_command_path_doesnt_start_with_slash _________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_path_doesnt_start_with_slash>\n\n    def test_command_path_doesnt_start_with_slash(self):\n        command = self._makeOne(['', 'development.ini', 'abc'])\n        command.run()\n        self.assertEqual(self._path_info, '/abc')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:50: AssertionError\n__________________ TestPRequestCommand.test_command_two_args ___________________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_two_args>\n\n    def test_command_two_args(self):\n        command = self._makeOne(['', 'development.ini', '/'])\n        command.run()\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:42: AssertionError\n________________ TestPRequestCommand.test_command_w_basic_auth _________________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_w_basic_auth>\n\n    def test_command_w_basic_auth(self):\n        command = self._makeOne(\n            ['', '--login=user:password',\n                 '--header=name:value','development.ini', '/'])\n        command.run()\n        self.assertEqual(self._environ['HTTP_NAME'], 'value')\n        self.assertEqual(self._environ['HTTP_AUTHORIZATION'],\n                        'Basic dXNlcjpwYXNzd29yZA==')\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:82: AssertionError\n______________ TestPRequestCommand.test_command_with_query_string ______________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_with_query_string>\n\n    def test_command_with_query_string(self):\n        command = self._makeOne(['', 'development.ini', '/abc?a=1&b=2&c'])\n        command.run()\n        self.assertEqual(self._environ['QUERY_STRING'], 'a=1&b=2&c')\n        self.assertEqual(self._path_info, '/abc')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:193: AssertionError\n_____ TestPViewsCommand.test_views_command_single_view_function_traversal ______\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_single_view_function_traversal>\n\n    def test_views_command_single_view_function_traversal(self):\n        from pyramid.registry import Registry\n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n        def view(): pass\n        view.__request_attrs__ = {'context': 'context', 'view_name': 'a'}\n        command._find_view = lambda arg1: view\n        command.args = ('/foo/bar/myapp.ini#myapp', '/a')\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(L[1], 'URL = /a')\n        self.assertEqual(L[3], '    context: context')\n        self.assertEqual(L[4], '    view name: a')\n>       self.assertEqual(L[8],\n                         '    pyramid.tests.test_scripts.test_pviews.view')\nE       AssertionError: '    r2e_tests.test_scripts.test_pviews.view' != '    pyramid.tests.test_scripts.test_pviews.view'\nE       -     r2e_tests.test_scripts.test_pviews.view\nE       ?      ^^^\nE       +     pyramid.tests.test_scripts.test_pviews.view\nE       ?     ++ ^^^^^\n\nr2e_tests/test_scripts/test_pviews.py:296: AssertionError\n==================================== PASSES ====================================\n=========================== short test summary info ============================\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_allows_other_predicates\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_context\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_for_\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_http_cache\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_name\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_permission\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_with_renderer\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_with_view_defaults\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_allows_other_predicates\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_append_slash\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_context\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_for_\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_http_cache\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_name\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_permission\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_with_renderer\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_with_view_defaults\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_static_view_absolute\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_static_view_package_relative\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_as_instance\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_as_instance_requestonly\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_as_instancemethod\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_as_instancemethod_requestonly\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_as_oldstyle_class\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_as_oldstyle_class_requestonly\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_context_as_class\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_context_as_dottedname\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_context_as_iface\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_context_trumps_for\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_custom_more_preds_first_bests_fewer_preds_last\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_default_phash_overrides_default_phash\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_default_phash_overrides_no_phash\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_default_phash_overrides_default_phash\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_default_phash_overrides_no_phash\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_multiview_replaces_existing_securedview\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_multiview_replaces_existing_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_multiview_replaces_multiview\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_mulview_replaces_existing_view_with___accept__\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_same_phash_overrides_existing_single_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_with_accept_multiview_replaces_existing_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exception_register_secured_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_for__as_dottedname\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_for_as_class\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_for_as_iface\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_mixed_case_replaces_existing_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview___discriminator__\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview_call_ordering\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview_context_superclass_then_subclass\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview_exception_superclass_then_subclass\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_existing_securedview\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_existing_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_existing_view_with___accept__\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_multiview\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_register_secured_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_same_phash_overrides_existing_single_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_same_predicates\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_view_callable_None_no_renderer\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_view_callable_None_with_renderer\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_view_callable_dottedname\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_accept_match\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_accept_multiview_replaces_existing_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_accept_nomatch\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_containment_dottedname\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_containment_false\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_containment_true\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_decorator\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_decorator_tuple\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_default_permission_no_explicit_permission\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_default_renderer\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_function_callable\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_function_callable_requestonly\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_header_badregex\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_header_noval_match\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_header_noval_nomatch\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_header_val_match\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_header_val_missing\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_header_val_nomatch\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_http_cache\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_mapper\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_name\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_name_unicode\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_no_default_permission_no_explicit_permission\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_nonexistant_route_name\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_path_info_badregex\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_path_info_match\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_path_info_nomatch\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_permission\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_method_false\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_method_get_implies_head\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_method_sequence_conflict\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_method_sequence_false\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_method_sequence_true\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_method_true\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_param_noval_false\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_param_noval_true\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_param_val_false\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_param_val_true\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_type\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_type_and_route_name\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_type_as_iface\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_type_as_noniface\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_route_name\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_route_name_exception\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_tmpl_renderer_factory_introspector_missing\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_tmpl_renderer_factory_no_renderer_factory\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_tmpl_renderer_factory_with_renderer_factory\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_view_config_and_view_defaults_conflicts\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_view_config_and_view_defaults_doesnt_conflict\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults_viewname_is_dottedname_kwarg\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_xhr_false\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_xhr_true\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_wrapped_view_is_decorated\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_views_with_accept_multiview_replaces_existing\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_derive_view_dottedname\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_derive_view_function\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_derive_view_with_default_renderer_no_explicit_renderer\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_derive_view_with_default_renderer_with_explicit_renderer\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_set_view_mapper\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_set_view_mapper_dottedname\nPASSED r2e_tests/test_1.py::Test_requestonly::test_defaults\nPASSED r2e_tests/test_1.py::Test_requestonly::test_otherattr\nPASSED r2e_tests/test_1.py::Test_isexception::test_is_IException\nPASSED r2e_tests/test_1.py::Test_isexception::test_is_IException_subinterface\nPASSED r2e_tests/test_1.py::Test_isexception::test_is_exception_class\nPASSED r2e_tests/test_1.py::Test_isexception::test_is_exception_instance\nPASSED r2e_tests/test_1.py::TestMultiView::test___call__\nPASSED r2e_tests/test_1.py::TestMultiView::test___call__intermediate_not_found\nPASSED r2e_tests/test_1.py::TestMultiView::test___call__raise_not_found_isnt_interpreted_as_pred_mismatch\nPASSED r2e_tests/test_1.py::TestMultiView::test___call_permissive_has_call_permissive\nPASSED r2e_tests/test_1.py::TestMultiView::test___call_permissive_has_no_call_permissive\nPASSED r2e_tests/test_1.py::TestMultiView::test__call__not_found\nPASSED r2e_tests/test_1.py::TestMultiView::test__call__with_accept_match\nPASSED r2e_tests/test_1.py::TestMultiView::test__call__with_accept_miss\nPASSED r2e_tests/test_1.py::TestMultiView::test__call_permissive__not_found\nPASSED r2e_tests/test_1.py::TestMultiView::test_add\nPASSED r2e_tests/test_1.py::TestMultiView::test_add_with_phash\nPASSED r2e_tests/test_1.py::TestMultiView::test_add_with_phash_override_accept\nPASSED r2e_tests/test_1.py::TestMultiView::test_add_with_phash_override_accept2\nPASSED r2e_tests/test_1.py::TestMultiView::test_class_implements_ISecuredView\nPASSED r2e_tests/test_1.py::TestMultiView::test_get_views\nPASSED r2e_tests/test_1.py::TestMultiView::test_get_views_best_match_returns_None\nPASSED r2e_tests/test_1.py::TestMultiView::test_get_views_no_self_accepts\nPASSED r2e_tests/test_1.py::TestMultiView::test_get_views_request_has_no_accept\nPASSED r2e_tests/test_1.py::TestMultiView::test_instance_implements_ISecuredView\nPASSED r2e_tests/test_1.py::TestMultiView::test_match_not_found\nPASSED r2e_tests/test_1.py::TestMultiView::test_match_predicate_fails\nPASSED r2e_tests/test_1.py::TestMultiView::test_match_predicate_succeeds\nPASSED r2e_tests/test_1.py::TestMultiView::test_multiple_with_functions_as_views\nPASSED r2e_tests/test_1.py::TestMultiView::test_permitted\nPASSED r2e_tests/test_1.py::TestMultiView::test_permitted_no_match_with__permitted__\nPASSED r2e_tests/test_1.py::TestMultiView::test_permitted_no_views\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_function_context_and_request\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_function_requestonly\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_instance_context_and_request\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_instance_context_and_request_attr_and_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_instance_requestonly_attr_and_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_newstyle_class_context_and_request\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_newstyle_class_context_and_request_attr_and_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_newstyle_class_requestonly\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_newstyle_class_requestonly_attr_and_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_oldstyle_class_context_and_request\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_oldstyle_class_requestonly\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_oldstyle_cls_context_request_attr_and_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_oldstyle_cls_requestonly_attr_and_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_attr_wrapped_view_branching_default_phash\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_attr_wrapped_view_branching_nondefault_phash\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_class_with_attr\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_class_without_attr\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_debug_auth_permission_authpol_denied\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_debug_auth_permission_authpol_denied2\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_debug_auth_permission_authpol_overridden\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_debug_auth_permission_authpol_permitted\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_debug_auth_permission_authpol_permitted_no_request\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_function_returns_true_Response_no_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_function_returns_true_Response_with_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_http_cached_prevent_http_cache_in_settings\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_http_cached_view_bad_tuple\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_http_cached_view_integer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_http_cached_view_prevent_auto_set\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_http_cached_view_timedelta\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_http_cached_view_tuple\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_http_cached_view_tuple_seconds_None\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_predicate_mismatch_exception_has_text_in_detail\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_predicate_mismatch_view_has_name\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_predicate_mismatch_view_has_no_name\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_requestonly_function\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_requestonly_function_with_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_requestonly_function_with_renderer_request_has_view\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_requestonly_function_with_renderer_request_override\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_secured_view_authn_policy_no_authz_policy\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_secured_view_authz_policy_no_authn_policy\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_secured_view_raises_forbidden_no_name\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_secured_view_raises_forbidden_with_name\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_debug_authorization_authn_policy_no_authz_policy\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_debug_authorization_authz_policy_no_authn_policy\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_debug_authorization_no_authpol\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_debug_authorization_no_permission\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_predicates_all\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_predicates_checker\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_predicates_notall\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_view_mapper_config_specified\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_view_mapper_default_mapper_specified\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_view_mapper_view_specified\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_wrapper_viewname\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_wrapper_viewname_notfound\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test__view_as_function_with_attr\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_function_context_and_request\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_function_requestonly\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_function_requestonly_with_attr\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_instance_context_and_request\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_instance_context_and_request_and_attr\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_instance_requestonly\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_instance_requestonly_with_attr\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_newstyle_class_context_and_request\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_newstyle_class_context_and_request_with_attr\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_newstyle_class_requestonly\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_newstyle_class_requestonly_with_attr\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_oldstyle_class_context_and_request\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_oldstyle_class_context_and_request_with_attr\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_oldstyle_class_requestonly\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_oldstyle_class_requestonly_with_attr\nPASSED r2e_tests/test_1.py::Test_preserve_view_attrs::test_it_different\nPASSED r2e_tests/test_1.py::Test_preserve_view_attrs::test_it_different_with_existing_original_view\nPASSED r2e_tests/test_1.py::Test_preserve_view_attrs::test_it_same\nPASSED r2e_tests/test_1.py::Test_preserve_view_attrs::test_it_view_is_None\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_already_exists\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_url_noendslash\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_url_noscheme\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_url_withendslash\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_viewname\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_viewname_with_context\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_viewname_with_for_\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_viewname_with_permission\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_viewname_with_renderer\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_viewname_with_route_prefix\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_missing\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_quoting\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_registration_miss\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_registration_no_registry_on_request\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_route_url\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_slash_in_name1\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_slash_in_name2\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_url_quoted_remote\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_url_unquoted_local\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_verifyClass\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_verifyObject\nPASSED r2e_tests/test_1.py::Test_view_description::test_with_text\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_object_event_subscriber\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_resource_url_default_resource_iface_means_Interface\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_resource_url_nodefault_resource_iface\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_response_adapter\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_response_adapter_dottednames\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_response_adapter_self\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_defaults\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_dottednames\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_iface_specified\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_predicate\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_with_default_type_predicates_False\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_with_default_type_predicates_True\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_with_specific_type_and_predicates_False\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_with_specific_type_and_predicates_True\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_traverser_default_iface_means_Interface\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_traverser_introspectables\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_traverser_nondefault_iface\nPASSED r2e_tests/test_config/test_adapters.py::Test_eventonly::test_defaults\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test__override_already_registered\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test__override_not_yet_registered\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_directory_with_directory\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_directory_with_file\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_directory_with_package\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_file_with_directory\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_file_with_file\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_file_with_package\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_package_with_directory\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_package_with_package\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_samename\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_filename_override_returns_value\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_stream_no_overrides\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_stream_override_returns_None\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_stream_override_returns_value\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_string_no_overrides\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_string_override_returns_None\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_string_override_returns_value\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_has_resource_no_overrides\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_has_resource_override_returns_None\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_has_resource_override_returns_True\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_resource_isdir_no_overrides\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_resource_isdir_override_returns_False\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_resource_isdir_override_returns_None\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_resource_listdir_no_overrides\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_resource_listdir_override_returns_None\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_resource_listdir_override_returns_values\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_class_conforms_to_IPEP302Loader\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_class_conforms_to_IPackageOverrides\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_ctor_package_already_has_loader_of_different_type\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_ctor_package_already_has_loader_of_same_type\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_ctor_registers_loader_type\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_ctor_sets_loader\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_ctor_sets_local_state\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_code_pkg_has___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_code_pkg_has_no___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_data_pkg_has___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_data_pkg_has_no___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_filename_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_source_pkg_has___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_source_pkg_has_no___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_stream\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_stream_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_string\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_string_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_has_resource\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_has_resource_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_insert_directory\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_insert_emptystring\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_insert_file\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_instance_conforms_to_IPEP302Loader\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_instance_conforms_to_IPackageOverrides\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_is_package_pkg_has___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_is_package_pkg_has_no___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_isdir_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_isdir_false\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_isdir_true\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_listdir\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_listdir_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_search_path\nPASSED r2e_tests/test_config/test_assets.py::TestDirectoryOverride::test_it_match\nPASSED r2e_tests/test_config/test_assets.py::TestDirectoryOverride::test_it_no_match\nPASSED r2e_tests/test_config/test_assets.py::TestFileOverride::test_it_match\nPASSED r2e_tests/test_config/test_assets.py::TestFileOverride::test_it_no_match\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_add_request_method_with_None_callable\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_add_request_method_with_None_callable_and_no_name\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_add_request_method_with_None_callable_conflict\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_add_request_method_with_callable\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_add_request_method_with_unnamed_callable\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_multiple_request_methods_conflict\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_request_factory\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_request_factory_dottedname\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_root_factory\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_root_factory_as_None\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_root_factory_dottedname\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_session_factory\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_session_factory_dottedname\nPASSED r2e_tests/test_config/test_factories.py::TestDeprecatedFactoriesMixinMethods::test_set_multiple_request_properties\nPASSED r2e_tests/test_config/test_factories.py::TestDeprecatedFactoriesMixinMethods::test_set_multiple_request_properties_conflict\nPASSED r2e_tests/test_config/test_factories.py::TestDeprecatedFactoriesMixinMethods::test_set_request_property_with_callable\nPASSED r2e_tests/test_config/test_factories.py::TestDeprecatedFactoriesMixinMethods::test_set_request_property_with_property\nPASSED r2e_tests/test_config/test_factories.py::TestDeprecatedFactoriesMixinMethods::test_set_request_property_with_unnamed_callable\nPASSED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_missing_dir\nPASSED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_no_specs\nPASSED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_set_locale_negotiator\nPASSED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_set_locale_negotiator_dottedname\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test___getattr__matches\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test___getattr__matches_no_action_wrap\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test___getattr__missing_when_directives_dont_exist\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test___getattr__missing_when_directives_exist\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test__fix_registry_has_listeners\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test__fix_registry_notify\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test__fix_registry_queryAdapterOrSelf\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test__fix_registry_registerSelfAdapter\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_absolute_asset_spec_already_absolute\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_absolute_asset_spec_notastring\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_absolute_asset_spec_relative\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_autocommit_with_introspectables\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_autocommit_with_introspectables_introspection_off\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_branching_kw_is_None\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_branching_kw_is_not_None\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_branching_nonautocommit_with_config_info\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_branching_nonautocommit_with_introspectables\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_branching_nonautocommit_without_config_info\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_nonautocommit_with_introspectables_introspection_off\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_autocommit_no_conflicts\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_begin\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_begin_with_request\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_commit_conflict_resolved_with_include\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_commit_conflict_resolved_with_two_includes_and_local\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_commit_conflict_simple\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_commit_conflict_with_two_includes\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_conflict_set_forbidden_view\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_conflict_set_notfound_view\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_alternate_renderers\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_authentication_policy\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_authorization_policy_only\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_default_permission\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_default_renderers\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_default_view_mapper\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_default_webob_response_adapter_registered\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_exceptionresponse_view_None\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_exceptionresponse_view_custom\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_httpexception_view_default\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_no_root_factory\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_noreg_custom_settings\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_noreg_debug_logger_non_None\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_session_factory\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_with_introspection\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_with_package_registry\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_with_root_factory\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_end\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_hook_zca\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_dotted_name\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_missing_source_file\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_module_defaults_to_includeme\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_module_defaults_to_includeme_missing\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_nested_route_prefix\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_python_callable\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_route_prefix\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_introspector_decorator\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_make_wsgi_app\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_maybe_dotted_notstring_success\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_maybe_dotted_string_fail\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_maybe_dotted_string_success\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_scan_integration\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_scan_integration_dottedname_package\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_scan_integration_with_extra_kw\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_scan_integration_with_ignore\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_scan_integration_with_onerror\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_alternate_renderers\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authentication_policy\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authentication_policy_dottedname\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authorization_policy_dottedname\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authorization_policy_only\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_calls_fix_registry\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_custom_settings\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_debug_logger_name\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_debug_logger_non_None\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_default_permission\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_dottedname_root_factory\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_explicit_notfound_trumps_iexceptionresponse\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_includes\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_includes_spaces\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_locale_negotiator\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_locale_negotiator_dottedname\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_no_default_root_factory\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_registers_default_exceptionresponse_views\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_registers_default_view_predicates\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_registers_default_webob_iresponse_adapter\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_request_factory\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_request_factory_dottedname\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_tweens\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_unhook_zca\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_with_package\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_with_package_module\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_with_package_package\nPASSED r2e_tests/test_config/test_init.py::TestConfigurator_add_directive::test_directive_persists_across_configurator_creations\nPASSED r2e_tests/test_config/test_init.py::TestConfigurator_add_directive::test_extend_action_method_successful\nPASSED r2e_tests/test_config/test_init.py::TestConfigurator_add_directive::test_extend_same_name_doesnt_conflict\nPASSED r2e_tests/test_config/test_init.py::TestConfigurator__add_predicate::test_factory_as_object\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_action_simple\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_action_with_includepath\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_action_with_includepath_and_info\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_action_with_info\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_action_with_introspectables\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_action_with_order\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_execute_actions_dicts\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_execute_actions_error\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_execute_actions_tuples\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_execute_actions_with_introspectable_no_callable\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_execute_actions_with_introspectables\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_it\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_processSpec\nPASSED r2e_tests/test_config/test_init.py::Test_resolveConflicts::test_it_conflict\nPASSED r2e_tests/test_config/test_init.py::Test_resolveConflicts::test_it_success_dicts\nPASSED r2e_tests/test_config/test_init.py::Test_resolveConflicts::test_it_success_tuples\nPASSED r2e_tests/test_config/test_init.py::Test_resolveConflicts::test_it_with_actions_grouped_by_order\nPASSED r2e_tests/test_config/test_init.py::TestGlobalRegistriesIntegration::test_global_registries\nPASSED r2e_tests/test_config/test_init.py::TestGlobalRegistriesIntegration::test_global_registries_empty\nPASSED r2e_tests/test_config/test_predicates.py::TestXHRPredicate::test___call___false\nPASSED r2e_tests/test_config/test_predicates.py::TestXHRPredicate::test___call___true\nPASSED r2e_tests/test_config/test_predicates.py::TestXHRPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::TestXHRPredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestMethodPredicate::test___call___false\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestMethodPredicate::test___call___true_multi\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestMethodPredicate::test___call___true_single\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestMethodPredicate::test_ctor_get_but_no_head\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestMethodPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestMethodPredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::TestPathInfoPredicate::test___call___false\nPASSED r2e_tests/test_config/test_predicates.py::TestPathInfoPredicate::test___call___true\nPASSED r2e_tests/test_config/test_predicates.py::TestPathInfoPredicate::test_ctor_compilefail\nPASSED r2e_tests/test_config/test_predicates.py::TestPathInfoPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::TestPathInfoPredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test___call___false\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test___call___false_multi\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test___call___true_exists\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test___call___true_multi\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test___call___true_withval\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test_phash_exists\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test_phash_withval\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test_text_exists\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test_text_multi\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test_text_withval\nPASSED r2e_tests/test_config/test_predicates.py::TestMatchParamPredicate::test___call___false\nPASSED r2e_tests/test_config/test_predicates.py::TestMatchParamPredicate::test___call___matchdict_is_None\nPASSED r2e_tests/test_config/test_predicates.py::TestMatchParamPredicate::test___call___true_multi\nPASSED r2e_tests/test_config/test_predicates.py::TestMatchParamPredicate::test___call___true_single\nPASSED r2e_tests/test_config/test_predicates.py::TestMatchParamPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::TestMatchParamPredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::TestCustomPredicate::test___call___false\nPASSED r2e_tests/test_config/test_predicates.py::TestCustomPredicate::test___call___true\nPASSED r2e_tests/test_config/test_predicates.py::TestCustomPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::TestCustomPredicate::test_text_func_has___text__\nPASSED r2e_tests/test_config/test_predicates.py::TestCustomPredicate::test_text_func_repr\nPASSED r2e_tests/test_config/test_predicates.py::TestTraversePredicate::test___call__traverse_has_remainder_already\nPASSED r2e_tests/test_config/test_predicates.py::TestTraversePredicate::test___call__traverse_matches\nPASSED r2e_tests/test_config/test_predicates.py::TestTraversePredicate::test___call__traverse_matches_with_highorder_chars\nPASSED r2e_tests/test_config/test_predicates.py::TestTraversePredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::TestTraversePredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::Test_CheckCSRFTokenPredicate::test_it_call_val_False\nPASSED r2e_tests/test_config/test_predicates.py::Test_CheckCSRFTokenPredicate::test_it_call_val_True\nPASSED r2e_tests/test_config/test_predicates.py::Test_CheckCSRFTokenPredicate::test_it_call_val_str\nPASSED r2e_tests/test_config/test_predicates.py::Test_CheckCSRFTokenPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::Test_CheckCSRFTokenPredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test___call___false\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test___call___false_withregex\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test___call___true_exists\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test___call___true_withregex\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test___call___true_withval\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test_phash_exists\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test_phash_withregex\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test_phash_withval\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test_text_exists\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test_text_withregex\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test_text_withval\nPASSED r2e_tests/test_config/test_predicates.py::Test_PhysicalPathPredicate::test_it_call_False\nPASSED r2e_tests/test_config/test_predicates.py::Test_PhysicalPathPredicate::test_it_call_context_has_no_name\nPASSED r2e_tests/test_config/test_predicates.py::Test_PhysicalPathPredicate::test_it_call_val_list_True\nPASSED r2e_tests/test_config/test_predicates.py::Test_PhysicalPathPredicate::test_it_call_val_str_True\nPASSED r2e_tests/test_config/test_predicates.py::Test_PhysicalPathPredicate::test_it_call_val_tuple_True\nPASSED r2e_tests/test_config/test_predicates.py::Test_PhysicalPathPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::Test_PhysicalPathPredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::Test_EffectivePrincipalsPredicate::test_it_call_authentication_policy_doesnt_provide_superset\nPASSED r2e_tests/test_config/test_predicates.py::Test_EffectivePrincipalsPredicate::test_it_call_authentication_policy_provides_superset\nPASSED r2e_tests/test_config/test_predicates.py::Test_EffectivePrincipalsPredicate::test_it_call_authentication_policy_provides_superset_implicit\nPASSED r2e_tests/test_config/test_predicates.py::Test_EffectivePrincipalsPredicate::test_it_call_no_authentication_policy\nPASSED r2e_tests/test_config/test_predicates.py::Test_EffectivePrincipalsPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::Test_EffectivePrincipalsPredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::Test_EffectivePrincipalsPredicate::test_text_noniter\nPASSED r2e_tests/test_config/test_rendering.py::TestRenderingConfiguratorMixin::test_add_default_renderers\nPASSED r2e_tests/test_config/test_rendering.py::TestRenderingConfiguratorMixin::test_add_renderer\nPASSED r2e_tests/test_config/test_rendering.py::TestRenderingConfiguratorMixin::test_add_renderer_dottedname_factory\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_defaults\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_discriminator\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_no_path_no_pattern\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_no_pattern_with_path\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_no_view_with_view_attr\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_no_view_with_view_context\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_no_view_with_view_permission\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_no_view_with_view_renderer\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_accept\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_custom_predicates\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_factory\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_factory_dottedname\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_header\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_path_info\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_path_info_highorder\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_path_info_regex\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_pregenerator\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_request_method\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_request_param\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_route_prefix\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_static\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_xhr\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_get_routes_mapper_already_registered\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_get_routes_mapper_not_yet_registered\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_add_permission\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_no_authz_policy\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_no_authz_policy_autocommit\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_with_authz_policy\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_with_authz_policy_autocommit\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_no_authn_policy\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_no_authn_policy_autocommit\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_with_authn_policy\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_with_authn_policy_autocommit\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_default_permission\nPASSED r2e_tests/test_config/test_settings.py::TestSettingsConfiguratorMixin::test__set_settings_as_None\nPASSED r2e_tests/test_config/test_settings.py::TestSettingsConfiguratorMixin::test__set_settings_as_dictwithvalues\nPASSED r2e_tests/test_config/test_settings.py::TestSettingsConfiguratorMixin::test_add_settings_settings_None\nPASSED r2e_tests/test_config/test_settings.py::TestSettingsConfiguratorMixin::test_add_settings_settings_already_registered\nPASSED r2e_tests/test_config/test_settings.py::TestSettingsConfiguratorMixin::test_add_settings_settings_not_yet_registered\nPASSED r2e_tests/test_config/test_settings.py::TestSettingsConfiguratorMixin::test_get_settings_nosettings\nPASSED r2e_tests/test_config/test_settings.py::TestSettingsConfiguratorMixin::test_get_settings_withsettings\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_debug_all\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_debug_authorization\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_debug_notfound\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_debug_routematch\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_debug_templates\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_default_locale_name\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_getattr_fail\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_getattr_raises_attribute_error\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_getattr_success\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_noargs\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_originals_kept\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_prevent_http_cache\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_reload_all\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_reload_assets\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_reload_resources\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_reload_templates\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_renderer\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_renderer_explicitrenderer\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_renderer_twice\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_subscriber_defaults\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_subscriber_dottedname\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_subscriber_multiple\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_subscriber_single\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_template\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_resources\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_securitypolicy\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_securitypolicy_forget_result\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_securitypolicy_remember_result\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_dottedname\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_instance\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_name_ingress\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_name_main\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_over_ingress\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_over_ingress_iterable\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_under_main\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_under_main_iterable\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_unsuitable\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tweens_conflict\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tweens_names_distinct\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tweens_names_with_over_nonstringoriter\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tweens_names_with_under_nonstringoriter\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tweens_names_with_underover\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test___call___explicit\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test___call___implicit\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_add_explicit\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_add_implicit\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_1\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_2\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_3\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_4\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_5\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_conflict_direct\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_conflict_indirect\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_missing_over_and_under_partials\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_missing_over_partial\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_missing_over_partial_with_fallback\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_missing_under_partial\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_missing_under_partial_with_fallback\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_with_missing_fallbacks\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_with_multiple_matching_fallbacks\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_with_partial_fallbacks\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_custom_predicates_can_affect_traversal\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_different_custom_predicates_with_same_hash\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_match_param_from_dict\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_match_param_from_dict_fails\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_match_param_from_string\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_match_param_from_string_fails\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_notted\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_ordering_importance_and_number\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_ordering_importance_of_predicates\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_ordering_number_of_predicates\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_ordering_xhr_and_request_method_trump_only_containment\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_predicate_text_is_correct\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_request_method_ordering_hashes_same\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_request_method_sequence\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_traverse_has_remainder_already\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_traverse_matches\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_traverse_matches_with_highorder_chars\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_unknown_predicate\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_defaultargs_firstname_not_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_defaultargs_firstname_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_noargs\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_onearg_named_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_onearg_named_somethingelse\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_toomanyargs\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_with_attr_false\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_with_attr_true\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_instance_defaultargs_firstname_not_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_instance_defaultargs_firstname_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_instance_defaultargs_onearg_named_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_instance_defaultargs_onearg_named_somethingelse\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_instance_nocall\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_instance_toomanyargs\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_method_onearg_named_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_newstyle_class_init_defaultargs_firstname_not_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_newstyle_class_init_defaultargs_firstname_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_newstyle_class_init_firstname_request_with_secondname\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_newstyle_class_init_noargs\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_newstyle_class_init_onearg_named_somethingelse\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_oldstyle_class_init_defaultargs_firstname_not_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_oldstyle_class_init_defaultargs_firstname_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_oldstyle_class_init_noargs\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_oldstyle_class_init_onearg_named_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_oldstyle_class_init_onearg_named_somethingelse\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_oldstyle_class_init_toomanyargs\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_oldstyle_class_no_init\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_requestonly_newstyle_class_init_onearg_named_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_requestonly_newstyle_class_init_toomanyargs\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_requestonly_newstyle_class_no_init\nPASSED r2e_tests/test_config/test_util.py::TestNotted::test_it_with_phash_val\nPASSED r2e_tests/test_config/test_util.py::TestNotted::test_it_without_phash_val\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_allows_other_predicates\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_context\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_for_\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_http_cache\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_name\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_permission\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_with_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_with_view_defaults\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_allows_other_predicates\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_append_slash\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_context\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_for_\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_http_cache\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_name\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_permission\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_with_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_with_view_defaults\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_static_view_absolute\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_static_view_here_no_utility_registered\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_static_view_package_relative\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_as_instance\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_as_instance_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_as_instancemethod\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_as_instancemethod_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_as_oldstyle_class\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_as_oldstyle_class_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_context_as_class\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_context_as_dottedname\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_context_as_iface\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_context_trumps_for\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_custom_more_preds_first_bests_fewer_preds_last\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_default_phash_overrides_default_phash\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_default_phash_overrides_no_phash\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_default_phash_overrides_default_phash\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_default_phash_overrides_no_phash\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_multiview_replaces_existing_securedview\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_multiview_replaces_existing_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_multiview_replaces_multiview\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_mulview_replaces_existing_view_with___accept__\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_same_phash_overrides_existing_single_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_with_accept_multiview_replaces_existing_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exception_register_secured_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_for__as_dottedname\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_for_as_class\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_for_as_iface\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_mixed_case_replaces_existing_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview___discriminator__\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview_call_ordering\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview_context_superclass_then_subclass\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview_exception_superclass_then_subclass\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_existing_securedview\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_existing_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_existing_view_with___accept__\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_multiview\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_register_secured_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_same_phash_overrides_existing_single_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_same_predicates\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_view_callable_None_no_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_view_callable_None_with_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_view_callable_dottedname\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_accept_match\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_accept_multiview_replaces_existing_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_accept_nomatch\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_containment_dottedname\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_containment_false\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_containment_true\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_decorator\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_decorator_tuple\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_default_permission_no_explicit_permission\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_default_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_function_callable\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_function_callable_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_header_badregex\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_header_noval_match\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_header_noval_nomatch\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_header_val_match\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_header_val_missing\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_header_val_nomatch\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_http_cache\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_mapper\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_name\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_name_unicode\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_no_default_permission_no_explicit_permission\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_nonexistant_route_name\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_path_info_badregex\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_path_info_match\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_path_info_nomatch\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_permission\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_method_false\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_method_get_implies_head\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_method_sequence_conflict\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_method_sequence_false\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_method_sequence_true\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_method_true\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_param_noval_false\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_param_noval_true\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_param_val_false\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_param_val_true\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_type\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_type_and_route_name\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_type_as_iface\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_type_as_noniface\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_route_name\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_route_name_exception\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_tmpl_renderer_factory_introspector_missing\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_tmpl_renderer_factory_no_renderer_factory\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_tmpl_renderer_factory_with_renderer_factory\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_view_config_and_view_defaults_conflicts\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_view_config_and_view_defaults_doesnt_conflict\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults_viewname_is_dottedname_kwarg\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_xhr_false\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_xhr_true\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_wrapped_view_is_decorated\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_views_with_accept_multiview_replaces_existing\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_derive_view_dottedname\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_derive_view_function\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_derive_view_with_default_renderer_no_explicit_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_derive_view_with_default_renderer_with_explicit_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_set_view_mapper\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_set_view_mapper_dottedname\nPASSED r2e_tests/test_config/test_views.py::Test_requestonly::test_defaults\nPASSED r2e_tests/test_config/test_views.py::Test_requestonly::test_otherattr\nPASSED r2e_tests/test_config/test_views.py::Test_isexception::test_is_IException\nPASSED r2e_tests/test_config/test_views.py::Test_isexception::test_is_IException_subinterface\nPASSED r2e_tests/test_config/test_views.py::Test_isexception::test_is_exception_class\nPASSED r2e_tests/test_config/test_views.py::Test_isexception::test_is_exception_instance\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test___call__\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test___call__intermediate_not_found\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test___call__raise_not_found_isnt_interpreted_as_pred_mismatch\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test___call_permissive_has_call_permissive\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test___call_permissive_has_no_call_permissive\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test__call__not_found\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test__call__with_accept_match\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test__call__with_accept_miss\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test__call_permissive__not_found\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_add\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_add_with_phash\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_add_with_phash_override_accept\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_add_with_phash_override_accept2\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_class_implements_ISecuredView\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_get_views\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_get_views_best_match_returns_None\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_get_views_no_self_accepts\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_get_views_request_has_no_accept\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_instance_implements_ISecuredView\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_match_not_found\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_match_predicate_fails\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_match_predicate_succeeds\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_multiple_with_functions_as_views\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_permitted\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_permitted_no_match_with__permitted__\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_permitted_no_views\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_function_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_function_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_instance_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_instance_context_and_request_attr_and_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_instance_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_instance_requestonly_attr_and_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_newstyle_class_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_newstyle_class_context_and_request_attr_and_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_newstyle_class_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_newstyle_class_requestonly_attr_and_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_oldstyle_class_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_oldstyle_class_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_oldstyle_cls_context_request_attr_and_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_oldstyle_cls_requestonly_attr_and_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_attr_wrapped_view_branching_default_phash\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_attr_wrapped_view_branching_nondefault_phash\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_class_with_attr\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_class_without_attr\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_debug_auth_permission_authpol_denied\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_debug_auth_permission_authpol_denied2\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_debug_auth_permission_authpol_overridden\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_debug_auth_permission_authpol_permitted\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_debug_auth_permission_authpol_permitted_no_request\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_function_returns_true_Response_no_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_function_returns_true_Response_with_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_http_cached_prevent_http_cache_in_settings\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_http_cached_view_bad_tuple\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_http_cached_view_integer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_http_cached_view_prevent_auto_set\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_http_cached_view_timedelta\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_http_cached_view_tuple\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_http_cached_view_tuple_seconds_None\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_predicate_mismatch_exception_has_text_in_detail\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_predicate_mismatch_view_has_name\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_predicate_mismatch_view_has_no_name\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_requestonly_function\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_requestonly_function_with_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_requestonly_function_with_renderer_request_has_view\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_requestonly_function_with_renderer_request_override\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_secured_view_authn_policy_no_authz_policy\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_secured_view_authz_policy_no_authn_policy\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_secured_view_raises_forbidden_no_name\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_secured_view_raises_forbidden_with_name\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_debug_authorization_authn_policy_no_authz_policy\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_debug_authorization_authz_policy_no_authn_policy\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_debug_authorization_no_authpol\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_debug_authorization_no_permission\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_predicates_all\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_predicates_checker\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_predicates_notall\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_view_mapper_config_specified\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_view_mapper_default_mapper_specified\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_view_mapper_view_specified\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_wrapper_viewname\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_wrapper_viewname_notfound\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test__view_as_function_with_attr\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_function_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_function_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_function_requestonly_with_attr\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_instance_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_instance_context_and_request_and_attr\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_instance_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_instance_requestonly_with_attr\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_newstyle_class_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_newstyle_class_context_and_request_with_attr\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_newstyle_class_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_newstyle_class_requestonly_with_attr\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_oldstyle_class_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_oldstyle_class_context_and_request_with_attr\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_oldstyle_class_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_oldstyle_class_requestonly_with_attr\nPASSED r2e_tests/test_config/test_views.py::Test_preserve_view_attrs::test_it_different\nPASSED r2e_tests/test_config/test_views.py::Test_preserve_view_attrs::test_it_different_with_existing_original_view\nPASSED r2e_tests/test_config/test_views.py::Test_preserve_view_attrs::test_it_same\nPASSED r2e_tests/test_config/test_views.py::Test_preserve_view_attrs::test_it_view_is_None\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_already_exists\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_url_noendslash\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_url_noscheme\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_url_withendslash\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_viewname\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_viewname_with_context\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_viewname_with_for_\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_viewname_with_permission\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_viewname_with_renderer\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_viewname_with_route_prefix\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_missing\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_quoting\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_registration_miss\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_registration_no_registry_on_request\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_route_url\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_slash_in_name1\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_slash_in_name2\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_url_quoted_remote\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_url_unquoted_local\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_verifyClass\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_verifyObject\nPASSED r2e_tests/test_config/test_views.py::Test_view_description::test_with_text\nPASSED r2e_tests/test_scripts/test_common.py::Test_logging_file_config::test_it\nPASSED r2e_tests/test_scripts/test_common.py::TestParseVars::test_parse_vars_bad\nPASSED r2e_tests/test_scripts/test_common.py::TestParseVars::test_parse_vars_good\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_known_scaffold_absolute_path\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_known_scaffold_multiple_rendered\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_known_scaffold_single_rendered\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_known_scaffold_with_path_as_project_target_rendered\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_no_project_name\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_run_no_scaffold_name\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_run_show_scaffolds_exist\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_run_show_scaffolds_none_exist\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_unknown_scaffold_name\nPASSED r2e_tests/test_scripts/test_pcreate.py::Test_main::test_it\nPASSED r2e_tests/test_scripts/test_pdistreport.py::TestPDistReportCommand::test_no_dists\nPASSED r2e_tests/test_scripts/test_pdistreport.py::TestPDistReportCommand::test_with_dists\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_has_bad_config_header\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_not_enough_args\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_response_has_no_charset\nPASSED r2e_tests/test_scripts/test_prequest.py::Test_main::test_it\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test__get_mapper\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_bad_args\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_good_args\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_no_mapper\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_no_routes\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_route_with_no_slash_prefix\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_single_route_no_route_registered\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_single_route_no_views_registered\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_single_route_one_view_registered\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_single_route_one_view_registered_with_factory\nPASSED r2e_tests/test_scripts/test_proutes.py::Test_main::test_it\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_get_options_no_command\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_get_options_with_command\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_parse_vars_bad\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_parse_vars_good\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_record_pid_not_verbose\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_record_pid_verbose\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_current_pid_is_not_pid_in_file\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_current_pid_is_not_written_pid\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_file_not_verbose\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_file_stale_pid_write_exception\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_file_unlink_exception\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_file_verbose\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_no_pid_file\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_not_a_number\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_run_no_args\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_run_stop_daemon_bad_pid_file\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_run_stop_daemon_invalid_pid_in_file\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_run_stop_daemon_no_such_pid_file\nPASSED r2e_tests/test_scripts/test_pserve.py::Test_read_pidfile::test_read_pidfile\nPASSED r2e_tests/test_scripts/test_pserve.py::Test_read_pidfile::test_read_pidfile_no_pid_file\nPASSED r2e_tests/test_scripts/test_pserve.py::Test_read_pidfile::test_read_pidfile_not_a_number\nPASSED r2e_tests/test_scripts/test_pserve.py::Test_main::test_it\nPASSED r2e_tests/test_scripts/test_pserve.py::TestLazyWriter::test_flush\nPASSED r2e_tests/test_scripts/test_pserve.py::TestLazyWriter::test_open\nPASSED r2e_tests/test_scripts/test_pserve.py::TestLazyWriter::test_write\nPASSED r2e_tests/test_scripts/test_pserve.py::TestLazyWriter::test_writeline\nPASSED r2e_tests/test_scripts/test_pserve.py::Test__methodwrapper::test___call__fail\nPASSED r2e_tests/test_scripts/test_pserve.py::Test__methodwrapper::test___call__succeed\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_custom_section_override\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_bpython_shell\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_check_variable_override_order\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_custom_items\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_default_shell\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_default_shell_with_unknown_shell\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_ipython_v0_10\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_ipython_v0_11\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_setup_from_options\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_setup\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_make_bpython_shell\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_make_default_shell\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_make_ipython_v0_10_shell\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_make_ipython_v0_11_shell\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_shell_ipython_ordering\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_shell_ordering\nPASSED r2e_tests/test_scripts/test_pshell.py::Test_main::test_it\nPASSED r2e_tests/test_scripts/test_ptweens.py::TestPTweensCommand::test__get_tweens\nPASSED r2e_tests/test_scripts/test_ptweens.py::TestPTweensCommand::test_command_implicit_and_explicit_tweens\nPASSED r2e_tests/test_scripts/test_ptweens.py::TestPTweensCommand::test_command_implicit_tweens_only\nPASSED r2e_tests/test_scripts/test_ptweens.py::TestPTweensCommand::test_command_no_tweens\nPASSED r2e_tests/test_scripts/test_ptweens.py::Test_main::test_it\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_multi_routes_all_match\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_multi_routes_none_match\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_multi_routes_some_match\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_view_no_match\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_view_no_match_multiview_registered\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_view_route_multiview\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_view_route_multiview_no_view_registered\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_view_route_no_multiview\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_view_traversal\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_view_traversal_multiview\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multi_view_nested\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multiview\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multiview_with_permission\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multiview_with_predicates\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_not_found\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_not_found_url_starts_without_slash\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_route\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_route_with_route_predicates\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_traversal\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_traversal_with_permission\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_traversal_with_predicates\nPASSED r2e_tests/test_scripts/test_pviews.py::Test_main::test_it\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_static_view_here_no_utility_registered\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_static_view_package_here_relative\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_custom_predicate_bests_standard_predicate\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_custom_predicates_match\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_custom_predicates_nomatch\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_template_renderer\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_template_renderer_no_callable\nFAILED r2e_tests/test_1.py::TestViewDeriver::test_as_instance_requestonly - A...\nFAILED r2e_tests/test_1.py::TestViewDeriver::test_function_returns_non_adaptable\nFAILED r2e_tests/test_1.py::TestViewDeriver::test_function_returns_non_adaptable_dict\nFAILED r2e_tests/test_1.py::TestViewDeriver::test_instance_returns_non_adaptable\nFAILED r2e_tests/test_1.py::TestViewDeriver::test_requestonly_default_method_returns_non_adaptable\nFAILED r2e_tests/test_1.py::TestViewDeriver::test_requestonly_nondefault_method_returns_non_adaptable\nFAILED r2e_tests/test_1.py::Test_view_description::test_without_text - Assert...\nFAILED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_resource_url_adapter_dotted_names\nFAILED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_resource_url_adapter_introspectables\nFAILED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_traverser_dotted_names\nFAILED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_filename_no_overrides\nFAILED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_filename_override_returns_None\nFAILED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_filename\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_abspath\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_asset_spec\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_asset_spec_existing_translation_dirs\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_multiple_specs\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_multiple_specs_multiple_calls\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_no_registry\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_noreg_debug_logger_None_default\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_scan_integration_conflict\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_debug_logger_None_default\nFAILED r2e_tests/test_config/test_init.py::TestConfigurator_add_directive::test_add_directive_with_custom_callable\nFAILED r2e_tests/test_config/test_init.py::TestConfigurator_add_directive::test_add_directive_with_partial\nFAILED r2e_tests/test_config/test_init.py::TestConfigurator_add_directive::test_extend_with_dotted_name\nFAILED r2e_tests/test_config/test_init.py::TestConfigurator_add_directive::test_extend_with_python_callable\nFAILED r2e_tests/test_config/test_init.py::TestConfigurator__add_predicate::test_factory_as_dotted_name\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_static_view_package_here_relative\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_custom_predicate_bests_standard_predicate\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_custom_predicates_match\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_custom_predicates_nomatch\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_template_renderer\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_template_renderer_no_callable\nFAILED r2e_tests/test_config/test_views.py::TestViewDeriver::test_function_returns_non_adaptable\nFAILED r2e_tests/test_config/test_views.py::TestViewDeriver::test_function_returns_non_adaptable_dict\nFAILED r2e_tests/test_config/test_views.py::TestViewDeriver::test_instance_returns_non_adaptable\nFAILED r2e_tests/test_config/test_views.py::TestViewDeriver::test_requestonly_default_method_returns_non_adaptable\nFAILED r2e_tests/test_config/test_views.py::TestViewDeriver::test_requestonly_nondefault_method_returns_non_adaptable\nFAILED r2e_tests/test_config/test_views.py::Test_view_description::test_without_text\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_display_headers\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_has_content_type_header_var\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_has_good_header_var\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_has_multiple_header_vars\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_get\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_options\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_patch\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_post\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_propfind\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_put\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_path_doesnt_start_with_slash\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_two_args\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_w_basic_auth\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_with_query_string\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_function_traversal\n======================= 61 failed, 1050 passed in 7.39s ========================\n",
    "new_commit_res_stderr": "",
    "old_commit_res_code": 1,
    "old_commit_res_stdout": "============================= test session starts ==============================\nplatform linux -- Python 3.8.20, pytest-8.3.4, pluggy-1.5.0\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1\ncollected 1111 items\n\nr2e_tests/test_1.py ........F.........F.FF............F................. [  4%]\n..................FF......................................FF............ [ 11%]\n..........................................F..................FF......... [ 17%]\nF...F....F..........................................................F    [ 23%]\nr2e_tests/test_config/test_adapters.py .FF..............F...             [ 25%]\nr2e_tests/test_config/test_assets.py ...........FF...................... [ 28%]\n.....F..........................                                         [ 31%]\nr2e_tests/test_config/test_factories.py ..................               [ 33%]\nr2e_tests/test_config/test_i18n.py FFF.FF...                             [ 34%]\nr2e_tests/test_config/test_init.py ..................................... [ 37%]\n.F..F....................F...........F....................FF...FFF...... [ 44%]\n..............                                                           [ 45%]\nr2e_tests/test_config/test_predicates.py ............................... [ 48%]\n........................................                                 [ 51%]\nr2e_tests/test_config/test_rendering.py ...                              [ 51%]\nr2e_tests/test_config/test_routes.py ........................            [ 54%]\nr2e_tests/test_config/test_security.py ..........                        [ 54%]\nr2e_tests/test_config/test_settings.py .......................           [ 57%]\nr2e_tests/test_config/test_testing.py ............                       [ 58%]\nr2e_tests/test_config/test_tweens.py .................................   [ 61%]\nr2e_tests/test_config/test_util.py ..................................... [ 64%]\n.............                                                            [ 65%]\nr2e_tests/test_config/test_views.py ........F.........F..F............F. [ 68%]\n..................................FF.................................... [ 75%]\n..FF.................................................................... [ 81%]\n.....FF.........F...F....F.............................................. [ 88%]\n............F                                                            [ 89%]\nr2e_tests/test_scripts/test_common.py ...                                [ 89%]\nr2e_tests/test_scripts/test_pcreate.py ..........                        [ 90%]\nr2e_tests/test_scripts/test_pdistreport.py ..                            [ 90%]\nr2e_tests/test_scripts/test_prequest.py F.FFFFFFFFF.F.FFF.               [ 92%]\nr2e_tests/test_scripts/test_proutes.py ...........                       [ 93%]\nr2e_tests/test_scripts/test_pserve.py ............................       [ 95%]\nr2e_tests/test_scripts/test_pshell.py .................                  [ 97%]\nr2e_tests/test_scripts/test_ptweens.py .....                             [ 97%]\nr2e_tests/test_scripts/test_pviews.py ................F......            [100%]\n\n=================================== FAILURES ===================================\n____ TestViewsConfigurationMixin.test_add_forbidden_view_with_view_defaults ____\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_forbidden_view_with_view_defaults>\n\n    def test_add_forbidden_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPForbidden\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_forbidden_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPForbidden),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n>       self.assertRaises(PredicateMismatch, wrapper, context, request)\nE       AssertionError: PredicateMismatch not raised by view\n\nr2e_tests/test_1.py:1846: AssertionError\n____ TestViewsConfigurationMixin.test_add_notfound_view_with_view_defaults _____\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_notfound_view_with_view_defaults>\n\n    def test_add_notfound_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPNotFound\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_notfound_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPNotFound),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n>       self.assertRaises(PredicateMismatch, wrapper, context, request)\nE       AssertionError: PredicateMismatch not raised by view\n\nr2e_tests/test_1.py:1943: AssertionError\n_ TestViewsConfigurationMixin.test_add_static_view_here_no_utility_registered __\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_static_view_here_no_utility_registered>\n\n    def test_add_static_view_here_no_utility_registered(self):\n        from pyramid.renderers import null_renderer\n        from zope.interface import Interface\n        from pyramid.interfaces import IView\n        from pyramid.interfaces import IViewClassifier\n        config = self._makeOne(autocommit=True)\n        config.add_static_view('static', 'files', renderer=null_renderer)\n        request_type = self._getRouteRequestIface(config, '__static/')\n        self._assertRoute(config, '__static/', 'static/*subpath')\n        wrapped = config.registry.adapters.lookup(\n            (IViewClassifier, request_type, Interface), IView, name='')\n        from pyramid.request import Request\n        request = Request.blank('/static/minimal.txt')\n        request.subpath = ('minimal.txt', )\n>       result = wrapped(None, request)\n\nr2e_tests/test_1.py:1734: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <pyramid.static.static_view object at 0x774f3abec040>, context = None\nrequest = <Request at 0x774f3abec4c0 GET http://localhost/static/minimal.txt>\n\n    def __call__(self, context, request):\n        if self.use_subpath:\n            path_tuple = request.subpath\n        else:\n            path_tuple = traversal_path_info(request.environ['PATH_INFO'])\n    \n        path = _secure_path(path_tuple)\n    \n        if path is None:\n            raise HTTPNotFound('Out of bounds: %s' % request.url)\n    \n        if self.package_name: # package resource\n    \n            resource_path ='%s/%s' % (self.docroot.rstrip('/'), path)\n            if resource_isdir(self.package_name, resource_path):\n                if not request.path_url.endswith('/'):\n                    self.add_slash_redirect(request)\n                resource_path = '%s/%s' % (resource_path.rstrip('/'),self.index)\n            if not resource_exists(self.package_name, resource_path):\n>               raise HTTPNotFound(request.url)\nE               pyramid.httpexceptions.HTTPNotFound: http://localhost/static/minimal.txt\n\npyramid/static.py:114: HTTPNotFound\n____ TestViewsConfigurationMixin.test_add_static_view_package_here_relative ____\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_static_view_package_here_relative>\n\n    def test_add_static_view_package_here_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static', 'files')\n>       self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\nE       AssertionError: Lists differ: [(<py[39 chars]74f3b121040>, 'static', 'r2e_tests:files', {})] != [(<py[39 chars]74f3b121040>, 'static', 'pyramid.tests.test_config:files', {})]\nE       \nE       First differing element 0:\nE       (<pyr[37 chars]774f3b121040>, 'static', 'r2e_tests:files', {})\nE       (<pyr[37 chars]774f3b121040>, 'static', 'pyramid.tests.test_config:files', {})\nE       \nE         [(<pyramid.config.Configurator object at 0x774f3b121040>,\nE           'static',\nE       -   'r2e_tests:files',\nE       +   'pyramid.tests.test_config:files',\nE           {})]\n\nr2e_tests/test_1.py:1755: AssertionError\n_ TestViewsConfigurationMixin.test_add_view_custom_predicate_bests_standard_predicate _\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_view_custom_predicate_bests_standard_predicate>\n\n    def test_add_view_custom_predicate_bests_standard_predicate(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=(pred1,),\n                        renderer=null_renderer)\n            config.add_view(view=view2, request_method='GET',\n                            renderer=null_renderer)\n>           self.assertEqual(len(w), 1)\nE           AssertionError: 3 != 1\n\nr2e_tests/test_1.py:1471: AssertionError\n____ TestViewsConfigurationMixin.test_add_view_with_custom_predicates_match ____\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_view_with_custom_predicates_match>\n\n    def test_add_view_with_custom_predicates_match(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return True\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates,\n                            renderer=null_renderer)\n>           self.assertEqual(len(w), 1)\nE           AssertionError: 2 != 1\n\nr2e_tests/test_1.py:1435: AssertionError\n___ TestViewsConfigurationMixin.test_add_view_with_custom_predicates_nomatch ___\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_view_with_custom_predicates_nomatch>\n\n    def test_add_view_with_custom_predicates_nomatch(self):\n        import warnings\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return False\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates)\n>           self.assertEqual(len(w), 1)\nE           AssertionError: 2 != 1\n\nr2e_tests/test_1.py:1452: AssertionError\n_______ TestViewsConfigurationMixin.test_add_view_with_template_renderer _______\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_view_with_template_renderer>\n\n    def test_add_view_with_template_renderer(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n    \n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=view, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n>       self.assertEqual(result.package, test_config)\nE       AssertionError: <module 'r2e_tests' from '/home/gcpuser/buckets/lo[93 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_1.py:1070: AssertionError\n_ TestViewsConfigurationMixin.test_add_view_with_template_renderer_no_callable _\n\nself = <r2e_tests.test_1.TestViewsConfigurationMixin testMethod=test_add_view_with_template_renderer_no_callable>\n\n    def test_add_view_with_template_renderer_no_callable(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=None, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n>       self.assertEqual(result.package, test_config)\nE       AssertionError: <module 'r2e_tests' from '/home/gcpuser/buckets/lo[93 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_1.py:1111: AssertionError\n_________________ TestViewDeriver.test_as_instance_requestonly _________________\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_as_instance_requestonly>\n\n    def test_as_instance_requestonly(self):\n        response = DummyResponse()\n        class View:\n            def __call__(self, request):\n                return response\n        view = View()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        self.assertEqual(view.__module__, result.__module__)\n        self.assertEqual(view.__doc__, result.__doc__)\n>       self.assertTrue('test_views' in result.__name__)\nE       AssertionError: False is not true\n\nr2e_tests/test_1.py:2699: AssertionError\n_____________ TestViewDeriver.test_function_returns_non_adaptable ______________\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_function_returns_non_adaptable>\n\n    def test_function_returns_non_adaptable(self):\n        def view(request):\n            return None\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n>           result(None, None)\n\nr2e_tests/test_1.py:2366: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None, request = None\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable function r2e_tests.test_1.view into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_function_returns_non_adaptable>\n\n    def test_function_returns_non_adaptable(self):\n        def view(request):\n            return None\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable function '\n                'pyramid.tests.test_config.test_views.view into a response '\n                'object. The value returned was None. You may have forgotten '\n                'to return a value from the view callable.'\n                )\nE           AssertionError: 'Coul[52 chars]tion r2e_tests.test_1.view into a response obj[94 chars]ble.' != 'Coul[52 chars]tion pyramid.tests.test_config.test_views.view[114 chars]ble.'\nE           - Could not convert return value of the view callable function r2e_tests.test_1.view into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\nE           ?                                                              ^^^ ^^^^^      ^^^^^^^^^^^^^\nE           + Could not convert return value of the view callable function pyramid.tests.test_config.test_views.view into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\nE           ?                                                              ^^^^^^^^^^^^^^^^^^ ^^^^^^      ^^^^^^^^^^^^^^^^^\n\nr2e_tests/test_1.py:2368: AssertionError\n___________ TestViewDeriver.test_function_returns_non_adaptable_dict ___________\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_function_returns_non_adaptable_dict>\n\n    def test_function_returns_non_adaptable_dict(self):\n        def view(request):\n            return {'a':1}\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n>           result(None, None)\n\nr2e_tests/test_1.py:2385: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None, request = None\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable function r2e_tests.test_1.view into a response object. The value returned was {'a': 1}. You may have forgotten to define a renderer in the view configuration.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_function_returns_non_adaptable_dict>\n\n    def test_function_returns_non_adaptable_dict(self):\n        def view(request):\n            return {'a':1}\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                \"Could not convert return value of the view callable function \"\n                \"pyramid.tests.test_config.test_views.view into a response \"\n                \"object. The value returned was {'a': 1}. You may have \"\n                \"forgotten to define a renderer in the view configuration.\"\n                )\nE           AssertionError: \"Coul[52 chars]tion r2e_tests.test_1.view into a response obj[104 chars]ion.\" != \"Coul[52 chars]tion pyramid.tests.test_config.test_views.view[124 chars]ion.\"\nE           Diff is 651 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_1.py:2387: AssertionError\n_____________ TestViewDeriver.test_instance_returns_non_adaptable ______________\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_instance_returns_non_adaptable>\n\n    def test_instance_returns_non_adaptable(self):\n        class AView(object):\n            def __call__(self, request):\n                return None\n        view = AView()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n>           result(None, None)\n\nr2e_tests/test_1.py:2406: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None, request = None\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable object <r2e_tests.test_1.TestViewDeriver.test_instance_returns_non_adaptable.<locals>.AView object at 0x774f3ad51940> into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_instance_returns_non_adaptable>\n\n    def test_instance_returns_non_adaptable(self):\n        class AView(object):\n            def __call__(self, request):\n                return None\n        view = AView()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n            msg = e.args[0]\n>           self.assertTrue(msg.startswith(\n                'Could not convert return value of the view callable object '\n                '<pyramid.tests.test_config.test_views.'))\nE           AssertionError: False is not true\n\nr2e_tests/test_1.py:2409: AssertionError\n____ TestViewDeriver.test_requestonly_default_method_returns_non_adaptable _____\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_requestonly_default_method_returns_non_adaptable>\n\n    def test_requestonly_default_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return None\n        deriver = self._makeOne()\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n>           result(None, request)\n\nr2e_tests/test_1.py:2452: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None\nrequest = <r2e_tests.test_1.DummyRequest object at 0x774f3adfe8b0>\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable method __call__ of class r2e_tests.test_1.AView into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_requestonly_default_method_returns_non_adaptable>\n\n    def test_requestonly_default_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return None\n        deriver = self._makeOne()\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n            result(None, request)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable '\n                'method __call__ of '\n                'class pyramid.tests.test_config.test_views.AView into a '\n                'response object. The value returned was None. You may have '\n                'forgotten to return a value from the view callable.'\n                )\nE           AssertionError: 'Coul[68 chars]lass r2e_tests.test_1.AView into a response ob[95 chars]ble.' != 'Coul[68 chars]lass pyramid.tests.test_config.test_views.AVie[115 chars]ble.'\nE           Diff is 673 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_1.py:2454: AssertionError\n___ TestViewDeriver.test_requestonly_nondefault_method_returns_non_adaptable ___\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_requestonly_nondefault_method_returns_non_adaptable>\n\n    def test_requestonly_nondefault_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def theviewmethod(self):\n                return None\n        deriver = self._makeOne(attr='theviewmethod')\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n>           result(None, request)\n\nr2e_tests/test_1.py:2476: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None\nrequest = <r2e_tests.test_1.DummyRequest object at 0x774f3ac049d0>\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable method theviewmethod of class r2e_tests.test_1.AView into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_1.TestViewDeriver testMethod=test_requestonly_nondefault_method_returns_non_adaptable>\n\n    def test_requestonly_nondefault_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def theviewmethod(self):\n                return None\n        deriver = self._makeOne(attr='theviewmethod')\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n            result(None, request)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable '\n                'method theviewmethod of '\n                'class pyramid.tests.test_config.test_views.AView into a '\n                'response object. The value returned was None. You may have '\n                'forgotten to return a value from the view callable.'\n                )\nE           AssertionError: 'Coul[73 chars]lass r2e_tests.test_1.AView into a response ob[95 chars]ble.' != 'Coul[73 chars]lass pyramid.tests.test_config.test_views.AVie[115 chars]ble.'\nE           Diff is 693 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_1.py:2478: AssertionError\n___________________ Test_view_description.test_without_text ____________________\n\nself = <r2e_tests.test_1.Test_view_description testMethod=test_without_text>\n\n    def test_without_text(self):\n        def view(): pass\n        result = self._callFUT(view)\n>       self.assertEqual(result,\n                         'function pyramid.tests.test_config.test_views.view')\nE       AssertionError: 'function r2e_tests.test_1.view' != 'function pyramid.tests.test_config.test_views.view'\nE       - function r2e_tests.test_1.view\nE       + function pyramid.tests.test_config.test_views.view\n\nr2e_tests/test_1.py:3916: AssertionError\n__ AdaptersConfiguratorMixinTests.test_add_resource_url_adapter_dotted_names ___\n\nself = <r2e_tests.test_config.test_adapters.AdaptersConfiguratorMixinTests testMethod=test_add_resource_url_adapter_dotted_names>\n\n    def test_add_resource_url_adapter_dotted_names(self):\n        from pyramid.interfaces import IResourceURL\n        config = self._makeOne(autocommit=True)\n        config.add_resource_url_adapter(\n            'pyramid.tests.test_config.test_adapters.DummyResourceURL',\n            'pyramid.tests.test_config.test_adapters.DummyIface',\n            )\n        iface = DummyIface()\n>       adapter = config.registry.getMultiAdapter((iface, iface),\n                                                    IResourceURL)\n\nr2e_tests/test_config/test_adapters.py:280: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <Registry r2e_tests.test_config>\nobjects = (<r2e_tests.test_config.test_adapters.DummyIface object at 0x774f3ac09760>, <r2e_tests.test_config.test_adapters.DummyIface object at 0x774f3ac09760>)\ninterface = <InterfaceClass pyramid.interfaces.IResourceURL>, name = ''\n\n    def getMultiAdapter(self, objects, interface, name=''):\n        adapter = self.adapters.queryMultiAdapter(objects, interface, name)\n        if adapter is None:\n>           raise ComponentLookupError(objects, interface, name)\nE           zope.interface.interfaces.ComponentLookupError: ((<r2e_tests.test_config.test_adapters.DummyIface object at 0x774f3ac09760>, <r2e_tests.test_config.test_adapters.DummyIface object at 0x774f3ac09760>), <InterfaceClass pyramid.interfaces.IResourceURL>, '')\n\n.venv/lib/python3.8/site-packages/zope/interface/registry.py:379: ComponentLookupError\n_ AdaptersConfiguratorMixinTests.test_add_resource_url_adapter_introspectables _\n\nself = <r2e_tests.test_config.test_adapters.AdaptersConfiguratorMixinTests testMethod=test_add_resource_url_adapter_introspectables>\n\n    def test_add_resource_url_adapter_introspectables(self):\n        config = self._makeOne()\n        config.add_resource_url_adapter(DummyResourceURL, DummyIface)\n        actions = config.action_state.actions\n        self.assertEqual(len(actions), 1)\n        intrs  = actions[0]['introspectables']\n        self.assertEqual(len(intrs), 1)\n        intr = intrs[0]\n        self.assertEqual(intr.type_name, 'resource url adapter')\n        self.assertEqual(intr.discriminator,\n                         ('resource url adapter', DummyIface))\n        self.assertEqual(intr.category_name, 'resource url adapters')\n>       self.assertEqual(\n            intr.title,\n            \"resource url adapter for resource iface \"\n            \"<class 'pyramid.tests.test_config.test_adapters.DummyIface'>\"\n            )\nE       AssertionError: \"reso[34 chars]e <class 'r2e_tests.test_config.test_adapters.DummyIface'>\" != \"reso[34 chars]e <class 'pyramid.tests.test_config.test_adapters.DummyIface'>\"\nE       - resource url adapter for resource iface <class 'r2e_tests.test_config.test_adapters.DummyIface'>\nE       ?                                                  ^^^\nE       + resource url adapter for resource iface <class 'pyramid.tests.test_config.test_adapters.DummyIface'>\nE       ?                                                 ++ ^^^^^\n\nr2e_tests/test_config/test_adapters.py:326: AssertionError\n________ AdaptersConfiguratorMixinTests.test_add_traverser_dotted_names ________\n\nself = <r2e_tests.test_config.test_adapters.AdaptersConfiguratorMixinTests testMethod=test_add_traverser_dotted_names>\n\n    def test_add_traverser_dotted_names(self):\n        from pyramid.interfaces import ITraverser\n        config = self._makeOne(autocommit=True)\n        config.add_traverser(\n            'pyramid.tests.test_config.test_adapters.DummyTraverser',\n            'pyramid.tests.test_config.test_adapters.DummyIface')\n        iface = DummyIface()\n>       traverser = config.registry.getAdapter(iface, ITraverser)\n\nr2e_tests/test_config/test_adapters.py:237: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <Registry r2e_tests.test_config>\nobject = <r2e_tests.test_config.test_adapters.DummyIface object at 0x774f3b001ac0>\ninterface = <InterfaceClass pyramid.interfaces.ITraverser>, name = ''\n\n    def getAdapter(self, object, interface, name=''):\n        adapter = self.adapters.queryAdapter(object, interface, name)\n        if adapter is None:\n>           raise ComponentLookupError(object, interface, name)\nE           zope.interface.interfaces.ComponentLookupError: (<r2e_tests.test_config.test_adapters.DummyIface object at 0x774f3b001ac0>, <InterfaceClass pyramid.interfaces.ITraverser>, '')\n\n.venv/lib/python3.8/site-packages/zope/interface/registry.py:368: ComponentLookupError\n_________ TestOverrideProvider.test_get_resource_filename_no_overrides _________\n\nself = <r2e_tests.test_config.test_assets.TestOverrideProvider testMethod=test_get_resource_filename_no_overrides>\n\n    def test_get_resource_filename_no_overrides(self):\n        import os\n        resource_name = 'test_assets.py'\n        import pyramid.tests.test_config\n        provider = self._makeOne(pyramid.tests.test_config)\n        here = os.path.dirname(os.path.abspath(__file__))\n        expected = os.path.join(here, resource_name)\n        result = provider.get_resource_filename(None, resource_name)\n>       self.assertEqual(result, expected)\nE       AssertionError: '/hom[73 chars]14ddd61de089fe1f073d1/pyramid/tests/test_config/test_assets.py' != '/hom[73 chars]14ddd61de089fe1f073d1/r2e_tests/test_config/test_assets.py'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/test_config/test_assets.py\nE       ?                                                                                                    -- ^^^^^\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/test_config/test_assets.py\nE       ?                                                                                                     ^^^\n\nr2e_tests/test_config/test_assets.py:158: AssertionError\n____ TestOverrideProvider.test_get_resource_filename_override_returns_None _____\n\nself = <r2e_tests.test_config.test_assets.TestOverrideProvider testMethod=test_get_resource_filename_override_returns_None>\n\n    def test_get_resource_filename_override_returns_None(self):\n        overrides = DummyOverrides(None)\n        self._registerOverrides(overrides)\n        import os\n        resource_name = 'test_assets.py'\n        import pyramid.tests.test_config\n        provider = self._makeOne(pyramid.tests.test_config)\n        here = os.path.dirname(os.path.abspath(__file__))\n        expected = os.path.join(here, resource_name)\n        result = provider.get_resource_filename(None, resource_name)\n>       self.assertEqual(result, expected)\nE       AssertionError: '/hom[73 chars]14ddd61de089fe1f073d1/pyramid/tests/test_config/test_assets.py' != '/hom[73 chars]14ddd61de089fe1f073d1/r2e_tests/test_config/test_assets.py'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/test_config/test_assets.py\nE       ?                                                                                                    -- ^^^^^\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/test_config/test_assets.py\nE       ?                                                                                                     ^^^\n\nr2e_tests/test_config/test_assets.py:212: AssertionError\n____________________ TestPackageOverrides.test_get_filename ____________________\n\nself = <r2e_tests.test_config.test_assets.TestPackageOverrides testMethod=test_get_filename>\n\n    def test_get_filename(self):\n        import os\n        overrides = [ DummyOverride(None), DummyOverride(\n            ('pyramid.tests.test_config', 'test_assets.py'))]\n        package = DummyPackage('package')\n        po = self._makeOne(package)\n        po.overrides= overrides\n        here = os.path.dirname(os.path.abspath(__file__))\n        expected = os.path.join(here, 'test_assets.py')\n>       self.assertEqual(po.get_filename('whatever'), expected)\nE       AssertionError: '/hom[73 chars]14ddd61de089fe1f073d1/pyramid/tests/test_config/test_assets.py' != '/hom[73 chars]14ddd61de089fe1f073d1/r2e_tests/test_config/test_assets.py'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/test_config/test_assets.py\nE       ?                                                                                                    -- ^^^^^\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/test_config/test_assets.py\nE       ?                                                                                                     ^^^\n\nr2e_tests/test_config/test_assets.py:425: AssertionError\n_________ TestI18NConfiguratorMixin.test_add_translation_dirs_abspath __________\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_abspath>\n\n    def test_add_translation_dirs_abspath(self):\n        from pyramid.interfaces import ITranslationDirectories\n        config = self._makeOne(autocommit=True)\n>       config.add_translation_dirs(locale)\n\nr2e_tests/test_config/test_i18n.py:86: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \npyramid/util.py:507: in wrapper\n    result = wrapped(self, *arg, **kw)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <pyramid.config.Configurator object at 0x774f3b6e2a90>\nspecs = ('/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale',)\nintrospectables = []\nspec = '/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale'\npackage_name = None\n\n    @action_method\n    def add_translation_dirs(self, *specs):\n        \"\"\" Add one or more :term:`translation directory` paths to the\n        current configuration state.  The ``specs`` argument is a\n        sequence that may contain absolute directory paths\n        (e.g. ``/usr/share/locale``) or :term:`asset specification`\n        names naming a directory path (e.g. ``some.package:locale``)\n        or a combination of the two.\n    \n        Example:\n    \n        .. code-block:: python\n    \n           config.add_translation_dirs('/usr/share/locale',\n                                       'some.package:locale')\n    \n        Later calls to ``add_translation_dir`` insert directories into the\n        beginning of the list of translation directories created by earlier\n        calls.  This means that the same translation found in a directory\n        added later in the configuration process will be found before one\n        added earlier in the configuration process.  However, if multiple\n        specs are provided in a single call to ``add_translation_dirs``, the\n        directories will be inserted into the beginning of the directory list\n        in the order they're provided in the ``*specs`` list argument (items\n        earlier in the list trump ones later in the list).\n        \"\"\"\n        directories = []\n        introspectables = []\n    \n        for spec in specs[::-1]: # reversed\n            package_name, filename = self._split_spec(spec)\n            if package_name is None: # absolute filename\n                directory = filename\n            else:\n                __import__(package_name)\n                package = sys.modules[package_name]\n                directory = os.path.join(package_path(package), filename)\n    \n            if not os.path.isdir(os.path.realpath(directory)):\n>               raise ConfigurationError('\"%s\" is not a directory' %\n                                         directory)\nE               pyramid.exceptions.ConfigurationError: \"/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale\" is not a directory\n\npyramid/config/i18n.py:86: ConfigurationError\n________ TestI18NConfiguratorMixin.test_add_translation_dirs_asset_spec ________\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_asset_spec>\n\n    def test_add_translation_dirs_asset_spec(self):\n        from pyramid.interfaces import ITranslationDirectories\n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale')\n>       self.assertEqual(config.registry.getUtility(ITranslationDirectories),\n                         [locale])\nE       AssertionError: Lists differ: ['/ho[70 chars]cd9414ddd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale'] != ['/ho[70 chars]cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale']\nE       \nE       First differing element 0:\nE       '/hom[68 chars]5cd9414ddd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale'\nE       '/hom[68 chars]5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale'\nE       \nE       - ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale']\nE       ?                                                                                                      -- ^^^^^\nE       \nE       + ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale']\nE       ?                                                                                                       ^^^\n\nr2e_tests/test_config/test_i18n.py:54: AssertionError\n_ TestI18NConfiguratorMixin.test_add_translation_dirs_asset_spec_existing_translation_dirs _\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_asset_spec_existing_translation_dirs>\n\n    def test_add_translation_dirs_asset_spec_existing_translation_dirs(self):\n        from pyramid.interfaces import ITranslationDirectories\n        config = self._makeOne(autocommit=True)\n        directories = ['abc']\n        config.registry.registerUtility(directories, ITranslationDirectories)\n        config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale')\n        result = config.registry.getUtility(ITranslationDirectories)\n>       self.assertEqual(result, [locale, 'abc'])\nE       AssertionError: Lists differ: ['/ho[77 chars]dd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale', 'abc'] != ['/ho[77 chars]dd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale', 'abc']\nE       \nE       First differing element 0:\nE       '/hom[68 chars]5cd9414ddd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale'\nE       '/hom[68 chars]5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale'\nE       \nE       - ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale',\nE       ?                                                                                                      -- ^^^^^\nE       \nE       + ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale',\nE       ?                                                                                                       ^^^\nE       \nE          'abc']\n\nr2e_tests/test_config/test_i18n.py:64: AssertionError\n______ TestI18NConfiguratorMixin.test_add_translation_dirs_multiple_specs ______\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_multiple_specs>\n\n    def test_add_translation_dirs_multiple_specs(self):\n        from pyramid.interfaces import ITranslationDirectories\n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale',\n                                    'pyramid.tests.pkgs.localeapp:locale2')\n>       self.assertEqual(config.registry.getUtility(ITranslationDirectories),\n                         [locale, locale2])\nE       AssertionError: Lists differ: ['/ho[91 chars]73d1/pyramid/tests/pkgs/localeapp/locale', '/h[130 chars]le2'] != ['/ho[91 chars]73d1/r2e_tests/pkgs/localeapp/locale', '/home/[122 chars]le2']\nE       \nE       First differing element 0:\nE       '/hom[68 chars]5cd9414ddd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale'\nE       '/hom[68 chars]5cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale'\nE       \nE       Diff is 1002 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_i18n.py:71: AssertionError\n_ TestI18NConfiguratorMixin.test_add_translation_dirs_multiple_specs_multiple_calls _\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_multiple_specs_multiple_calls>\n\n    def test_add_translation_dirs_multiple_specs_multiple_calls(self):\n        from pyramid.interfaces import ITranslationDirectories\n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale',\n                                    'pyramid.tests.pkgs.localeapp:locale2')\n        config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale3')\n>       self.assertEqual(config.registry.getUtility(ITranslationDirectories),\n                         [locale3, locale, locale2])\nE       AssertionError: Lists differ: ['/ho[91 chars]73d1/pyramid/tests/pkgs/localeapp/locale3', '/[269 chars]le2'] != ['/ho[91 chars]73d1/r2e_tests/pkgs/localeapp/locale3', '/home[257 chars]le2']\nE       \nE       First differing element 0:\nE       '/hom[69 chars]cd9414ddd61de089fe1f073d1/pyramid/tests/pkgs/localeapp/locale3'\nE       '/hom[69 chars]cd9414ddd61de089fe1f073d1/r2e_tests/pkgs/localeapp/locale3'\nE       \nE       Diff is 1504 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_i18n.py:80: AssertionError\n___________________ ConfiguratorTests.test_ctor_no_registry ____________________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_ctor_no_registry>\n\n    def test_ctor_no_registry(self):\n        import sys\n        from pyramid.interfaces import ISettings\n        from pyramid.config import Configurator\n        from pyramid.interfaces import IRendererFactory\n        config = Configurator()\n        this_pkg = sys.modules['pyramid.tests.test_config']\n        self.assertTrue(config.registry.getUtility(ISettings))\n>       self.assertEqual(config.package, this_pkg)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_config/test_init.py:67: AssertionError\n_________ ConfiguratorTests.test_ctor_noreg_debug_logger_None_default __________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_ctor_noreg_debug_logger_None_default>\n\n    def test_ctor_noreg_debug_logger_None_default(self):\n        from pyramid.interfaces import IDebugLogger\n        config = self._makeOne()\n        logger = config.registry.getUtility(IDebugLogger)\n>       self.assertEqual(logger.name, 'pyramid.tests.test_config')\nE       AssertionError: 'r2e_tests.test_config' != 'pyramid.tests.test_config'\nE       - r2e_tests.test_config\nE       ?  ^^^\nE       + pyramid.tests.test_config\nE       ? ++ ^^^^^\n\nr2e_tests/test_config/test_init.py:123: AssertionError\n_______________ ConfiguratorTests.test_scan_integration_conflict _______________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_scan_integration_conflict>\n\n    def test_scan_integration_conflict(self):\n        from pyramid.tests.test_config.pkgs import selfscan\n        from pyramid.config import Configurator\n        c = Configurator()\n        c.scan(selfscan)\n        c.scan(selfscan)\n        try:\n>           c.commit()\n\nr2e_tests/test_config/test_init.py:999: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \npyramid/config/__init__.py:606: in commit\n    self.action_state.execute_actions(introspector=self.introspector)\npyramid/config/__init__.py:1044: in execute_actions\n    for action in resolveConflicts(self.actions):\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nactions = []\n\n    def resolveConflicts(actions):\n        \"\"\"Resolve conflicting actions\n    \n        Given an actions list, identify and try to resolve conflicting actions.\n        Actions conflict if they have the same non-None discriminator.\n        Conflicting actions can be resolved if the include path of one of\n        the actions is a prefix of the includepaths of the other\n        conflicting actions and is unequal to the include paths in the\n        other conflicting actions.\n        \"\"\"\n    \n        def orderandpos(v):\n            n, v = v\n            if not isinstance(v, dict):\n                # old-style tuple action\n                v = expand_action(*v)\n            return (v['order'] or 0, n)\n    \n        sactions = sorted(enumerate(actions), key=orderandpos)\n    \n        def orderonly(v):\n            n, v = v\n            if not isinstance(v, dict):\n                # old-style tuple action\n                v = expand_action(*v)\n            return v['order'] or 0\n    \n        for order, actiongroup in itertools.groupby(sactions, orderonly):\n            # \"order\" is an integer grouping. Actions in a lower order will be\n            # executed before actions in a higher order.  All of the actions in\n            # one grouping will be executed (its callable, if any will be called)\n            # before any of the actions in the next.\n    \n            unique = {}\n            output = []\n    \n            for i, action in actiongroup:\n                # Within an order, actions are executed sequentially based on\n                # original action ordering (\"i\").\n    \n                if not isinstance(action, dict):\n                    # old-style tuple action\n                    action = expand_action(*action)\n    \n                # \"ainfo\" is a tuple of (order, i, action) where \"order\" is a\n                # user-supplied grouping, \"i\" is an integer expressing the relative\n                # position of this action in the action list being resolved, and\n                # \"action\" is an action dictionary.  The purpose of an ainfo is to\n                # associate an \"order\" and an \"i\" with a particular action; \"order\"\n                # and \"i\" exist for sorting purposes after conflict resolution.\n                ainfo = (order, i, action)\n    \n                discriminator = undefer(action['discriminator'])\n                action['discriminator'] = discriminator\n    \n                if discriminator is None:\n                    # The discriminator is None, so this action can never conflict.\n                    # We can add it directly to the result.\n                    output.append(ainfo)\n                    continue\n    \n                L = unique.setdefault(discriminator, [])\n                L.append(ainfo)\n    \n            # Check for conflicts\n            conflicts = {}\n    \n            for discriminator, ainfos in unique.items():\n                # We use (includepath, order, i) as a sort key because we need to\n                # sort the actions by the paths so that the shortest path with a\n                # given prefix comes first.  The \"first\" action is the one with the\n                # shortest include path.  We break sorting ties using \"order\", then\n                # \"i\".\n                def bypath(ainfo):\n                    path, order, i = ainfo[2]['includepath'], ainfo[0], ainfo[1]\n                    return path, order, i\n    \n                ainfos.sort(key=bypath)\n                ainfo, rest = ainfos[0], ainfos[1:]\n                output.append(ainfo)\n                _, _, action = ainfo\n                basepath, baseinfo, discriminator = (\n                    action['includepath'],\n                    action['info'],\n                    action['discriminator'],\n                    )\n    \n                for _, _, action in rest:\n                    includepath = action['includepath']\n                    # Test whether path is a prefix of opath\n                    if (includepath[:len(basepath)] != basepath # not a prefix\n                        or includepath == basepath):\n                        L = conflicts.setdefault(discriminator, [baseinfo])\n                        L.append(action['info'])\n    \n            if conflicts:\n>               raise ConfigurationConflictError(conflicts)\nE               pyramid.exceptions.ConfigurationConflictError: Conflicting configuration actions\nE                 For: ('view', None, '', None, 'd41d8cd98f00b204e9800998ecf8427e')\nE                   Line 4 of file /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/test_config/pkgs/selfscan/__init__.py:\nE                       def abc(request):\nE                   Line 4 of file /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/test_config/pkgs/selfscan/__init__.py:\nE                       def abc(request):\nE                 For: ('view', None, 'two', None, 'd41d8cd98f00b204e9800998ecf8427e')\nE                   Line 4 of file /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/test_config/pkgs/selfscan/another.py:\nE                       def two(request):\nE                   Line 4 of file /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_7c96246eb6e14f5cd9414ddd61de089fe1f073d1/pyramid/tests/test_config/pkgs/selfscan/another.py:\nE                       def two(request):\n\npyramid/config/__init__.py:1172: ConfigurationConflictError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_scan_integration_conflict>\n\n    def test_scan_integration_conflict(self):\n        from pyramid.tests.test_config.pkgs import selfscan\n        from pyramid.config import Configurator\n        c = Configurator()\n        c.scan(selfscan)\n        c.scan(selfscan)\n        try:\n            c.commit()\n        except ConfigurationConflictError as why:\n            def scanconflicts(e):\n                conflicts = e._conflicts.values()\n                for conflict in conflicts:\n                    for confinst in conflict:\n                        yield confinst.src\n            which = list(scanconflicts(why))\n            self.assertEqual(len(which), 4)\n>           self.assertTrue(\"@view_config(renderer='string')\" in which)\nE           AssertionError: False is not true\n\nr2e_tests/test_config/test_init.py:1008: AssertionError\n_______ ConfiguratorTests.test_setup_registry_debug_logger_None_default ________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_setup_registry_debug_logger_None_default>\n\n    def test_setup_registry_debug_logger_None_default(self):\n        from pyramid.registry import Registry\n        from pyramid.interfaces import IDebugLogger\n        reg = Registry()\n        config = self._makeOne(reg)\n        config.setup_registry()\n        logger = reg.getUtility(IDebugLogger)\n>       self.assertEqual(logger.name, 'pyramid.tests.test_config')\nE       AssertionError: 'r2e_tests.test_config' != 'pyramid.tests.test_config'\nE       - r2e_tests.test_config\nE       ?  ^^^\nE       + pyramid.tests.test_config\nE       ? ++ ^^^^^\n\nr2e_tests/test_config/test_init.py:428: AssertionError\n____ TestConfigurator_add_directive.test_add_directive_with_custom_callable ____\n\nself = <r2e_tests.test_config.test_init.TestConfigurator_add_directive testMethod=test_add_directive_with_custom_callable>\n\n    def test_add_directive_with_custom_callable(self):\n        from pyramid.tests import test_config\n        config = self.config\n        config.add_directive(\n                'dummy_callable', 'pyramid.tests.test_config.dummy_callable')\n        self.assertTrue(hasattr(config, 'dummy_callable'))\n        config.dummy_callable('discrim')\n        after = config.action_state\n        action = after.actions[-1]\n        self.assertEqual(action['discriminator'], 'discrim')\n        self.assertEqual(action['callable'], None)\n>       self.assertEqual(action['args'], test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_config/test_init.py:1207: AssertionError\n________ TestConfigurator_add_directive.test_add_directive_with_partial ________\n\nself = <r2e_tests.test_config.test_init.TestConfigurator_add_directive testMethod=test_add_directive_with_partial>\n\n    def test_add_directive_with_partial(self):\n        from pyramid.tests import test_config\n        config = self.config\n        config.add_directive(\n                'dummy_partial', 'pyramid.tests.test_config.dummy_partial')\n        self.assertTrue(hasattr(config, 'dummy_partial'))\n        config.dummy_partial()\n        after = config.action_state\n        action = after.actions[-1]\n        self.assertEqual(action['discriminator'], 'partial')\n        self.assertEqual(action['callable'], None)\n>       self.assertEqual(action['args'], test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_config/test_init.py:1194: AssertionError\n_________ TestConfigurator_add_directive.test_extend_with_dotted_name __________\n\nself = <r2e_tests.test_config.test_init.TestConfigurator_add_directive testMethod=test_extend_with_dotted_name>\n\n    def test_extend_with_dotted_name(self):\n        from pyramid.tests import test_config\n        config = self.config\n        config.add_directive(\n            'dummy_extend', 'pyramid.tests.test_config.dummy_extend')\n        self.assertTrue(hasattr(config, 'dummy_extend'))\n        config.dummy_extend('discrim')\n        after = config.action_state\n        action = after.actions[-1]\n        self.assertEqual(action['discriminator'], 'discrim')\n        self.assertEqual(action['callable'], None)\n>       self.assertEqual(action['args'], test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_config/test_init.py:1181: AssertionError\n_______ TestConfigurator_add_directive.test_extend_with_python_callable ________\n\nself = <r2e_tests.test_config.test_init.TestConfigurator_add_directive testMethod=test_extend_with_python_callable>\n\n    def test_extend_with_python_callable(self):\n        from pyramid.tests import test_config\n        config = self.config\n        config.add_directive(\n            'dummy_extend', dummy_extend)\n        self.assertTrue(hasattr(config, 'dummy_extend'))\n        config.dummy_extend('discrim')\n        after = config.action_state\n        action = after.actions[-1]\n        self.assertEqual(action['discriminator'], 'discrim')\n        self.assertEqual(action['callable'], None)\n>       self.assertEqual(action['args'], test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_config/test_init.py:1220: AssertionError\n_________ TestConfigurator__add_predicate.test_factory_as_dotted_name __________\n\nself = <r2e_tests.test_config.test_init.TestConfigurator__add_predicate testMethod=test_factory_as_dotted_name>\n\n    def test_factory_as_dotted_name(self):\n        config = self._makeOne()\n    \n        def _fakeAction(discriminator, callable=None, args=(),\n                        kw=None, order=0, introspectables=(), **extra):\n            self.assertEqual(len(introspectables), 1)\n            self.assertEqual(introspectables[0]['name'], 'testing')\n            self.assertEqual(introspectables[0]['factory'], DummyPredicate)\n    \n        config.action = _fakeAction\n>       config._add_predicate(\n            'route',\n            'testing',\n            'pyramid.tests.test_config.test_init.DummyPredicate'\n            )\n\nr2e_tests/test_config/test_init.py:1284: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \npyramid/config/__init__.py:495: in _add_predicate\n    self.action(discriminator, register, introspectables=(intr,),\nr2e_tests/test_config/test_init.py:1281: in _fakeAction\n    self.assertEqual(introspectables[0]['factory'], DummyPredicate)\nE   AssertionError: <class 'pyramid.tests.test_config.test_init.DummyPredicate'> != <class 'r2e_tests.test_config.test_init.DummyPredicate'>\n____ TestViewsConfigurationMixin.test_add_forbidden_view_with_view_defaults ____\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_forbidden_view_with_view_defaults>\n\n    def test_add_forbidden_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPForbidden\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_forbidden_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPForbidden),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n>       self.assertRaises(PredicateMismatch, wrapper, context, request)\nE       AssertionError: PredicateMismatch not raised by view\n\nr2e_tests/test_config/test_views.py:1846: AssertionError\n____ TestViewsConfigurationMixin.test_add_notfound_view_with_view_defaults _____\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_notfound_view_with_view_defaults>\n\n    def test_add_notfound_view_with_view_defaults(self):\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPNotFound\n        from zope.interface import directlyProvides\n        from zope.interface import implementedBy\n        class view(object):\n            __view_defaults__ = {\n                'containment':'pyramid.tests.test_config.IDummy'\n                }\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_notfound_view(\n            view=view,\n            renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config, ctx_iface=implementedBy(HTTPNotFound),\n            request_iface=IRequest)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n        self.assertEqual(wrapper(context, request), 'OK')\n        context = DummyContext()\n        request = self._makeRequest(config)\n>       self.assertRaises(PredicateMismatch, wrapper, context, request)\nE       AssertionError: PredicateMismatch not raised by view\n\nr2e_tests/test_config/test_views.py:1943: AssertionError\n____ TestViewsConfigurationMixin.test_add_static_view_package_here_relative ____\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_static_view_package_here_relative>\n\n    def test_add_static_view_package_here_relative(self):\n        from pyramid.interfaces import IStaticURLInfo\n        info = DummyStaticURLInfo()\n        config = self._makeOne(autocommit=True)\n        config.registry.registerUtility(info, IStaticURLInfo)\n        config.add_static_view('static', 'files')\n>       self.assertEqual(\n            info.added,\n            [(config, 'static', 'pyramid.tests.test_config:files', {})])\nE       AssertionError: Lists differ: [(<py[39 chars]74f3b60dfd0>, 'static', 'r2e_tests.test_config:files', {})] != [(<py[39 chars]74f3b60dfd0>, 'static', 'pyramid.tests.test_config:files', {})]\nE       \nE       First differing element 0:\nE       (<pyr[37 chars]774f3b60dfd0>, 'static', 'r2e_tests.test_config:files', {})\nE       (<pyr[37 chars]774f3b60dfd0>, 'static', 'pyramid.tests.test_config:files', {})\nE       \nE         [(<pyramid.config.Configurator object at 0x774f3b60dfd0>,\nE           'static',\nE       -   'r2e_tests.test_config:files',\nE       ?     ^^^\nE       \nE       +   'pyramid.tests.test_config:files',\nE       ?    ++ ^^^^^\nE       \nE           {})]\n\nr2e_tests/test_config/test_views.py:1755: AssertionError\n_ TestViewsConfigurationMixin.test_add_view_custom_predicate_bests_standard_predicate _\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_custom_predicate_bests_standard_predicate>\n\n    def test_add_view_custom_predicate_bests_standard_predicate(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        view2 = lambda *arg: 'NOT OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=(pred1,),\n                        renderer=null_renderer)\n            config.add_view(view=view2, request_method='GET',\n                            renderer=null_renderer)\n>           self.assertEqual(len(w), 1)\nE           AssertionError: 3 != 1\n\nr2e_tests/test_config/test_views.py:1471: AssertionError\n____ TestViewsConfigurationMixin.test_add_view_with_custom_predicates_match ____\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_custom_predicates_match>\n\n    def test_add_view_with_custom_predicates_match(self):\n        import warnings\n        from pyramid.renderers import null_renderer\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return True\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates,\n                            renderer=null_renderer)\n>           self.assertEqual(len(w), 1)\nE           AssertionError: 2 != 1\n\nr2e_tests/test_config/test_views.py:1435: AssertionError\n___ TestViewsConfigurationMixin.test_add_view_with_custom_predicates_nomatch ___\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_custom_predicates_nomatch>\n\n    def test_add_view_with_custom_predicates_nomatch(self):\n        import warnings\n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        def pred1(context, request):\n            return True\n        def pred2(context, request):\n            return False\n        predicates = (pred1, pred2)\n        with warnings.catch_warnings(record=True) as w:\n            warnings.filterwarnings('always')\n            config.add_view(view=view, custom_predicates=predicates)\n>           self.assertEqual(len(w), 1)\nE           AssertionError: 2 != 1\n\nr2e_tests/test_config/test_views.py:1452: AssertionError\n_______ TestViewsConfigurationMixin.test_add_view_with_template_renderer _______\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_template_renderer>\n\n    def test_add_view_with_template_renderer(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        class view(object):\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n    \n            def __call__(self):\n                return {'a':'1'}\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=view, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n>       self.assertEqual(result.package, test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_config/test_views.py:1070: AssertionError\n_ TestViewsConfigurationMixin.test_add_view_with_template_renderer_no_callable _\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_template_renderer_no_callable>\n\n    def test_add_view_with_template_renderer_no_callable(self):\n        from pyramid.tests import test_config\n        from pyramid.interfaces import ISettings\n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = 'pyramid.tests.test_config:files/minimal.txt'\n        config.introspection = False\n        config.add_view(view=None, renderer=fixture)\n        wrapper = self._getViewCallable(config)\n        request = self._makeRequest(config)\n        result = wrapper(None, request)\n        self.assertEqual(result.body, b'Hello!')\n        settings = config.registry.queryUtility(ISettings)\n        result = renderer.info\n        self.assertEqual(result.registry, config.registry)\n        self.assertEqual(result.type, '.txt')\n>       self.assertEqual(result.package, test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'pyramid.tests.test_config' from '/home/gc[125 chars].py'>\n\nr2e_tests/test_config/test_views.py:1111: AssertionError\n_____________ TestViewDeriver.test_function_returns_non_adaptable ______________\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_function_returns_non_adaptable>\n\n    def test_function_returns_non_adaptable(self):\n        def view(request):\n            return None\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n>           result(None, None)\n\nr2e_tests/test_config/test_views.py:2366: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None, request = None\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable function r2e_tests.test_config.test_views.view into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_function_returns_non_adaptable>\n\n    def test_function_returns_non_adaptable(self):\n        def view(request):\n            return None\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable function '\n                'pyramid.tests.test_config.test_views.view into a response '\n                'object. The value returned was None. You may have forgotten '\n                'to return a value from the view callable.'\n                )\nE           AssertionError: 'Coul[52 chars]tion r2e_tests.test_config.test_views.view int[110 chars]ble.' != 'Coul[52 chars]tion pyramid.tests.test_config.test_views.view[114 chars]ble.'\nE           Diff is 663 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_views.py:2368: AssertionError\n___________ TestViewDeriver.test_function_returns_non_adaptable_dict ___________\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_function_returns_non_adaptable_dict>\n\n    def test_function_returns_non_adaptable_dict(self):\n        def view(request):\n            return {'a':1}\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n>           result(None, None)\n\nr2e_tests/test_config/test_views.py:2385: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None, request = None\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable function r2e_tests.test_config.test_views.view into a response object. The value returned was {'a': 1}. You may have forgotten to define a renderer in the view configuration.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_function_returns_non_adaptable_dict>\n\n    def test_function_returns_non_adaptable_dict(self):\n        def view(request):\n            return {'a':1}\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                \"Could not convert return value of the view callable function \"\n                \"pyramid.tests.test_config.test_views.view into a response \"\n                \"object. The value returned was {'a': 1}. You may have \"\n                \"forgotten to define a renderer in the view configuration.\"\n                )\nE           AssertionError: \"Coul[52 chars]tion r2e_tests.test_config.test_views.view int[120 chars]ion.\" != \"Coul[52 chars]tion pyramid.tests.test_config.test_views.view[124 chars]ion.\"\nE           Diff is 683 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_views.py:2387: AssertionError\n_____________ TestViewDeriver.test_instance_returns_non_adaptable ______________\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_instance_returns_non_adaptable>\n\n    def test_instance_returns_non_adaptable(self):\n        class AView(object):\n            def __call__(self, request):\n                return None\n        view = AView()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n>           result(None, None)\n\nr2e_tests/test_config/test_views.py:2406: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None, request = None\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable object <r2e_tests.test_config.test_views.TestViewDeriver.test_instance_returns_non_adaptable.<locals>.AView object at 0x774f3b52a820> into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_instance_returns_non_adaptable>\n\n    def test_instance_returns_non_adaptable(self):\n        class AView(object):\n            def __call__(self, request):\n                return None\n        view = AView()\n        deriver = self._makeOne()\n        result = deriver(view)\n        self.assertFalse(result is view)\n        try:\n            result(None, None)\n        except ValueError as e:\n            msg = e.args[0]\n>           self.assertTrue(msg.startswith(\n                'Could not convert return value of the view callable object '\n                '<pyramid.tests.test_config.test_views.'))\nE           AssertionError: False is not true\n\nr2e_tests/test_config/test_views.py:2409: AssertionError\n____ TestViewDeriver.test_requestonly_default_method_returns_non_adaptable _____\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_requestonly_default_method_returns_non_adaptable>\n\n    def test_requestonly_default_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return None\n        deriver = self._makeOne()\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n>           result(None, request)\n\nr2e_tests/test_config/test_views.py:2452: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x774f3a5f9070>\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable method __call__ of class r2e_tests.test_config.test_views.AView into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_requestonly_default_method_returns_non_adaptable>\n\n    def test_requestonly_default_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def __call__(self):\n                return None\n        deriver = self._makeOne()\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n            result(None, request)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable '\n                'method __call__ of '\n                'class pyramid.tests.test_config.test_views.AView into a '\n                'response object. The value returned was None. You may have '\n                'forgotten to return a value from the view callable.'\n                )\nE           AssertionError: 'Coul[68 chars]lass r2e_tests.test_config.test_views.AView in[111 chars]ble.' != 'Coul[68 chars]lass pyramid.tests.test_config.test_views.AVie[115 chars]ble.'\nE           Diff is 649 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_views.py:2454: AssertionError\n___ TestViewDeriver.test_requestonly_nondefault_method_returns_non_adaptable ___\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_requestonly_nondefault_method_returns_non_adaptable>\n\n    def test_requestonly_nondefault_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def theviewmethod(self):\n                return None\n        deriver = self._makeOne(attr='theviewmethod')\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n>           result(None, request)\n\nr2e_tests/test_config/test_views.py:2476: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = None\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x774f3ae75df0>\n\n    def viewresult_to_response(context, request):\n        result = view(context, request)\n        if result.__class__ is Response: # common case\n            response = result\n        else:\n            response = registry.queryAdapterOrSelf(result, IResponse)\n            if response is None:\n                if result is None:\n                    append = (' You may have forgotten to return a value '\n                              'from the view callable.')\n                elif isinstance(result, dict):\n                    append = (' You may have forgotten to define a '\n                              'renderer in the view configuration.')\n                else:\n                    append = ''\n    \n                msg = ('Could not convert return value of the view '\n                       'callable %s into a response object. '\n                       'The value returned was %r.' + append)\n    \n>               raise ValueError(msg % (view_description(view), result))\nE               ValueError: Could not convert return value of the view callable method theviewmethod of class r2e_tests.test_config.test_views.AView into a response object. The value returned was None. You may have forgotten to return a value from the view callable.\n\npyramid/config/views.py:397: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_config.test_views.TestViewDeriver testMethod=test_requestonly_nondefault_method_returns_non_adaptable>\n\n    def test_requestonly_nondefault_method_returns_non_adaptable(self):\n        request = DummyRequest()\n        class AView(object):\n            def __init__(self, request):\n                pass\n            def theviewmethod(self):\n                return None\n        deriver = self._makeOne(attr='theviewmethod')\n        result = deriver(AView)\n        self.assertFalse(result is AView)\n        try:\n            result(None, request)\n        except ValueError as e:\n>           self.assertEqual(\n                e.args[0],\n                'Could not convert return value of the view callable '\n                'method theviewmethod of '\n                'class pyramid.tests.test_config.test_views.AView into a '\n                'response object. The value returned was None. You may have '\n                'forgotten to return a value from the view callable.'\n                )\nE           AssertionError: 'Coul[73 chars]lass r2e_tests.test_config.test_views.AView in[111 chars]ble.' != 'Coul[73 chars]lass pyramid.tests.test_config.test_views.AVie[115 chars]ble.'\nE           Diff is 669 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_views.py:2478: AssertionError\n___________________ Test_view_description.test_without_text ____________________\n\nself = <r2e_tests.test_config.test_views.Test_view_description testMethod=test_without_text>\n\n    def test_without_text(self):\n        def view(): pass\n        result = self._callFUT(view)\n>       self.assertEqual(result,\n                         'function pyramid.tests.test_config.test_views.view')\nE       AssertionError: 'function r2e_tests.test_config.test_views.view' != 'function pyramid.tests.test_config.test_views.view'\nE       - function r2e_tests.test_config.test_views.view\nE       ?           ^^^\nE       + function pyramid.tests.test_config.test_views.view\nE       ?          ++ ^^^^^\n\nr2e_tests/test_config/test_views.py:3916: AssertionError\n_______________ TestPRequestCommand.test_command_display_headers _______________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_display_headers>\n\n    def test_command_display_headers(self):\n        command = self._makeOne(\n            ['', '--display-headers', 'development.ini', '/'])\n        command.run()\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(\n            self._out,\n            ['200 OK', 'Content-Type: text/html; charset=UTF-8', 'abc'])\nE       AssertionError: Lists differ: ['200 OK', b'abc'] != ['200 OK', 'Content-Type: text/html; charset=UTF-8', 'abc']\nE       \nE       First differing element 1:\nE       b'abc'\nE       'Content-Type: text/html; charset=UTF-8'\nE       \nE       Second list contains 1 additional elements.\nE       First extra element 2:\nE       'abc'\nE       \nE       - ['200 OK', b'abc']\nE       + ['200 OK', 'Content-Type: text/html; charset=UTF-8', 'abc']\n\nr2e_tests/test_scripts/test_prequest.py:202: AssertionError\n_________ TestPRequestCommand.test_command_has_content_type_header_var _________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_has_content_type_header_var>\n\n    def test_command_has_content_type_header_var(self):\n        command = self._makeOne(\n            ['', '--header=content-type:app/foo','development.ini', '/'])\n        command.run()\n        self.assertEqual(self._environ['CONTENT_TYPE'], 'app/foo')\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:92: AssertionError\n_____________ TestPRequestCommand.test_command_has_good_header_var _____________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_has_good_header_var>\n\n    def test_command_has_good_header_var(self):\n        command = self._makeOne(\n            ['', '--header=name:value','development.ini', '/'])\n        command.run()\n        self.assertEqual(self._environ['HTTP_NAME'], 'value')\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:69: AssertionError\n__________ TestPRequestCommand.test_command_has_multiple_header_vars ___________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_has_multiple_header_vars>\n\n    def test_command_has_multiple_header_vars(self):\n        command = self._makeOne(\n            ['',\n             '--header=name:value',\n             '--header=name2:value2',\n             'development.ini',\n             '/'])\n        command.run()\n        self.assertEqual(self._environ['HTTP_NAME'], 'value')\n        self.assertEqual(self._environ['HTTP_NAME2'], 'value2')\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:107: AssertionError\n_________________ TestPRequestCommand.test_command_method_get __________________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_method_get>\n\n    def test_command_method_get(self):\n        command = self._makeOne(['', '--method=GET', 'development.ini', '/'])\n        command.run()\n        self.assertEqual(self._environ['REQUEST_METHOD'], 'GET')\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:116: AssertionError\n_______________ TestPRequestCommand.test_command_method_options ________________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_method_options>\n\n    def test_command_method_options(self):\n        from pyramid.compat import NativeIO\n        command = self._makeOne(['', '--method=OPTIONS', 'development.ini',\n                                '/'])\n        stdin = NativeIO()\n        command.stdin = stdin\n        command.run()\n        self.assertEqual(self._environ['REQUEST_METHOD'], 'OPTIONS')\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:184: AssertionError\n________________ TestPRequestCommand.test_command_method_patch _________________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_method_patch>\n\n    def test_command_method_patch(self):\n        from pyramid.compat import NativeIO\n        command = self._makeOne(['', '--method=PATCH', 'development.ini', '/'])\n        stdin = NativeIO()\n        command.stdin = stdin\n        command.run()\n        self.assertEqual(self._environ['REQUEST_METHOD'], 'PATCH')\n        self.assertEqual(self._environ['CONTENT_LENGTH'], '-1')\n        self.assertEqual(self._environ['wsgi.input'], stdin)\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:158: AssertionError\n_________________ TestPRequestCommand.test_command_method_post _________________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_method_post>\n\n    def test_command_method_post(self):\n        from pyramid.compat import NativeIO\n        command = self._makeOne(['', '--method=POST', 'development.ini', '/'])\n        stdin = NativeIO()\n        command.stdin = stdin\n        command.run()\n        self.assertEqual(self._environ['REQUEST_METHOD'], 'POST')\n        self.assertEqual(self._environ['CONTENT_LENGTH'], '-1')\n        self.assertEqual(self._environ['wsgi.input'], stdin)\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:130: AssertionError\n_______________ TestPRequestCommand.test_command_method_propfind _______________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_method_propfind>\n\n    def test_command_method_propfind(self):\n        from pyramid.compat import NativeIO\n        command = self._makeOne(['', '--method=PROPFIND', 'development.ini',\n                                '/'])\n        stdin = NativeIO()\n        command.stdin = stdin\n        command.run()\n        self.assertEqual(self._environ['REQUEST_METHOD'], 'PROPFIND')\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:171: AssertionError\n_________________ TestPRequestCommand.test_command_method_put __________________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_method_put>\n\n    def test_command_method_put(self):\n        from pyramid.compat import NativeIO\n        command = self._makeOne(['', '--method=PUT', 'development.ini', '/'])\n        stdin = NativeIO()\n        command.stdin = stdin\n        command.run()\n        self.assertEqual(self._environ['REQUEST_METHOD'], 'PUT')\n        self.assertEqual(self._environ['CONTENT_LENGTH'], '-1')\n        self.assertEqual(self._environ['wsgi.input'], stdin)\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:144: AssertionError\n________ TestPRequestCommand.test_command_path_doesnt_start_with_slash _________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_path_doesnt_start_with_slash>\n\n    def test_command_path_doesnt_start_with_slash(self):\n        command = self._makeOne(['', 'development.ini', 'abc'])\n        command.run()\n        self.assertEqual(self._path_info, '/abc')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:50: AssertionError\n__________________ TestPRequestCommand.test_command_two_args ___________________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_two_args>\n\n    def test_command_two_args(self):\n        command = self._makeOne(['', 'development.ini', '/'])\n        command.run()\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:42: AssertionError\n________________ TestPRequestCommand.test_command_w_basic_auth _________________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_w_basic_auth>\n\n    def test_command_w_basic_auth(self):\n        command = self._makeOne(\n            ['', '--login=user:password',\n                 '--header=name:value','development.ini', '/'])\n        command.run()\n        self.assertEqual(self._environ['HTTP_NAME'], 'value')\n        self.assertEqual(self._environ['HTTP_AUTHORIZATION'],\n                        'Basic dXNlcjpwYXNzd29yZA==')\n        self.assertEqual(self._path_info, '/')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:82: AssertionError\n______________ TestPRequestCommand.test_command_with_query_string ______________\n\nself = <r2e_tests.test_scripts.test_prequest.TestPRequestCommand testMethod=test_command_with_query_string>\n\n    def test_command_with_query_string(self):\n        command = self._makeOne(['', 'development.ini', '/abc?a=1&b=2&c'])\n        command.run()\n        self.assertEqual(self._environ['QUERY_STRING'], 'a=1&b=2&c')\n        self.assertEqual(self._path_info, '/abc')\n        self.assertEqual(self._spec, 'development.ini')\n        self.assertEqual(self._app_name, None)\n>       self.assertEqual(self._out, ['abc'])\nE       AssertionError: Lists differ: [b'abc'] != ['abc']\nE       \nE       First differing element 0:\nE       b'abc'\nE       'abc'\nE       \nE       - [b'abc']\nE       ?  -\nE       \nE       + ['abc']\n\nr2e_tests/test_scripts/test_prequest.py:193: AssertionError\n_____ TestPViewsCommand.test_views_command_single_view_function_traversal ______\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_single_view_function_traversal>\n\n    def test_views_command_single_view_function_traversal(self):\n        from pyramid.registry import Registry\n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n        def view(): pass\n        view.__request_attrs__ = {'context': 'context', 'view_name': 'a'}\n        command._find_view = lambda arg1: view\n        command.args = ('/foo/bar/myapp.ini#myapp', '/a')\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(L[1], 'URL = /a')\n        self.assertEqual(L[3], '    context: context')\n        self.assertEqual(L[4], '    view name: a')\n>       self.assertEqual(L[8],\n                         '    pyramid.tests.test_scripts.test_pviews.view')\nE       AssertionError: '    r2e_tests.test_scripts.test_pviews.view' != '    pyramid.tests.test_scripts.test_pviews.view'\nE       -     r2e_tests.test_scripts.test_pviews.view\nE       ?      ^^^\nE       +     pyramid.tests.test_scripts.test_pviews.view\nE       ?     ++ ^^^^^\n\nr2e_tests/test_scripts/test_pviews.py:296: AssertionError\n==================================== PASSES ====================================\n=========================== short test summary info ============================\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_allows_other_predicates\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_context\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_for_\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_http_cache\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_name\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_permission\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_with_renderer\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_allows_other_predicates\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_append_slash\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_context\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_for_\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_http_cache\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_name\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_permission\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_with_renderer\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_static_view_absolute\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_static_view_package_relative\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_as_instance\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_as_instance_requestonly\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_as_instancemethod\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_as_instancemethod_requestonly\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_as_oldstyle_class\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_as_oldstyle_class_requestonly\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_context_as_class\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_context_as_dottedname\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_context_as_iface\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_context_trumps_for\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_custom_more_preds_first_bests_fewer_preds_last\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_default_phash_overrides_default_phash\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_default_phash_overrides_no_phash\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_default_phash_overrides_default_phash\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_default_phash_overrides_no_phash\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_multiview_replaces_existing_securedview\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_multiview_replaces_existing_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_multiview_replaces_multiview\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_mulview_replaces_existing_view_with___accept__\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_same_phash_overrides_existing_single_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exc_with_accept_multiview_replaces_existing_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_exception_register_secured_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_for__as_dottedname\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_for_as_class\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_for_as_iface\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_mixed_case_replaces_existing_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview___discriminator__\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview_call_ordering\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview_context_superclass_then_subclass\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview_exception_superclass_then_subclass\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_existing_securedview\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_existing_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_existing_view_with___accept__\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_multiview\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_register_secured_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_same_phash_overrides_existing_single_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_same_predicates\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_view_callable_None_no_renderer\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_view_callable_None_with_renderer\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_view_callable_dottedname\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_accept_match\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_accept_multiview_replaces_existing_view\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_accept_nomatch\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_containment_dottedname\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_containment_false\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_containment_true\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_decorator\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_decorator_tuple\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_default_permission_no_explicit_permission\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_default_renderer\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_function_callable\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_function_callable_requestonly\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_header_badregex\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_header_noval_match\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_header_noval_nomatch\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_header_val_match\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_header_val_missing\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_header_val_nomatch\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_http_cache\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_mapper\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_name\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_name_unicode\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_no_default_permission_no_explicit_permission\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_nonexistant_route_name\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_path_info_badregex\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_path_info_match\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_path_info_nomatch\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_permission\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_method_false\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_method_get_implies_head\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_method_sequence_conflict\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_method_sequence_false\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_method_sequence_true\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_method_true\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_param_noval_false\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_param_noval_true\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_param_val_false\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_param_val_true\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_type\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_type_and_route_name\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_type_as_iface\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_request_type_as_noniface\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_route_name\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_route_name_exception\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_tmpl_renderer_factory_introspector_missing\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_tmpl_renderer_factory_no_renderer_factory\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_tmpl_renderer_factory_with_renderer_factory\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_view_config_and_view_defaults_conflicts\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_view_config_and_view_defaults_doesnt_conflict\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults_viewname_is_dottedname_kwarg\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_xhr_false\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_xhr_true\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_wrapped_view_is_decorated\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_views_with_accept_multiview_replaces_existing\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_derive_view_dottedname\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_derive_view_function\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_derive_view_with_default_renderer_no_explicit_renderer\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_derive_view_with_default_renderer_with_explicit_renderer\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_set_view_mapper\nPASSED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_set_view_mapper_dottedname\nPASSED r2e_tests/test_1.py::Test_requestonly::test_defaults\nPASSED r2e_tests/test_1.py::Test_requestonly::test_otherattr\nPASSED r2e_tests/test_1.py::Test_isexception::test_is_IException\nPASSED r2e_tests/test_1.py::Test_isexception::test_is_IException_subinterface\nPASSED r2e_tests/test_1.py::Test_isexception::test_is_exception_class\nPASSED r2e_tests/test_1.py::Test_isexception::test_is_exception_instance\nPASSED r2e_tests/test_1.py::TestMultiView::test___call__\nPASSED r2e_tests/test_1.py::TestMultiView::test___call__intermediate_not_found\nPASSED r2e_tests/test_1.py::TestMultiView::test___call__raise_not_found_isnt_interpreted_as_pred_mismatch\nPASSED r2e_tests/test_1.py::TestMultiView::test___call_permissive_has_call_permissive\nPASSED r2e_tests/test_1.py::TestMultiView::test___call_permissive_has_no_call_permissive\nPASSED r2e_tests/test_1.py::TestMultiView::test__call__not_found\nPASSED r2e_tests/test_1.py::TestMultiView::test__call__with_accept_match\nPASSED r2e_tests/test_1.py::TestMultiView::test__call__with_accept_miss\nPASSED r2e_tests/test_1.py::TestMultiView::test__call_permissive__not_found\nPASSED r2e_tests/test_1.py::TestMultiView::test_add\nPASSED r2e_tests/test_1.py::TestMultiView::test_add_with_phash\nPASSED r2e_tests/test_1.py::TestMultiView::test_add_with_phash_override_accept\nPASSED r2e_tests/test_1.py::TestMultiView::test_add_with_phash_override_accept2\nPASSED r2e_tests/test_1.py::TestMultiView::test_class_implements_ISecuredView\nPASSED r2e_tests/test_1.py::TestMultiView::test_get_views\nPASSED r2e_tests/test_1.py::TestMultiView::test_get_views_best_match_returns_None\nPASSED r2e_tests/test_1.py::TestMultiView::test_get_views_no_self_accepts\nPASSED r2e_tests/test_1.py::TestMultiView::test_get_views_request_has_no_accept\nPASSED r2e_tests/test_1.py::TestMultiView::test_instance_implements_ISecuredView\nPASSED r2e_tests/test_1.py::TestMultiView::test_match_not_found\nPASSED r2e_tests/test_1.py::TestMultiView::test_match_predicate_fails\nPASSED r2e_tests/test_1.py::TestMultiView::test_match_predicate_succeeds\nPASSED r2e_tests/test_1.py::TestMultiView::test_multiple_with_functions_as_views\nPASSED r2e_tests/test_1.py::TestMultiView::test_permitted\nPASSED r2e_tests/test_1.py::TestMultiView::test_permitted_no_match_with__permitted__\nPASSED r2e_tests/test_1.py::TestMultiView::test_permitted_no_views\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_function_context_and_request\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_function_requestonly\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_instance_context_and_request\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_instance_context_and_request_attr_and_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_instance_requestonly_attr_and_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_newstyle_class_context_and_request\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_newstyle_class_context_and_request_attr_and_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_newstyle_class_requestonly\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_newstyle_class_requestonly_attr_and_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_oldstyle_class_context_and_request\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_oldstyle_class_requestonly\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_oldstyle_cls_context_request_attr_and_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_as_oldstyle_cls_requestonly_attr_and_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_attr_wrapped_view_branching_default_phash\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_attr_wrapped_view_branching_nondefault_phash\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_class_with_attr\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_class_without_attr\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_debug_auth_permission_authpol_denied\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_debug_auth_permission_authpol_denied2\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_debug_auth_permission_authpol_overridden\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_debug_auth_permission_authpol_permitted\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_debug_auth_permission_authpol_permitted_no_request\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_function_returns_true_Response_no_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_function_returns_true_Response_with_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_http_cached_prevent_http_cache_in_settings\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_http_cached_view_bad_tuple\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_http_cached_view_integer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_http_cached_view_prevent_auto_set\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_http_cached_view_timedelta\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_http_cached_view_tuple\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_http_cached_view_tuple_seconds_None\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_predicate_mismatch_exception_has_text_in_detail\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_predicate_mismatch_view_has_name\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_predicate_mismatch_view_has_no_name\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_requestonly_function\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_requestonly_function_with_renderer\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_requestonly_function_with_renderer_request_has_view\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_requestonly_function_with_renderer_request_override\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_secured_view_authn_policy_no_authz_policy\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_secured_view_authz_policy_no_authn_policy\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_secured_view_raises_forbidden_no_name\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_secured_view_raises_forbidden_with_name\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_debug_authorization_authn_policy_no_authz_policy\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_debug_authorization_authz_policy_no_authn_policy\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_debug_authorization_no_authpol\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_debug_authorization_no_permission\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_predicates_all\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_predicates_checker\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_predicates_notall\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_view_mapper_config_specified\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_view_mapper_default_mapper_specified\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_view_mapper_view_specified\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_wrapper_viewname\nPASSED r2e_tests/test_1.py::TestViewDeriver::test_with_wrapper_viewname_notfound\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test__view_as_function_with_attr\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_function_context_and_request\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_function_requestonly\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_function_requestonly_with_attr\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_instance_context_and_request\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_instance_context_and_request_and_attr\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_instance_requestonly\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_instance_requestonly_with_attr\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_newstyle_class_context_and_request\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_newstyle_class_context_and_request_with_attr\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_newstyle_class_requestonly\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_newstyle_class_requestonly_with_attr\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_oldstyle_class_context_and_request\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_oldstyle_class_context_and_request_with_attr\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_oldstyle_class_requestonly\nPASSED r2e_tests/test_1.py::TestDefaultViewMapper::test_view_as_oldstyle_class_requestonly_with_attr\nPASSED r2e_tests/test_1.py::Test_preserve_view_attrs::test_it_different\nPASSED r2e_tests/test_1.py::Test_preserve_view_attrs::test_it_different_with_existing_original_view\nPASSED r2e_tests/test_1.py::Test_preserve_view_attrs::test_it_same\nPASSED r2e_tests/test_1.py::Test_preserve_view_attrs::test_it_view_is_None\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_already_exists\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_url_noendslash\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_url_noscheme\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_url_withendslash\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_viewname\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_viewname_with_context\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_viewname_with_for_\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_viewname_with_permission\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_viewname_with_renderer\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_add_viewname_with_route_prefix\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_missing\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_quoting\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_registration_miss\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_registration_no_registry_on_request\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_route_url\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_slash_in_name1\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_slash_in_name2\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_url_quoted_remote\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_generate_url_unquoted_local\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_verifyClass\nPASSED r2e_tests/test_1.py::TestStaticURLInfo::test_verifyObject\nPASSED r2e_tests/test_1.py::Test_view_description::test_with_text\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_object_event_subscriber\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_resource_url_default_resource_iface_means_Interface\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_resource_url_nodefault_resource_iface\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_response_adapter\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_response_adapter_dottednames\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_response_adapter_self\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_defaults\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_dottednames\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_iface_specified\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_predicate\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_with_default_type_predicates_False\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_with_default_type_predicates_True\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_with_specific_type_and_predicates_False\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_subscriber_with_specific_type_and_predicates_True\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_traverser_default_iface_means_Interface\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_traverser_introspectables\nPASSED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_traverser_nondefault_iface\nPASSED r2e_tests/test_config/test_adapters.py::Test_eventonly::test_defaults\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test__override_already_registered\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test__override_not_yet_registered\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_directory_with_directory\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_directory_with_file\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_directory_with_package\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_file_with_directory\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_file_with_file\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_file_with_package\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_package_with_directory\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_package_with_package\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_samename\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_filename_override_returns_value\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_stream_no_overrides\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_stream_override_returns_None\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_stream_override_returns_value\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_string_no_overrides\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_string_override_returns_None\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_string_override_returns_value\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_has_resource_no_overrides\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_has_resource_override_returns_None\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_has_resource_override_returns_True\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_resource_isdir_no_overrides\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_resource_isdir_override_returns_False\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_resource_isdir_override_returns_None\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_resource_listdir_no_overrides\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_resource_listdir_override_returns_None\nPASSED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_resource_listdir_override_returns_values\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_class_conforms_to_IPEP302Loader\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_class_conforms_to_IPackageOverrides\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_ctor_package_already_has_loader_of_different_type\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_ctor_package_already_has_loader_of_same_type\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_ctor_registers_loader_type\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_ctor_sets_loader\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_ctor_sets_local_state\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_code_pkg_has___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_code_pkg_has_no___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_data_pkg_has___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_data_pkg_has_no___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_filename_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_source_pkg_has___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_source_pkg_has_no___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_stream\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_stream_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_string\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_string_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_has_resource\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_has_resource_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_insert_directory\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_insert_emptystring\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_insert_file\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_instance_conforms_to_IPEP302Loader\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_instance_conforms_to_IPackageOverrides\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_is_package_pkg_has___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_is_package_pkg_has_no___loader__\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_isdir_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_isdir_false\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_isdir_true\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_listdir\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_listdir_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_search_path\nPASSED r2e_tests/test_config/test_assets.py::TestDirectoryOverride::test_it_match\nPASSED r2e_tests/test_config/test_assets.py::TestDirectoryOverride::test_it_no_match\nPASSED r2e_tests/test_config/test_assets.py::TestFileOverride::test_it_match\nPASSED r2e_tests/test_config/test_assets.py::TestFileOverride::test_it_no_match\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_add_request_method_with_None_callable\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_add_request_method_with_None_callable_and_no_name\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_add_request_method_with_None_callable_conflict\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_add_request_method_with_callable\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_add_request_method_with_unnamed_callable\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_multiple_request_methods_conflict\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_request_factory\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_request_factory_dottedname\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_root_factory\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_root_factory_as_None\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_root_factory_dottedname\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_session_factory\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_session_factory_dottedname\nPASSED r2e_tests/test_config/test_factories.py::TestDeprecatedFactoriesMixinMethods::test_set_multiple_request_properties\nPASSED r2e_tests/test_config/test_factories.py::TestDeprecatedFactoriesMixinMethods::test_set_multiple_request_properties_conflict\nPASSED r2e_tests/test_config/test_factories.py::TestDeprecatedFactoriesMixinMethods::test_set_request_property_with_callable\nPASSED r2e_tests/test_config/test_factories.py::TestDeprecatedFactoriesMixinMethods::test_set_request_property_with_property\nPASSED r2e_tests/test_config/test_factories.py::TestDeprecatedFactoriesMixinMethods::test_set_request_property_with_unnamed_callable\nPASSED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_missing_dir\nPASSED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_no_specs\nPASSED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_set_locale_negotiator\nPASSED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_set_locale_negotiator_dottedname\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test___getattr__matches\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test___getattr__matches_no_action_wrap\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test___getattr__missing_when_directives_dont_exist\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test___getattr__missing_when_directives_exist\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test__fix_registry_has_listeners\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test__fix_registry_notify\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test__fix_registry_queryAdapterOrSelf\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test__fix_registry_registerSelfAdapter\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_absolute_asset_spec_already_absolute\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_absolute_asset_spec_notastring\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_absolute_asset_spec_relative\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_autocommit_with_introspectables\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_autocommit_with_introspectables_introspection_off\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_branching_kw_is_None\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_branching_kw_is_not_None\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_branching_nonautocommit_with_config_info\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_branching_nonautocommit_with_introspectables\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_branching_nonautocommit_without_config_info\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_action_nonautocommit_with_introspectables_introspection_off\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_autocommit_no_conflicts\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_begin\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_begin_with_request\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_commit_conflict_resolved_with_include\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_commit_conflict_resolved_with_two_includes_and_local\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_commit_conflict_simple\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_commit_conflict_with_two_includes\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_conflict_set_forbidden_view\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_conflict_set_notfound_view\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_alternate_renderers\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_authentication_policy\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_authorization_policy_only\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_default_permission\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_default_renderers\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_default_view_mapper\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_default_webob_response_adapter_registered\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_exceptionresponse_view_None\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_exceptionresponse_view_custom\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_httpexception_view_default\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_no_root_factory\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_noreg_custom_settings\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_noreg_debug_logger_non_None\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_session_factory\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_with_introspection\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_with_package_registry\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_with_root_factory\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_end\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_hook_zca\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_dotted_name\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_missing_source_file\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_module_defaults_to_includeme\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_module_defaults_to_includeme_missing\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_nested_route_prefix\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_python_callable\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_route_prefix\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_introspector_decorator\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_make_wsgi_app\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_maybe_dotted_notstring_success\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_maybe_dotted_string_fail\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_maybe_dotted_string_success\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_scan_integration\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_scan_integration_dottedname_package\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_scan_integration_with_extra_kw\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_scan_integration_with_ignore\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_scan_integration_with_onerror\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_alternate_renderers\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authentication_policy\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authentication_policy_dottedname\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authorization_policy_dottedname\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authorization_policy_only\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_calls_fix_registry\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_custom_settings\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_debug_logger_name\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_debug_logger_non_None\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_default_permission\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_dottedname_root_factory\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_explicit_notfound_trumps_iexceptionresponse\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_includes\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_includes_spaces\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_locale_negotiator\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_locale_negotiator_dottedname\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_no_default_root_factory\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_registers_default_exceptionresponse_views\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_registers_default_view_predicates\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_registers_default_webob_iresponse_adapter\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_request_factory\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_request_factory_dottedname\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_tweens\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_unhook_zca\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_with_package\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_with_package_module\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_with_package_package\nPASSED r2e_tests/test_config/test_init.py::TestConfigurator_add_directive::test_directive_persists_across_configurator_creations\nPASSED r2e_tests/test_config/test_init.py::TestConfigurator_add_directive::test_extend_action_method_successful\nPASSED r2e_tests/test_config/test_init.py::TestConfigurator_add_directive::test_extend_same_name_doesnt_conflict\nPASSED r2e_tests/test_config/test_init.py::TestConfigurator__add_predicate::test_factory_as_object\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_action_simple\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_action_with_includepath\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_action_with_includepath_and_info\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_action_with_info\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_action_with_introspectables\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_action_with_order\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_execute_actions_dicts\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_execute_actions_error\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_execute_actions_tuples\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_execute_actions_with_introspectable_no_callable\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_execute_actions_with_introspectables\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_it\nPASSED r2e_tests/test_config/test_init.py::TestActionState::test_processSpec\nPASSED r2e_tests/test_config/test_init.py::Test_resolveConflicts::test_it_conflict\nPASSED r2e_tests/test_config/test_init.py::Test_resolveConflicts::test_it_success_dicts\nPASSED r2e_tests/test_config/test_init.py::Test_resolveConflicts::test_it_success_tuples\nPASSED r2e_tests/test_config/test_init.py::Test_resolveConflicts::test_it_with_actions_grouped_by_order\nPASSED r2e_tests/test_config/test_init.py::TestGlobalRegistriesIntegration::test_global_registries\nPASSED r2e_tests/test_config/test_init.py::TestGlobalRegistriesIntegration::test_global_registries_empty\nPASSED r2e_tests/test_config/test_predicates.py::TestXHRPredicate::test___call___false\nPASSED r2e_tests/test_config/test_predicates.py::TestXHRPredicate::test___call___true\nPASSED r2e_tests/test_config/test_predicates.py::TestXHRPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::TestXHRPredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestMethodPredicate::test___call___false\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestMethodPredicate::test___call___true_multi\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestMethodPredicate::test___call___true_single\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestMethodPredicate::test_ctor_get_but_no_head\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestMethodPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestMethodPredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::TestPathInfoPredicate::test___call___false\nPASSED r2e_tests/test_config/test_predicates.py::TestPathInfoPredicate::test___call___true\nPASSED r2e_tests/test_config/test_predicates.py::TestPathInfoPredicate::test_ctor_compilefail\nPASSED r2e_tests/test_config/test_predicates.py::TestPathInfoPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::TestPathInfoPredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test___call___false\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test___call___false_multi\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test___call___true_exists\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test___call___true_multi\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test___call___true_withval\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test_phash_exists\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test_phash_withval\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test_text_exists\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test_text_multi\nPASSED r2e_tests/test_config/test_predicates.py::TestRequestParamPredicate::test_text_withval\nPASSED r2e_tests/test_config/test_predicates.py::TestMatchParamPredicate::test___call___false\nPASSED r2e_tests/test_config/test_predicates.py::TestMatchParamPredicate::test___call___matchdict_is_None\nPASSED r2e_tests/test_config/test_predicates.py::TestMatchParamPredicate::test___call___true_multi\nPASSED r2e_tests/test_config/test_predicates.py::TestMatchParamPredicate::test___call___true_single\nPASSED r2e_tests/test_config/test_predicates.py::TestMatchParamPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::TestMatchParamPredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::TestCustomPredicate::test___call___false\nPASSED r2e_tests/test_config/test_predicates.py::TestCustomPredicate::test___call___true\nPASSED r2e_tests/test_config/test_predicates.py::TestCustomPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::TestCustomPredicate::test_text_func_has___text__\nPASSED r2e_tests/test_config/test_predicates.py::TestCustomPredicate::test_text_func_repr\nPASSED r2e_tests/test_config/test_predicates.py::TestTraversePredicate::test___call__traverse_has_remainder_already\nPASSED r2e_tests/test_config/test_predicates.py::TestTraversePredicate::test___call__traverse_matches\nPASSED r2e_tests/test_config/test_predicates.py::TestTraversePredicate::test___call__traverse_matches_with_highorder_chars\nPASSED r2e_tests/test_config/test_predicates.py::TestTraversePredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::TestTraversePredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::Test_CheckCSRFTokenPredicate::test_it_call_val_False\nPASSED r2e_tests/test_config/test_predicates.py::Test_CheckCSRFTokenPredicate::test_it_call_val_True\nPASSED r2e_tests/test_config/test_predicates.py::Test_CheckCSRFTokenPredicate::test_it_call_val_str\nPASSED r2e_tests/test_config/test_predicates.py::Test_CheckCSRFTokenPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::Test_CheckCSRFTokenPredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test___call___false\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test___call___false_withregex\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test___call___true_exists\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test___call___true_withregex\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test___call___true_withval\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test_phash_exists\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test_phash_withregex\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test_phash_withval\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test_text_exists\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test_text_withregex\nPASSED r2e_tests/test_config/test_predicates.py::TestHeaderPredicate::test_text_withval\nPASSED r2e_tests/test_config/test_predicates.py::Test_PhysicalPathPredicate::test_it_call_False\nPASSED r2e_tests/test_config/test_predicates.py::Test_PhysicalPathPredicate::test_it_call_context_has_no_name\nPASSED r2e_tests/test_config/test_predicates.py::Test_PhysicalPathPredicate::test_it_call_val_list_True\nPASSED r2e_tests/test_config/test_predicates.py::Test_PhysicalPathPredicate::test_it_call_val_str_True\nPASSED r2e_tests/test_config/test_predicates.py::Test_PhysicalPathPredicate::test_it_call_val_tuple_True\nPASSED r2e_tests/test_config/test_predicates.py::Test_PhysicalPathPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::Test_PhysicalPathPredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::Test_EffectivePrincipalsPredicate::test_it_call_authentication_policy_doesnt_provide_superset\nPASSED r2e_tests/test_config/test_predicates.py::Test_EffectivePrincipalsPredicate::test_it_call_authentication_policy_provides_superset\nPASSED r2e_tests/test_config/test_predicates.py::Test_EffectivePrincipalsPredicate::test_it_call_authentication_policy_provides_superset_implicit\nPASSED r2e_tests/test_config/test_predicates.py::Test_EffectivePrincipalsPredicate::test_it_call_no_authentication_policy\nPASSED r2e_tests/test_config/test_predicates.py::Test_EffectivePrincipalsPredicate::test_phash\nPASSED r2e_tests/test_config/test_predicates.py::Test_EffectivePrincipalsPredicate::test_text\nPASSED r2e_tests/test_config/test_predicates.py::Test_EffectivePrincipalsPredicate::test_text_noniter\nPASSED r2e_tests/test_config/test_rendering.py::TestRenderingConfiguratorMixin::test_add_default_renderers\nPASSED r2e_tests/test_config/test_rendering.py::TestRenderingConfiguratorMixin::test_add_renderer\nPASSED r2e_tests/test_config/test_rendering.py::TestRenderingConfiguratorMixin::test_add_renderer_dottedname_factory\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_defaults\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_discriminator\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_no_path_no_pattern\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_no_pattern_with_path\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_no_view_with_view_attr\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_no_view_with_view_context\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_no_view_with_view_permission\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_no_view_with_view_renderer\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_accept\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_custom_predicates\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_factory\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_factory_dottedname\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_header\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_path_info\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_path_info_highorder\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_path_info_regex\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_pregenerator\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_request_method\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_request_param\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_route_prefix\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_static\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_xhr\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_get_routes_mapper_already_registered\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_get_routes_mapper_not_yet_registered\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_add_permission\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_no_authz_policy\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_no_authz_policy_autocommit\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_with_authz_policy\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_with_authz_policy_autocommit\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_no_authn_policy\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_no_authn_policy_autocommit\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_with_authn_policy\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_with_authn_policy_autocommit\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_default_permission\nPASSED r2e_tests/test_config/test_settings.py::TestSettingsConfiguratorMixin::test__set_settings_as_None\nPASSED r2e_tests/test_config/test_settings.py::TestSettingsConfiguratorMixin::test__set_settings_as_dictwithvalues\nPASSED r2e_tests/test_config/test_settings.py::TestSettingsConfiguratorMixin::test_add_settings_settings_None\nPASSED r2e_tests/test_config/test_settings.py::TestSettingsConfiguratorMixin::test_add_settings_settings_already_registered\nPASSED r2e_tests/test_config/test_settings.py::TestSettingsConfiguratorMixin::test_add_settings_settings_not_yet_registered\nPASSED r2e_tests/test_config/test_settings.py::TestSettingsConfiguratorMixin::test_get_settings_nosettings\nPASSED r2e_tests/test_config/test_settings.py::TestSettingsConfiguratorMixin::test_get_settings_withsettings\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_debug_all\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_debug_authorization\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_debug_notfound\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_debug_routematch\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_debug_templates\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_default_locale_name\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_getattr_fail\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_getattr_raises_attribute_error\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_getattr_success\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_noargs\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_originals_kept\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_prevent_http_cache\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_reload_all\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_reload_assets\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_reload_resources\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_reload_templates\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_renderer\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_renderer_explicitrenderer\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_renderer_twice\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_subscriber_defaults\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_subscriber_dottedname\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_subscriber_multiple\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_subscriber_single\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_template\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_resources\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_securitypolicy\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_securitypolicy_forget_result\nPASSED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_securitypolicy_remember_result\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_dottedname\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_instance\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_name_ingress\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_name_main\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_over_ingress\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_over_ingress_iterable\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_under_main\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_under_main_iterable\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_unsuitable\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tweens_conflict\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tweens_names_distinct\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tweens_names_with_over_nonstringoriter\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tweens_names_with_under_nonstringoriter\nPASSED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tweens_names_with_underover\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test___call___explicit\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test___call___implicit\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_add_explicit\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_add_implicit\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_1\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_2\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_3\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_4\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_5\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_conflict_direct\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_conflict_indirect\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_missing_over_and_under_partials\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_missing_over_partial\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_missing_over_partial_with_fallback\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_missing_under_partial\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_missing_under_partial_with_fallback\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_with_missing_fallbacks\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_with_multiple_matching_fallbacks\nPASSED r2e_tests/test_config/test_tweens.py::TestTweens::test_implicit_ordering_with_partial_fallbacks\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_custom_predicates_can_affect_traversal\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_different_custom_predicates_with_same_hash\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_match_param_from_dict\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_match_param_from_dict_fails\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_match_param_from_string\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_match_param_from_string_fails\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_notted\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_ordering_importance_and_number\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_ordering_importance_of_predicates\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_ordering_number_of_predicates\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_ordering_xhr_and_request_method_trump_only_containment\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_predicate_text_is_correct\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_request_method_ordering_hashes_same\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_request_method_sequence\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_traverse_has_remainder_already\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_traverse_matches\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_traverse_matches_with_highorder_chars\nPASSED r2e_tests/test_config/test_util.py::TestPredicateList::test_unknown_predicate\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_defaultargs_firstname_not_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_defaultargs_firstname_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_noargs\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_onearg_named_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_onearg_named_somethingelse\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_toomanyargs\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_with_attr_false\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_function_with_attr_true\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_instance_defaultargs_firstname_not_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_instance_defaultargs_firstname_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_instance_defaultargs_onearg_named_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_instance_defaultargs_onearg_named_somethingelse\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_instance_nocall\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_instance_toomanyargs\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_method_onearg_named_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_newstyle_class_init_defaultargs_firstname_not_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_newstyle_class_init_defaultargs_firstname_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_newstyle_class_init_firstname_request_with_secondname\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_newstyle_class_init_noargs\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_newstyle_class_init_onearg_named_somethingelse\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_oldstyle_class_init_defaultargs_firstname_not_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_oldstyle_class_init_defaultargs_firstname_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_oldstyle_class_init_noargs\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_oldstyle_class_init_onearg_named_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_oldstyle_class_init_onearg_named_somethingelse\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_oldstyle_class_init_toomanyargs\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_oldstyle_class_no_init\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_requestonly_newstyle_class_init_onearg_named_request\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_requestonly_newstyle_class_init_toomanyargs\nPASSED r2e_tests/test_config/test_util.py::Test_takes_one_arg::test_requestonly_newstyle_class_no_init\nPASSED r2e_tests/test_config/test_util.py::TestNotted::test_it_with_phash_val\nPASSED r2e_tests/test_config/test_util.py::TestNotted::test_it_without_phash_val\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_allows_other_predicates\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_context\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_for_\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_http_cache\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_name\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_disallows_permission\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_with_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_allows_other_predicates\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_append_slash\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_context\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_for_\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_http_cache\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_name\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_disallows_permission\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_with_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_static_view_absolute\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_static_view_here_no_utility_registered\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_static_view_package_relative\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_as_instance\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_as_instance_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_as_instancemethod\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_as_instancemethod_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_as_oldstyle_class\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_as_oldstyle_class_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_context_as_class\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_context_as_dottedname\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_context_as_iface\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_context_trumps_for\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_custom_more_preds_first_bests_fewer_preds_last\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_default_phash_overrides_default_phash\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_default_phash_overrides_no_phash\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_default_phash_overrides_default_phash\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_default_phash_overrides_no_phash\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_multiview_replaces_existing_securedview\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_multiview_replaces_existing_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_multiview_replaces_multiview\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_mulview_replaces_existing_view_with___accept__\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_same_phash_overrides_existing_single_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_with_accept_multiview_replaces_existing_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exception_register_secured_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_for__as_dottedname\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_for_as_class\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_for_as_iface\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_mixed_case_replaces_existing_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview___discriminator__\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview_call_ordering\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview_context_superclass_then_subclass\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview_exception_superclass_then_subclass\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_existing_securedview\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_existing_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_existing_view_with___accept__\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_multiview_replaces_multiview\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_register_secured_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_same_phash_overrides_existing_single_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_same_predicates\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_view_callable_None_no_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_view_callable_None_with_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_view_callable_dottedname\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_accept_match\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_accept_multiview_replaces_existing_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_accept_nomatch\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_containment_dottedname\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_containment_false\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_containment_true\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_decorator\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_decorator_tuple\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_default_permission_no_explicit_permission\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_default_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_function_callable\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_function_callable_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_header_badregex\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_header_noval_match\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_header_noval_nomatch\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_header_val_match\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_header_val_missing\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_header_val_nomatch\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_http_cache\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_mapper\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_name\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_name_unicode\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_no_default_permission_no_explicit_permission\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_nonexistant_route_name\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_path_info_badregex\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_path_info_match\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_path_info_nomatch\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_permission\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_method_false\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_method_get_implies_head\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_method_sequence_conflict\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_method_sequence_false\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_method_sequence_true\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_method_true\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_param_noval_false\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_param_noval_true\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_param_val_false\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_param_val_true\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_type\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_type_and_route_name\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_type_as_iface\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_request_type_as_noniface\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_route_name\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_route_name_exception\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_tmpl_renderer_factory_introspector_missing\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_tmpl_renderer_factory_no_renderer_factory\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_tmpl_renderer_factory_with_renderer_factory\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_view_config_and_view_defaults_conflicts\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_view_config_and_view_defaults_doesnt_conflict\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults_viewname_is_dottedname_kwarg\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_xhr_false\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_xhr_true\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_wrapped_view_is_decorated\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_views_with_accept_multiview_replaces_existing\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_derive_view_dottedname\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_derive_view_function\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_derive_view_with_default_renderer_no_explicit_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_derive_view_with_default_renderer_with_explicit_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_set_view_mapper\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_set_view_mapper_dottedname\nPASSED r2e_tests/test_config/test_views.py::Test_requestonly::test_defaults\nPASSED r2e_tests/test_config/test_views.py::Test_requestonly::test_otherattr\nPASSED r2e_tests/test_config/test_views.py::Test_isexception::test_is_IException\nPASSED r2e_tests/test_config/test_views.py::Test_isexception::test_is_IException_subinterface\nPASSED r2e_tests/test_config/test_views.py::Test_isexception::test_is_exception_class\nPASSED r2e_tests/test_config/test_views.py::Test_isexception::test_is_exception_instance\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test___call__\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test___call__intermediate_not_found\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test___call__raise_not_found_isnt_interpreted_as_pred_mismatch\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test___call_permissive_has_call_permissive\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test___call_permissive_has_no_call_permissive\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test__call__not_found\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test__call__with_accept_match\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test__call__with_accept_miss\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test__call_permissive__not_found\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_add\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_add_with_phash\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_add_with_phash_override_accept\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_add_with_phash_override_accept2\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_class_implements_ISecuredView\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_get_views\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_get_views_best_match_returns_None\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_get_views_no_self_accepts\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_get_views_request_has_no_accept\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_instance_implements_ISecuredView\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_match_not_found\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_match_predicate_fails\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_match_predicate_succeeds\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_multiple_with_functions_as_views\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_permitted\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_permitted_no_match_with__permitted__\nPASSED r2e_tests/test_config/test_views.py::TestMultiView::test_permitted_no_views\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_function_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_function_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_instance_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_instance_context_and_request_attr_and_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_instance_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_instance_requestonly_attr_and_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_newstyle_class_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_newstyle_class_context_and_request_attr_and_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_newstyle_class_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_newstyle_class_requestonly_attr_and_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_oldstyle_class_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_oldstyle_class_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_oldstyle_cls_context_request_attr_and_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_as_oldstyle_cls_requestonly_attr_and_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_attr_wrapped_view_branching_default_phash\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_attr_wrapped_view_branching_nondefault_phash\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_class_with_attr\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_class_without_attr\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_debug_auth_permission_authpol_denied\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_debug_auth_permission_authpol_denied2\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_debug_auth_permission_authpol_overridden\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_debug_auth_permission_authpol_permitted\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_debug_auth_permission_authpol_permitted_no_request\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_function_returns_true_Response_no_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_function_returns_true_Response_with_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_http_cached_prevent_http_cache_in_settings\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_http_cached_view_bad_tuple\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_http_cached_view_integer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_http_cached_view_prevent_auto_set\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_http_cached_view_timedelta\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_http_cached_view_tuple\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_http_cached_view_tuple_seconds_None\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_predicate_mismatch_exception_has_text_in_detail\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_predicate_mismatch_view_has_name\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_predicate_mismatch_view_has_no_name\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_requestonly_function\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_requestonly_function_with_renderer\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_requestonly_function_with_renderer_request_has_view\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_requestonly_function_with_renderer_request_override\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_secured_view_authn_policy_no_authz_policy\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_secured_view_authz_policy_no_authn_policy\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_secured_view_raises_forbidden_no_name\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_secured_view_raises_forbidden_with_name\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_debug_authorization_authn_policy_no_authz_policy\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_debug_authorization_authz_policy_no_authn_policy\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_debug_authorization_no_authpol\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_debug_authorization_no_permission\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_predicates_all\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_predicates_checker\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_predicates_notall\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_view_mapper_config_specified\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_view_mapper_default_mapper_specified\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_view_mapper_view_specified\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_wrapper_viewname\nPASSED r2e_tests/test_config/test_views.py::TestViewDeriver::test_with_wrapper_viewname_notfound\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test__view_as_function_with_attr\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_function_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_function_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_function_requestonly_with_attr\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_instance_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_instance_context_and_request_and_attr\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_instance_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_instance_requestonly_with_attr\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_newstyle_class_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_newstyle_class_context_and_request_with_attr\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_newstyle_class_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_newstyle_class_requestonly_with_attr\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_oldstyle_class_context_and_request\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_oldstyle_class_context_and_request_with_attr\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_oldstyle_class_requestonly\nPASSED r2e_tests/test_config/test_views.py::TestDefaultViewMapper::test_view_as_oldstyle_class_requestonly_with_attr\nPASSED r2e_tests/test_config/test_views.py::Test_preserve_view_attrs::test_it_different\nPASSED r2e_tests/test_config/test_views.py::Test_preserve_view_attrs::test_it_different_with_existing_original_view\nPASSED r2e_tests/test_config/test_views.py::Test_preserve_view_attrs::test_it_same\nPASSED r2e_tests/test_config/test_views.py::Test_preserve_view_attrs::test_it_view_is_None\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_already_exists\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_url_noendslash\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_url_noscheme\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_url_withendslash\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_viewname\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_viewname_with_context\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_viewname_with_for_\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_viewname_with_permission\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_viewname_with_renderer\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_viewname_with_route_prefix\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_missing\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_quoting\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_registration_miss\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_registration_no_registry_on_request\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_route_url\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_slash_in_name1\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_slash_in_name2\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_url_quoted_remote\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_url_unquoted_local\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_verifyClass\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_verifyObject\nPASSED r2e_tests/test_config/test_views.py::Test_view_description::test_with_text\nPASSED r2e_tests/test_scripts/test_common.py::Test_logging_file_config::test_it\nPASSED r2e_tests/test_scripts/test_common.py::TestParseVars::test_parse_vars_bad\nPASSED r2e_tests/test_scripts/test_common.py::TestParseVars::test_parse_vars_good\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_known_scaffold_absolute_path\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_known_scaffold_multiple_rendered\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_known_scaffold_single_rendered\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_known_scaffold_with_path_as_project_target_rendered\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_no_project_name\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_run_no_scaffold_name\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_run_show_scaffolds_exist\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_run_show_scaffolds_none_exist\nPASSED r2e_tests/test_scripts/test_pcreate.py::TestPCreateCommand::test_unknown_scaffold_name\nPASSED r2e_tests/test_scripts/test_pcreate.py::Test_main::test_it\nPASSED r2e_tests/test_scripts/test_pdistreport.py::TestPDistReportCommand::test_no_dists\nPASSED r2e_tests/test_scripts/test_pdistreport.py::TestPDistReportCommand::test_with_dists\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_has_bad_config_header\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_not_enough_args\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_response_has_no_charset\nPASSED r2e_tests/test_scripts/test_prequest.py::Test_main::test_it\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test__get_mapper\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_bad_args\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_good_args\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_no_mapper\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_no_routes\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_route_with_no_slash_prefix\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_single_route_no_route_registered\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_single_route_no_views_registered\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_single_route_one_view_registered\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_single_route_one_view_registered_with_factory\nPASSED r2e_tests/test_scripts/test_proutes.py::Test_main::test_it\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_get_options_no_command\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_get_options_with_command\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_parse_vars_bad\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_parse_vars_good\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_record_pid_not_verbose\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_record_pid_verbose\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_current_pid_is_not_pid_in_file\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_current_pid_is_not_written_pid\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_file_not_verbose\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_file_stale_pid_write_exception\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_file_unlink_exception\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_file_verbose\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_no_pid_file\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_remove_pid_not_a_number\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_run_no_args\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_run_stop_daemon_bad_pid_file\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_run_stop_daemon_invalid_pid_in_file\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_run_stop_daemon_no_such_pid_file\nPASSED r2e_tests/test_scripts/test_pserve.py::Test_read_pidfile::test_read_pidfile\nPASSED r2e_tests/test_scripts/test_pserve.py::Test_read_pidfile::test_read_pidfile_no_pid_file\nPASSED r2e_tests/test_scripts/test_pserve.py::Test_read_pidfile::test_read_pidfile_not_a_number\nPASSED r2e_tests/test_scripts/test_pserve.py::Test_main::test_it\nPASSED r2e_tests/test_scripts/test_pserve.py::TestLazyWriter::test_flush\nPASSED r2e_tests/test_scripts/test_pserve.py::TestLazyWriter::test_open\nPASSED r2e_tests/test_scripts/test_pserve.py::TestLazyWriter::test_write\nPASSED r2e_tests/test_scripts/test_pserve.py::TestLazyWriter::test_writeline\nPASSED r2e_tests/test_scripts/test_pserve.py::Test__methodwrapper::test___call__fail\nPASSED r2e_tests/test_scripts/test_pserve.py::Test__methodwrapper::test___call__succeed\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_custom_section_override\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_bpython_shell\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_check_variable_override_order\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_custom_items\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_default_shell\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_default_shell_with_unknown_shell\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_ipython_v0_10\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_ipython_v0_11\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_setup_from_options\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_setup\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_make_bpython_shell\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_make_default_shell\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_make_ipython_v0_10_shell\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_make_ipython_v0_11_shell\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_shell_ipython_ordering\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_shell_ordering\nPASSED r2e_tests/test_scripts/test_pshell.py::Test_main::test_it\nPASSED r2e_tests/test_scripts/test_ptweens.py::TestPTweensCommand::test__get_tweens\nPASSED r2e_tests/test_scripts/test_ptweens.py::TestPTweensCommand::test_command_implicit_and_explicit_tweens\nPASSED r2e_tests/test_scripts/test_ptweens.py::TestPTweensCommand::test_command_implicit_tweens_only\nPASSED r2e_tests/test_scripts/test_ptweens.py::TestPTweensCommand::test_command_no_tweens\nPASSED r2e_tests/test_scripts/test_ptweens.py::Test_main::test_it\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_multi_routes_all_match\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_multi_routes_none_match\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_multi_routes_some_match\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_view_no_match\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_view_no_match_multiview_registered\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_view_route_multiview\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_view_route_multiview_no_view_registered\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_view_route_no_multiview\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_view_traversal\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test__find_view_traversal_multiview\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multi_view_nested\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multiview\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multiview_with_permission\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multiview_with_predicates\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_not_found\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_not_found_url_starts_without_slash\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_route\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_route_with_route_predicates\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_traversal\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_traversal_with_permission\nPASSED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_traversal_with_predicates\nPASSED r2e_tests/test_scripts/test_pviews.py::Test_main::test_it\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_forbidden_view_with_view_defaults\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_notfound_view_with_view_defaults\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_static_view_here_no_utility_registered\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_static_view_package_here_relative\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_custom_predicate_bests_standard_predicate\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_custom_predicates_match\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_custom_predicates_nomatch\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_template_renderer\nFAILED r2e_tests/test_1.py::TestViewsConfigurationMixin::test_add_view_with_template_renderer_no_callable\nFAILED r2e_tests/test_1.py::TestViewDeriver::test_as_instance_requestonly - A...\nFAILED r2e_tests/test_1.py::TestViewDeriver::test_function_returns_non_adaptable\nFAILED r2e_tests/test_1.py::TestViewDeriver::test_function_returns_non_adaptable_dict\nFAILED r2e_tests/test_1.py::TestViewDeriver::test_instance_returns_non_adaptable\nFAILED r2e_tests/test_1.py::TestViewDeriver::test_requestonly_default_method_returns_non_adaptable\nFAILED r2e_tests/test_1.py::TestViewDeriver::test_requestonly_nondefault_method_returns_non_adaptable\nFAILED r2e_tests/test_1.py::Test_view_description::test_without_text - Assert...\nFAILED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_resource_url_adapter_dotted_names\nFAILED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_resource_url_adapter_introspectables\nFAILED r2e_tests/test_config/test_adapters.py::AdaptersConfiguratorMixinTests::test_add_traverser_dotted_names\nFAILED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_filename_no_overrides\nFAILED r2e_tests/test_config/test_assets.py::TestOverrideProvider::test_get_resource_filename_override_returns_None\nFAILED r2e_tests/test_config/test_assets.py::TestPackageOverrides::test_get_filename\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_abspath\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_asset_spec\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_asset_spec_existing_translation_dirs\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_multiple_specs\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_multiple_specs_multiple_calls\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_no_registry\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_noreg_debug_logger_None_default\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_scan_integration_conflict\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_debug_logger_None_default\nFAILED r2e_tests/test_config/test_init.py::TestConfigurator_add_directive::test_add_directive_with_custom_callable\nFAILED r2e_tests/test_config/test_init.py::TestConfigurator_add_directive::test_add_directive_with_partial\nFAILED r2e_tests/test_config/test_init.py::TestConfigurator_add_directive::test_extend_with_dotted_name\nFAILED r2e_tests/test_config/test_init.py::TestConfigurator_add_directive::test_extend_with_python_callable\nFAILED r2e_tests/test_config/test_init.py::TestConfigurator__add_predicate::test_factory_as_dotted_name\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_with_view_defaults\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_with_view_defaults\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_static_view_package_here_relative\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_custom_predicate_bests_standard_predicate\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_custom_predicates_match\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_custom_predicates_nomatch\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_template_renderer\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_template_renderer_no_callable\nFAILED r2e_tests/test_config/test_views.py::TestViewDeriver::test_function_returns_non_adaptable\nFAILED r2e_tests/test_config/test_views.py::TestViewDeriver::test_function_returns_non_adaptable_dict\nFAILED r2e_tests/test_config/test_views.py::TestViewDeriver::test_instance_returns_non_adaptable\nFAILED r2e_tests/test_config/test_views.py::TestViewDeriver::test_requestonly_default_method_returns_non_adaptable\nFAILED r2e_tests/test_config/test_views.py::TestViewDeriver::test_requestonly_nondefault_method_returns_non_adaptable\nFAILED r2e_tests/test_config/test_views.py::Test_view_description::test_without_text\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_display_headers\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_has_content_type_header_var\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_has_good_header_var\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_has_multiple_header_vars\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_get\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_options\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_patch\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_post\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_propfind\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_put\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_path_doesnt_start_with_slash\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_two_args\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_w_basic_auth\nFAILED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_with_query_string\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_function_traversal\n======================= 65 failed, 1046 passed in 6.77s ========================\n",
    "old_commit_res_stderr": ""
}
pyramid/config/views.py pyramid/tests/test_config/test_views.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title:** Forbidden and NotFound Views Ignore `view_defaults`, Causing Predicate Mismatches

**Description:**
When configuring forbidden or notfound views using `config.add_forbidden_view` or `config.add_notfound_view`, the `view_defaults` are being ignored. This leads to predicates not functioning as expected, resulting in the views not behaving correctly based on the default configurations.

**Example Buggy Code:**
```python
from pyramid.config import Configurator
from pyramid.httpexceptions import HTTPForbidden, HTTPNotFound
from zope.interface import directlyProvides, implementedBy

class ForbiddenView:
    __view_defaults__ = {'containment': IDummy}

    def __init__(self, request):
        pass

    def __call__(self):
        return 'OK'

config = Configurator(autocommit=True)
config.add_forbidden_view(view=ForbiddenView, renderer='null_renderer')
wrapper = get_view_callable(config, ctx_iface=implementedBy(HTTPForbidden), request_iface=IRequest)

context = DummyContext()
directlyProvides(context, IDummy)
request = make_request(config)
result = wrapper(context, request)  # Expected to return 'OK'

context = DummyContext()
request = make_request(config)
wrapper(context, request)  # Expected to raise PredicateMismatch
```

**Expected Behavior:**
The `view_defaults` should be correctly applied when adding forbidden or notfound views. This ensures that predicates defined in `view_defaults` are respected, allowing the view to behave as intended based on these defaults.

**Actual Behavior:**
The `view_defaults` are ignored due to the way arguments are handled in `config.add_forbidden_view` and `config.add_notfound_view`. As a result, predicates do not function correctly, leading to unexpected behavior such as not raising `PredicateMismatch` when conditions defined in `view_defaults` are not met.

[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### pyramid/config/views.py
import inspect
import operator
import os
import warnings

from zope.interface import (
    Interface,
    implementedBy,
    implementer,
    provider,
    )

from zope.interface.interfaces import IInterface

from pyramid.interfaces import (
    IAuthenticationPolicy,
    IAuthorizationPolicy,
    IDebugLogger,
    IDefaultPermission,
    IException,
    IExceptionViewClassifier,
    IMultiView,
    IRendererFactory,
    IRequest,
    IResponse,
    IRouteRequest,
    ISecuredView,
    IStaticURLInfo,
    IView,
    IViewClassifier,
    IViewMapper,
    IViewMapperFactory,
    PHASE1_CONFIG,
    )

from pyramid import renderers

from pyramid.compat import (
    string_types,
    urlparse,
    url_quote,
    WIN,
    is_bound_method,
    is_nonstr_iter
    )

from pyramid.exceptions import (
    ConfigurationError,
    PredicateMismatch,
    )

from pyramid.httpexceptions import (
    HTTPForbidden,
    HTTPNotFound,
    )

from pyramid.registry import (
    predvalseq,
    Deferred,
    )

from pyramid.response import Response

from pyramid.security import NO_PERMISSION_REQUIRED
from pyramid.static import static_view
from pyramid.threadlocal import get_current_registry

from pyramid.view import (
    render_view_to_response,
    AppendSlashNotFoundViewFactory,
    )

from pyramid.util import (
    object_description,
    viewdefaults,
    action_method,
    )

import pyramid.config.predicates

from pyramid.config.util import (
    DEFAULT_PHASH,
    MAX_ORDER,
    takes_one_arg,
    )

urljoin = urlparse.urljoin
url_parse = urlparse.urlparse

def view_description(view):
    try:
        return view.__text__
    except AttributeError:
        # custom view mappers might not add __text__
        return object_description(view)

def wraps_view(wrapper):
    def inner(self, view):
        wrapper_view = wrapper(self, view)
        return preserve_view_attrs(view, wrapper_view)
    return inner

def preserve_view_attrs(view, wrapper):
    if view is None:
        return wrapper

    if wrapper is view:
        return view

    original_view = getattr(view, '__original_view__', None)

    if original_view is None:
        original_view = view

    wrapper.__wraps__ = view
    wrapper.__original_view__ = original_view
    wrapper.__module__ = view.__module__
    wrapper.__doc__ = view.__doc__

    try:
        wrapper.__name__ = view.__name__
    except AttributeError:
        wrapper.__name__ = repr(view)

    # attrs that may not exist on "view", but, if so, must be attached to
    # "wrapped view"
    for attr in ('__permitted__', '__call_permissive__', '__permission__',
                 '__predicated__', '__predicates__', '__accept__',
                 '__order__', '__text__'):
        try:
            setattr(wrapper, attr, getattr(view, attr))
        except AttributeError:
            pass

    return wrapper

class ViewDeriver(object):
    def __init__(self, **kw):
        self.kw = kw
        self.registry = kw['registry']
        self.authn_policy = self.registry.queryUtility(IAuthenticationPolicy)
        self.authz_policy = self.registry.queryUtility(IAuthorizationPolicy)
        self.logger = self.registry.queryUtility(IDebugLogger)

    def __call__(self, view):
        return self.attr_wrapped_view(
            self.predicated_view(
                self.authdebug_view(
                    self.secured_view(
                        self.owrapped_view(
                            self.http_cached_view(
                                self.decorated_view(
                                    self.rendered_view(
                                        self.mapped_view(
                                                view)))))))))

    @wraps_view
    def mapped_view(self, view):
        mapper = self.kw.get('mapper')
        if mapper is None:
            mapper = getattr(view, '__view_mapper__', None)
            if mapper is None:
                mapper = self.registry.queryUtility(IViewMapperFactory)
                if mapper is None:
                    mapper = DefaultViewMapper

        mapped_view = mapper(**self.kw)(view)
        return mapped_view

    @wraps_view
    def owrapped_view(self, view):
        wrapper_viewname = self.kw.get('wrapper_viewname')
        viewname = self.kw.get('viewname')
        if not wrapper_viewname:
            return view
        def _owrapped_view(context, request):
            response = view(context, request)
            request.wrapped_response = response
            request.wrapped_body = response.body
            request.wrapped_view = view
            wrapped_response = render_view_to_response(context, request,
                                                       wrapper_viewname)
            if wrapped_response is None:
                raise ValueError(
                    'No wrapper view named %r found when executing view '
                    'named %r' % (wrapper_viewname, viewname))
            return wrapped_response
        return _owrapped_view

    @wraps_view
    def http_cached_view(self, view):
        if self.registry.settings.get('prevent_http_cache', False):
            return view

        seconds = self.kw.get('http_cache')

        if seconds is None:
            return view

        options = {}

        if isinstance(seconds, (tuple, list)):
            try:
                seconds, options = seconds
            except ValueError:
                raise ConfigurationError(
                    'If http_cache parameter is a tuple or list, it must be '
                    'in the form (seconds, options); not %s' % (seconds,))

        def wrapper(context, request):
            response = view(context, request)
            prevent_caching = getattr(response.cache_control, 'prevent_auto',
                                      False)
            if not prevent_caching:
                response.cache_expires(seconds, **options)
            return response

        return wrapper

    @wraps_view
    def secured_view(self, view):
        permission = self.kw.get('permission')
        if permission == NO_PERMISSION_REQUIRED:
            # allow views registered within configurations that have a
            # default permission to explicitly override the default
            # permission, replacing it with no permission at all
            permission = None

        wrapped_view = view
        if self.authn_policy and self.authz_policy and (permission is not None):
            def _permitted(context, request):
                principals = self.authn_policy.effective_principals(request)
                return self.authz_policy.permits(context, principals,
                                                 permission)
            def _secured_view(context, request):
                result = _permitted(context, request)
                if result:
                    return view(context, request)
                view_name = getattr(view, '__name__', view)
                msg = getattr(
                    request, 'authdebug_message',
                    'Unauthorized: %s failed permission check' % view_name)
                raise HTTPForbidden(msg, result=result)
            _secured_view.__call_permissive__ = view
            _secured_view.__permitted__ = _permitted
            _secured_view.__permission__ = permission
            wrapped_view = _secured_view

        return wrapped_view

    @wraps_view
    def authdebug_view(self, view):
        wrapped_view = view
        settings = self.registry.settings
        permission = self.kw.get('permission')
        if settings and settings.get('debug_authorization', False):
            def _authdebug_view(context, request):
                view_name = getattr(request, 'view_name', None)

                if self.authn_policy and self.authz_policy:
                    if permission is NO_PERMISSION_REQUIRED:
                        msg = 'Allowed (NO_PERMISSION_REQUIRED)'
                    elif permission is None:
                        msg = 'Allowed (no permission registered)'
                    else:
                        principals = self.authn_policy.effective_principals(
                            request)
                        msg = str(self.authz_policy.permits(context, principals,
                                                            permission))
                else:
                    msg = 'Allowed (no authorization policy in use)'

                view_name = getattr(request, 'view_name', None)
                url = getattr(request, 'url', None)
                msg = ('debug_authorization of url %s (view name %r against '
                       'context %r): %s' % (url, view_name, context, msg))
                self.logger and self.logger.debug(msg)
                if request is not None:
                    request.authdebug_message = msg
                return view(context, request)

            wrapped_view = _authdebug_view

        return wrapped_view

    @wraps_view
    def predicated_view(self, view):
        preds = self.kw.get('predicates', ())
        if not preds:
            return view
        def predicate_wrapper(context, request):
            for predicate in preds:
                if not predicate(context, request):
                    view_name = getattr(view, '__name__', view)
                    raise PredicateMismatch(
                         'predicate mismatch for view %s (%s)' % (
                         view_name, predicate.text()))
            return view(context, request)        
        def checker(context, request):
            return all((predicate(context, request) for predicate in
                        preds))
        predicate_wrapper.__predicated__ = checker
        predicate_wrapper.__predicates__ = preds
        return predicate_wrapper

    @wraps_view
    def attr_wrapped_view(self, view):
        kw = self.kw
        accept, order, phash = (kw.get('accept', None),
                                kw.get('order', MAX_ORDER),
                                kw.get('phash', DEFAULT_PHASH))
        # this is a little silly but we don't want to decorate the original
        # function with attributes that indicate accept, order, and phash,
        # so we use a wrapper
        if (
            (accept is None) and
            (order == MAX_ORDER) and
            (phash == DEFAULT_PHASH)
            ):
            return view # defaults
        def attr_view(context, request):
            return view(context, request)
        attr_view.__accept__ = accept
        attr_view.__order__ = order
        attr_view.__phash__ = phash
        attr_view.__view_attr__ = self.kw.get('attr')
        attr_view.__permission__ = self.kw.get('permission')
        return attr_view

    @wraps_view
    def rendered_view(self, view):
        # one way or another this wrapper must produce a Response (unless
        # the renderer is a NullRendererHelper)
        renderer = self.kw.get('renderer')
        if renderer is None:
            # register a default renderer if you want super-dynamic
            # rendering.  registering a default renderer will also allow
            # override_renderer to work if a renderer is left unspecified for
            # a view registration.
            return self._response_resolved_view(view)
        if renderer is renderers.null_renderer:
            return view
        return self._rendered_view(view, renderer)

    def _rendered_view(self, view, view_renderer):
        def rendered_view(context, request):
            renderer = view_renderer
            result = view(context, request)
            if result.__class__ is Response: # potential common case
                response = result
            else:
                registry = self.registry
                # this must adapt, it can't do a simple interface check
                # (avoid trying to render webob responses)
                response = registry.queryAdapterOrSelf(result, IResponse)
                if response is None:
                    attrs = getattr(request, '__dict__', {})
                    if 'override_renderer' in attrs:
                        # renderer overridden by newrequest event or other
                        renderer_name = attrs.pop('override_renderer')
                        renderer = renderers.RendererHelper(
                            name=renderer_name,
                            package=self.kw.get('package'),
                            registry = registry)
                    if '__view__' in attrs:
                        view_inst = attrs.pop('__view__')
                    else:
                        view_inst = getattr(view, '__original_view__', view)
                    response = renderer.render_view(request, result, view_inst,
                                                    context)
            return response

        return rendered_view

    def _response_resolved_view(self, view):
        registry = self.registry
        def viewresult_to_response(context, request):
            result = view(context, request)
            if result.__class__ is Response: # common case
                response = result
            else:
                response = registry.queryAdapterOrSelf(result, IResponse)
                if response is None:
                    if result is None:
                        append = (' You may have forgotten to return a value '
                                  'from the view callable.')
                    elif isinstance(result, dict):
                        append = (' You may have forgotten to define a '
                                  'renderer in the view configuration.')
                    else:
                        append = ''

                    msg = ('Could not convert return value of the view '
                           'callable %s into a response object. '
                           'The value returned was %r.' + append)

                    raise ValueError(msg % (view_description(view), result))

            return response

        return viewresult_to_response

    @wraps_view
    def decorated_view(self, view):
        decorator = self.kw.get('decorator')
        if decorator is None:
            return view
        return decorator(view)

@implementer(IViewMapper)
@provider(IViewMapperFactory)
class DefaultViewMapper(object):
    def __init__(self, **kw):
        self.attr = kw.get('attr')

    def __call__(self, view):
        if inspect.isclass(view):
            view = self.map_class(view)
        else:
            view = self.map_nonclass(view)
        return view

    def map_class(self, view):
        ronly = requestonly(view, self.attr)
        if ronly:
            mapped_view = self.map_class_requestonly(view)
        else:
            mapped_view = self.map_class_native(view)
        mapped_view.__text__ = 'method %s of %s' % (
            self.attr or '__call__', object_description(view))
        return mapped_view

    def map_nonclass(self, view):
        # We do more work here than appears necessary to avoid wrapping the
        # view unless it actually requires wrapping (to avoid function call
        # overhead).
        mapped_view = view
        ronly = requestonly(view, self.attr)
        if ronly:
            mapped_view = self.map_nonclass_requestonly(view)
        elif self.attr:
            mapped_view = self.map_nonclass_attr(view)
        if inspect.isroutine(mapped_view):
            # This branch will be true if the view is a function or a method.
            # We potentially mutate an unwrapped object here if it's a
            # function.  We do this to avoid function call overhead of
            # injecting another wrapper.  However, we must wrap if the
            # function is a bound method because we can't set attributes on a
            # bound method.
            if is_bound_method(view):
                _mapped_view = mapped_view
                def mapped_view(context, request):
                    return _mapped_view(context, request)
            if self.attr is not None:
                mapped_view.__text__ = 'attr %s of %s' % (
                    self.attr, object_description(view))
            else:
                mapped_view.__text__ = object_description(view)
        return mapped_view

    def map_class_requestonly(self, view):
        # its a class that has an __init__ which only accepts request
        attr = self.attr
        def _class_requestonly_view(context, request):
            inst = view(request)
            request.__view__ = inst
            if attr is None:
                response = inst()
            else:
                response = getattr(inst, attr)()
            return response
        return _class_requestonly_view

    def map_class_native(self, view):
        # its a class that has an __init__ which accepts both context and
        # request
        attr = self.attr
        def _class_view(context, request):
            inst = view(context, request)
            request.__view__ = inst
            if attr is None:
                response = inst()
            else:
                response = getattr(inst, attr)()
            return response
        return _class_view

    def map_nonclass_requestonly(self, view):
        # its a function that has a __call__ which accepts only a single
        # request argument
        attr = self.attr
        def _requestonly_view(context, request):
            if attr is None:
                response = view(request)
            else:
                response = getattr(view, attr)(request)
            return response
        return _requestonly_view

    def map_nonclass_attr(self, view):
        # its a function that has a __call__ which accepts both context and
        # request, but still has an attr
        def _attr_view(context, request):
            response = getattr(view, self.attr)(context, request)
            return response
        return _attr_view

def requestonly(view, attr=None):
    return takes_one_arg(view, attr=attr, argname='request')

@implementer(IMultiView)
class MultiView(object):

    def __init__(self, name):
        self.name = name
        self.media_views = {}
        self.views = []
        self.accepts = []

    def __discriminator__(self, context, request):
        # used by introspection systems like so:
        # view = adapters.lookup(....)
        # view.__discriminator__(context, request) -> view's discriminator
        # so that superdynamic systems can feed the discriminator to
        # the introspection system to get info about it
        view = self.match(context, request)
        return view.__discriminator__(context, request)

    def add(self, view, order, accept=None, phash=None):
        if phash is not None:
            for i, (s, v, h) in enumerate(list(self.views)):
                if phash == h:
                    self.views[i] = (order, view, phash)
                    return

        if accept is None or '*' in accept:
            self.views.append((order, view, phash))
            self.views.sort(key=operator.itemgetter(0))
        else:
            subset = self.media_views.setdefault(accept, [])
            for i, (s, v, h) in enumerate(list(subset)):
                if phash == h:
                    subset[i] = (order, view, phash)
                    return
            else:
                subset.append((order, view, phash))
                subset.sort(key=operator.itemgetter(0))
            accepts = set(self.accepts)
            accepts.add(accept)
            self.accepts = list(accepts) # dedupe

    def get_views(self, request):
        if self.accepts and hasattr(request, 'accept'):
            accepts = self.accepts[:]
            views = []
            while accepts:
                match = request.accept.best_match(accepts)
                if match is None:
                    break
                subset = self.media_views[match]
                views.extend(subset)
                accepts.remove(match)
            views.extend(self.views)
            return views
        return self.views

    def match(self, context, request):
        for order, view, phash in self.get_views(request):
            if not hasattr(view, '__predicated__'):
                return view
            if view.__predicated__(context, request):
                return view
        raise PredicateMismatch(self.name)

    def __permitted__(self, context, request):
        view = self.match(context, request)
        if hasattr(view, '__permitted__'):
            return view.__permitted__(context, request)
        return True

    def __call_permissive__(self, context, request):
        view = self.match(context, request)
        view = getattr(view, '__call_permissive__', view)
        return view(context, request)

    def __call__(self, context, request):
        for order, view, phash in self.get_views(request):
            try:
                return view(context, request)
            except PredicateMismatch:
                continue
        raise PredicateMismatch(self.name)

class ViewsConfiguratorMixin(object):
    @viewdefaults
    @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,
        renderer=None,
        wrapper=None,
        xhr=None,
        accept=None,
        header=None,
        path_info=None,
        custom_predicates=(),
        context=None,
        decorator=None,
        mapper=None,
        http_cache=None,
        match_param=None,
        check_csrf=None,
        **predicates):
        """ Add a :term:`view configuration` to the current
        configuration state.  Arguments to ``add_view`` are broken
        down below into *predicate* arguments and *non-predicate*
        arguments.  Predicate arguments narrow the circumstances in
        which the view callable will be invoked when a request is
        presented to :app:`Pyramid`; non-predicate arguments are
        informational.

        Non-Predicate Arguments

        view

          A :term:`view callable` or a :term:`dotted Python name`
          which refers to a view callable.  This argument is required
          unless a ``renderer`` argument also exists.  If a
          ``renderer`` argument is passed, and a ``view`` argument is
          not provided, the view callable defaults to a callable that
          returns an empty dictionary (see
          :ref:`views_which_use_a_renderer`).

        permission

          A :term:`permission` that the user must possess in order to invoke
          the :term:`view callable`.  See :ref:`view_security_section` for
          more information about view security and permissions.  This is
          often a string like ``view`` or ``edit``.

          If ``permission`` is omitted, a *default* permission may be used
          for this view registration if one was named as the
          :class:`pyramid.config.Configurator` constructor's
          ``default_permission`` argument, or if
          :meth:`pyramid.config.Configurator.set_default_permission` was used
          prior to this view registration.  Pass the value
          :data:`pyramid.security.NO_PERMISSION_REQUIRED` as the permission
          argument to explicitly indicate that the view should always be
          executable by entirely anonymous users, regardless of the default
          permission, bypassing any :term:`authorization policy` that may be
          in effect.

        attr

          This knob is most useful when the view definition is a class.

          The view machinery defaults to using the ``__call__`` method
          of the :term:`view callable` (or the function itself, if the
          view callable is a function) to obtain a response.  The
          ``attr`` value allows you to vary the method attribute used
          to obtain the response.  For example, if your view was a
          class, and the class has a method named ``index`` and you
          wanted to use this method instead of the class' ``__call__``
          method to return the response, you'd say ``attr="index"`` in the
          view configuration for the view.

        renderer

          This is either a single string term (e.g. ``json``) or a
          string implying a path or :term:`asset specification`
          (e.g. ``templates/views.pt``) naming a :term:`renderer`
          implementation.  If the ``renderer`` value does not contain
          a dot ``.``, the specified string will be used to look up a
          renderer implementation, and that renderer implementation
          will be used to construct a response from the view return
          value.  If the ``renderer`` value contains a dot (``.``),
          the specified term will be treated as a path, and the
          filename extension of the last element in the path will be
          used to look up the renderer implementation, which will be
          passed the full path.  The renderer implementation will be
          used to construct a :term:`response` from the view return
          value.

          Note that if the view itself returns a :term:`response` (see
          :ref:`the_response`), the specified renderer implementation
          is never called.

          When the renderer is a path, although a path is usually just
          a simple relative pathname (e.g. ``templates/foo.pt``,
          implying that a template named "foo.pt" is in the
          "templates" directory relative to the directory of the
          current :term:`package` of the Configurator), a path can be
          absolute, starting with a slash on UNIX or a drive letter
          prefix on Windows.  The path can alternately be a
          :term:`asset specification` in the form
          ``some.dotted.package_name:relative/path``, making it
          possible to address template assets which live in a
          separate package.

          The ``renderer`` attribute is optional.  If it is not
          defined, the "null" renderer is assumed (no rendering is
          performed and the value is passed back to the upstream
          :app:`Pyramid` machinery unmodified).

        http_cache

          .. versionadded:: 1.1

          When you supply an ``http_cache`` value to a view configuration,
          the ``Expires`` and ``Cache-Control`` headers of a response
          generated by the associated view callable are modified.  The value
          for ``http_cache`` may be one of the following:

          - A nonzero integer.  If it's a nonzero integer, it's treated as a
            number of seconds.  This number of seconds will be used to
            compute the ``Expires`` header and the ``Cache-Control:
            max-age`` parameter of responses to requests which call this view.
            For example: ``http_cache=3600`` instructs the requesting browser
            to 'cache this response for an hour, please'.

          - A ``datetime.timedelta`` instance.  If it's a
            ``datetime.timedelta`` instance, it will be converted into a
            number of seconds, and that number of seconds will be used to
            compute the ``Expires`` header and the ``Cache-Control:
            max-age`` parameter of responses to requests which call this view.
            For example: ``http_cache=datetime.timedelta(days=1)`` instructs
            the requesting browser to 'cache this response for a day, please'.

          - Zero (``0``).  If the value is zero, the ``Cache-Control`` and
            ``Expires`` headers present in all responses from this view will
            be composed such that client browser cache (and any intermediate
            caches) are instructed to never cache the response.

          - A two-tuple.  If it's a two tuple (e.g. ``http_cache=(1,
            {'public':True})``), the first value in the tuple may be a
            nonzero integer or a ``datetime.timedelta`` instance; in either
            case this value will be used as the number of seconds to cache
            the response.  The second value in the tuple must be a
            dictionary.  The values present in the dictionary will be used as
            input to the ``Cache-Control`` response header.  For example:
            ``http_cache=(3600, {'public':True})`` means 'cache for an hour,
            and add ``public`` to the Cache-Control header of the response'.
            All keys and values supported by the
            ``webob.cachecontrol.CacheControl`` interface may be added to the
            dictionary.  Supplying ``{'public':True}`` is equivalent to
            calling ``response.cache_control.public = True``.

          Providing a non-tuple value as ``http_cache`` is equivalent to
          calling ``response.cache_expires(value)`` within your view's body.

          Providing a two-tuple value as ``http_cache`` is equivalent to
          calling ``response.cache_expires(value[0], **value[1])`` within your
          view's body.

          If you wish to avoid influencing, the ``Expires`` header, and
          instead wish to only influence ``Cache-Control`` headers, pass a
          tuple as ``http_cache`` with the first element of ``None``, e.g.:
          ``(None, {'public':True})``.

          If you wish to prevent a view that uses ``http_cache`` in its
          configuration from having its caching response headers changed by
          this machinery, set ``response.cache_control.prevent_auto = True``
          before returning the response from the view.  This effectively
          disables any HTTP caching done by ``http_cache`` for that response.

        wrapper

          The :term:`view name` of a different :term:`view
          configuration` which will receive the response body of this
          view as the ``request.wrapped_body`` attribute of its own
          :term:`request`, and the :term:`response` returned by this
          view as the ``request.wrapped_response`` attribute of its
          own request.  Using a wrapper makes it possible to "chain"
          views together to form a composite response.  The response
          of the outermost wrapper view will be returned to the user.
          The wrapper view will be found as any view is found: see
          :ref:`view_lookup`.  The "best" wrapper view will be found
          based on the lookup ordering: "under the hood" this wrapper
          view is looked up via
          ``pyramid.view.render_view_to_response(context, request,
          'wrapper_viewname')``. The context and request of a wrapper
          view is the same context and request of the inner view.  If
          this attribute is unspecified, no view wrapping is done.

        decorator

          A :term:`dotted Python name` to function (or the function itself,
          or an iterable of the aforementioned) which will be used to
          decorate the registered :term:`view callable`.  The decorator
          function(s) will be called with the view callable as a single
          argument.  The view callable it is passed will accept
          ``(context, request)``.  The decorator(s) must return a
          replacement view callable which also accepts ``(context,
          request)``.

          If decorator is an iterable, the callables will be combined and
          used in the order provided as a decorator.
          For example::

            @view_config(...,
                decorator=(decorator2,
                           decorator1))
            def myview(request):
                ....

          Is similar to doing::

            @view_config(...)
            @decorator2
            @decorator1
            def myview(request):
                ...

          Except with the existing benefits of ``decorator=`` (having a common
          decorator syntax for all view calling conventions and not having to
          think about preserving function attributes such as ``__name__`` and
          ``__module__`` within decorator logic).

          .. versionchanged:: 1.4a4
             Passing an iterable.

        mapper

          A Python object or :term:`dotted Python name` which refers to a
          :term:`view mapper`, or ``None``.  By default it is ``None``, which
          indicates that the view should use the default view mapper.  This
          plug-point is useful for Pyramid extension developers, but it's not
          very useful for 'civilians' who are just developing stock Pyramid
          applications. Pay no attention to the man behind the curtain.

        Predicate Arguments

        name

          The :term:`view name`.  Read :ref:`traversal_chapter` to
          understand the concept of a view name.

        context

          An object or a :term:`dotted Python name` referring to an
          interface or class object that the :term:`context` must be
          an instance of, *or* the :term:`interface` that the
          :term:`context` must provide in order for this view to be
          found and called.  This predicate is true when the
          :term:`context` is an instance of the represented class or
          if the :term:`context` provides the represented interface;
          it is otherwise false.  This argument may also be provided
          to ``add_view`` as ``for_`` (an older, still-supported
          spelling).

        route_name

          This value must match the ``name`` of a :term:`route
          configuration` declaration (see :ref:`urldispatch_chapter`)
          that must match before this view will be called.

        request_type

          This value should be an :term:`interface` that the
          :term:`request` must provide in order for this view to be
          found and called.  This value exists only for backwards
          compatibility purposes.

        request_method

          This value can be one of the strings ``GET``, ``POST``, ``PUT``,
          ``DELETE``, or ``HEAD`` representing an HTTP ``REQUEST_METHOD``, or
          a tuple containing one or more of these strings.  A view
          declaration with this argument ensures that the view will only be
          called when the request's ``method`` attribute (aka the
          ``REQUEST_METHOD`` of the WSGI environment) string matches a
          supplied value.  Note that use of ``GET`` also implies that the
          view will respond to ``HEAD`` as of Pyramid 1.4.

          .. versionchanged:: 1.2
             The ability to pass a tuple of items as ``request_method``.
             Previous versions allowed only a string.

        request_param

          This value can be any string or any sequence of strings.  A view 
          declaration with this argument ensures that the view will only be 
          called when the :term:`request` has a key in the ``request.params``
          dictionary (an HTTP ``GET`` or ``POST`` variable) that has a
          name which matches the supplied value (if the value is a string)
          or values (if the value is a tuple).  If any value
          supplied has a ``=`` sign in it,
          e.g. ``request_param="foo=123"``, then the key (``foo``)
          must both exist in the ``request.params`` dictionary, *and*
          the value must match the right hand side of the expression
          (``123``) for the view to "match" the current request.

        match_param

          .. versionadded:: 1.2

          This value can be a string of the format "key=value" or a tuple
          containing one or more of these strings.

          A view declaration with this argument ensures that the view will
          only be called when the :term:`request` has key/value pairs in its
          :term:`matchdict` that equal those supplied in the predicate.
          e.g. ``match_param="action=edit" would require the ``action``
          parameter in the :term:`matchdict` match the right hand side of
          the expression (``edit``) for the view to "match" the current
          request.

          If the ``match_param`` is a tuple, every key/value pair must match
          for the predicate to pass.

        containment

          This value should be a Python class or :term:`interface` (or a
          :term:`dotted Python name`) that an object in the
          :term:`lineage` of the context must provide in order for this view
          to be found and called.  The nodes in your object graph must be
          "location-aware" to use this feature.  See
          :ref:`location_aware` for more information about
          location-awareness.

        xhr

          This value should be either ``True`` or ``False``.  If this
          value is specified and is ``True``, the :term:`request`
          must possess an ``HTTP_X_REQUESTED_WITH`` (aka
          ``X-Requested-With``) header that has the value
          ``XMLHttpRequest`` for this view to be found and called.
          This is useful for detecting AJAX requests issued from
          jQuery, Prototype and other Javascript libraries.

        accept

          The value of this argument represents a match query for one
          or more mimetypes in the ``Accept`` HTTP request header.  If
          this value is specified, it must be in one of the following
          forms: a mimetype match token in the form ``text/plain``, a
          wildcard mimetype match token in the form ``text/*`` or a
          match-all wildcard mimetype match token in the form ``*/*``.
          If any of the forms matches the ``Accept`` header of the
          request, this predicate will be true.

        header

          This value represents an HTTP header name or a header
          name/value pair.  If the value contains a ``:`` (colon), it
          will be considered a name/value pair
          (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``).  The
          value portion should be a regular expression.  If the value
          does not contain a colon, the entire value will be
          considered to be the header name
          (e.g. ``If-Modified-Since``).  If the value evaluates to a
          header name only without a value, the header specified by
          the name must be present in the request for this predicate
          to be true.  If the value evaluates to a header name/value
          pair, the header specified by the name must be present in
          the request *and* the regular expression specified as the
          value must match the header value.  Whether or not the value
          represents a header name or a header name/value pair, the
          case of the header name is not significant.

        path_info

          This value represents a regular expression pattern that will
          be tested against the ``PATH_INFO`` WSGI environment
          variable.  If the regex matches, this predicate will be
          ``True``.

        check_csrf

          If specified, this value should be one of ``None``, ``True``,
          ``False``, or a string representing the 'check name'.  If the value
          is ``True`` or a string, CSRF checking will be performed.  If the
          value is ``False`` or ``None``, CSRF checking will not be performed.

          If the value provided is a string, that string will be used as the
          'check name'.  If the value provided is ``True``, ``csrf_token`` will
          be used as the check name.

          If CSRF checking is performed, the checked value will be the value
          of ``request.params[check_name]``.  This value will be compared
          against the value of ``request.session.get_csrf_token()``, and the
          check will pass if these two values are the same.  If the check
          passes, the associated view will be permitted to execute.  If the
          check fails, the associated view will not be permitted to execute.

          Note that using this feature requires a :term:`session factory` to
          have been configured.
         
          .. versionadded:: 1.4a2

        physical_path

          If specified, this value should be a string or a tuple representing
          the :term:`physical path` of the context found via traversal for this
          predicate to match as true.  For example: ``physical_path='/'`` or
          ``physical_path='/a/b/c'`` or ``physical_path=('', 'a', 'b', 'c')``.
          This is not a path prefix match or a regex, it's a whole-path match.
          It's useful when you want to always potentially show a view when some
          object is traversed to, but you can't be sure about what kind of
          object it will be, so you can't use the ``context`` predicate.  The
          individual path elements inbetween slash characters or in tuple
          elements should be the Unicode representation of the name of the
          resource and should not be encoded in any way.

          .. versionadded:: 1.4a3

        effective_principals

          If specified, this value should be a :term:`principal` identifier or
          a sequence of principal identifiers.  If the
          :func:`pyramid.security.effective_principals` method indicates that
          every principal named in the argument list is present in the current
          request, this predicate will return True; otherwise it will return
          False.  For example:
          ``effective_principals=pyramid.security.Authenticated`` or
          ``effective_principals=('fred', 'group:admins')``.

          .. versionadded:: 1.4a4

        custom_predicates

          .. deprecated:: 1.5

          This value should be a sequence of references to custom predicate
          callables.  Use custom predicates when no set of predefined
          predicates do what you need.  Custom predicates can be combined with
          predefined predicates as necessary.  Each custom predicate callable
          should accept two arguments: ``context`` and ``request`` and should
          return either ``True`` or ``False`` after doing arbitrary evaluation
          of the context and/or the request.  The ``predicates`` argument to
          this method and the ability to register third-party view predicates
          via :meth:`pyramid.config.Configurator.add_view_predicate` obsoletes
          this argument, but it is kept around for backwards compatibility.

        predicates

          Pass a key/value pair here to use a third-party predicate
          registered via
          :meth:`pyramid.config.Configurator.add_view_predicate`.  More than
          one key/value pair can be used at the same time.  See
          :ref:`view_and_route_predicates` for more information about
          third-party predicates.

          .. versionadded: 1.4a1

        """
        if custom_predicates:
            warnings.warn(
                ('The "custom_predicates" argument to Configurator.add_view '
                 'is deprecated as of Pyramid 1.5.  Use '
                 '"config.add_view_predicate" and use the registered '
                 'view predicate as a predicate argument to add_view instead. '
                 'See "Adding A Third Party View, Route, or Subscriber '
                 'Predicate" in the "Hooks" chapter of the documentation '
                 'for more information.'),
                DeprecationWarning,
                stacklevel=4
                )
        
        view = self.maybe_dotted(view)
        context = self.maybe_dotted(context)
        for_ = self.maybe_dotted(for_)
        containment = self.maybe_dotted(containment)
        mapper = self.maybe_dotted(mapper)

        def combine(*decorators):
            def decorated(view_callable):
                # reversed() is allows a more natural ordering in the api
                for decorator in reversed(decorators):
                    view_callable = decorator(view_callable)
                return view_callable
            return decorated

        if is_nonstr_iter(decorator):
            decorator = combine(*map(self.maybe_dotted, decorator))
        else:
            decorator = self.maybe_dotted(decorator)

        if not view:
            if renderer:
                def view(context, request):
                    return {}
            else:
                raise ConfigurationError('"view" was not specified and '
                                         'no "renderer" specified')

        if request_type is not None:
            request_type = self.maybe_dotted(request_type)
            if not IInterface.providedBy(request_type):
                raise ConfigurationError(
                    'request_type must be an interface, not %s' % request_type)

        if context is None:
            context = for_

        r_context = context
        if r_context is None:
            r_context = Interface
        if not IInterface.providedBy(r_context):
            r_context = implementedBy(r_context)

        if isinstance(renderer, string_types):
            renderer = renderers.RendererHelper(
                name=renderer, package=self.package,
                registry = self.registry)

        if accept is not None:
            accept = accept.lower()

        introspectables = []
        pvals = predicates.copy()
        pvals.update(
            dict(
                xhr=xhr,
                request_method=request_method,
                path_info=path_info,
                request_param=request_param,
                header=header,
                accept=accept,
                containment=containment,
                request_type=request_type,
                match_param=match_param,
                check_csrf=check_csrf,
                custom=predvalseq(custom_predicates),
                )
            )

        def discrim_func():
            # We need to defer the discriminator until we know what the phash
            # is.  It can't be computed any sooner because thirdparty
            # predicates may not yet exist when add_view is called.
            order, preds, phash = predlist.make(self, **pvals)
            view_intr.update({'phash':phash, 'order':order, 'predicates':preds})
            return ('view', context, name, route_name, phash)

        discriminator = Deferred(discrim_func)

        if inspect.isclass(view) and attr:
            view_desc = 'method %r of %s' % (
                attr, self.object_description(view))
        else:
            view_desc = self.object_description(view)

        tmpl_intr = None
            
        view_intr = self.introspectable('views',
                                        discriminator,
                                        view_desc,
                                        'view')
        view_intr.update(
            dict(name=name,
                 context=context,
                 containment=containment,
                 request_param=request_param,
                 request_methods=request_method,
                 route_name=route_name,
                 attr=attr,
                 xhr=xhr,
                 accept=accept,
                 header=header,
                 path_info=path_info,
                 match_param=match_param,
                 check_csrf=check_csrf,
                 callable=view,
                 mapper=mapper,
                 decorator=decorator,
                 )
            )
        view_intr.update(**predicates)
        introspectables.append(view_intr)
        predlist = self.get_predlist('view')

        def register(permission=permission, renderer=renderer):
            # the discrim_func above is guaranteed to have been called already
            order = view_intr['order']
            preds = view_intr['predicates']
            phash = view_intr['phash']
            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 (reg'd in phase 1)
                if self.registry.queryUtility(IRendererFactory) is not None:
                    renderer = renderers.RendererHelper(
                        name=None,
                        package=self.package,
                        registry=self.registry
                        )

            if permission is None:
                # intent: will be None if no default permission is registered
                # (reg'd in phase 1)
                permission = self.registry.queryUtility(IDefaultPermission)

            # added by discrim_func above during conflict resolving
            preds = view_intr['predicates']
            order = view_intr['order']
            phash = view_intr['phash']

            # __no_permission_required__ handled by _secure_view
            deriver = ViewDeriver(
                registry=self.registry,
                permission=permission,
                predicates=preds,
                attr=attr,
                renderer=renderer,
                wrapper_viewname=wrapper,
                viewname=name,
                accept=accept,
                order=order,
                phash=phash,
                package=self.package,
                mapper=mapper,
                decorator=decorator,
                http_cache=http_cache,
                )
            derived_view = deriver(view)
            derived_view.__discriminator__ = lambda *arg: discriminator
            # __discriminator__ is used by superdynamic systems
            # that require it for introspection after manual view lookup;
            # see also MultiView.__discriminator__
            view_intr['derived_callable'] = derived_view

            registered = self.registry.adapters.registered

            # A multiviews is a set of views which are registered for
            # exactly the same context type/request type/name triad.  Each
            # consituent view in a multiview differs only by the
            # predicates which it possesses.

            # To find a previously registered view for a context
            # type/request type/name triad, we need to use the
            # ``registered`` method of the adapter registry rather than
            # ``lookup``.  ``registered`` ignores interface inheritance
            # for the required and provided arguments, returning only a
            # view registered previously with the *exact* triad we pass
            # in.

            # We need to do this three times, because we use three
            # different interfaces as the ``provided`` interface while
            # doing registrations, and ``registered`` performs exact
            # matches on all the arguments it receives.

            old_view = None

            for view_type in (IView, ISecuredView, IMultiView):
                old_view = registered((IViewClassifier, request_iface,
                                       r_context), view_type, name)
                if old_view is not None:
                    break

            isexc = isexception(context)

            def regclosure():
                if hasattr(derived_view, '__call_permissive__'):
                    view_iface = ISecuredView
                else:
                    view_iface = IView
                self.registry.registerAdapter(
                    derived_view,
                    (IViewClassifier, request_iface, context), view_iface, name
                    )
                if isexc:
                    self.registry.registerAdapter(
                        derived_view,
                        (IExceptionViewClassifier, request_iface, context),
                        view_iface, name)

            is_multiview = IMultiView.providedBy(old_view)
            old_phash = getattr(old_view, '__phash__', DEFAULT_PHASH)

            if old_view is None:
                # - No component was yet registered for any of our I*View
                #   interfaces exactly; this is the first view for this
                #   triad.
                regclosure()

            elif (not is_multiview) and (old_phash == phash):
                # - A single view component was previously registered with
                #   the same predicate hash as this view; this registration
                #   is therefore an override.
                regclosure()

            else:
                # - A view or multiview was already registered for this
                #   triad, and the new view is not an override.

                # XXX we could try to be more efficient here and register
                # a non-secured view for a multiview if none of the
                # multiview's consituent views have a permission
                # associated with them, but this code is getting pretty
                # rough already
                if is_multiview:
                    multiview = old_view
                else:
                    multiview = MultiView(name)
                    old_accept = getattr(old_view, '__accept__', None)
                    old_order = getattr(old_view, '__order__', MAX_ORDER)
                    multiview.add(old_view, old_order, old_accept, old_phash)
                multiview.add(derived_view, order, accept, phash)
                for view_type in (IView, ISecuredView):
                    # unregister any existing views
                    self.registry.adapters.unregister(
                        (IViewClassifier, request_iface, r_context),
                        view_type, name=name)
                    if isexc:
                        self.registry.adapters.unregister(
                            (IExceptionViewClassifier, request_iface,
                             r_context), view_type, name=name)
                self.registry.registerAdapter(
                    multiview,
                    (IViewClassifier, request_iface, context),
                    IMultiView, name=name)
                if isexc:
                    self.registry.registerAdapter(
                        multiview,
                        (IExceptionViewClassifier, request_iface, context),
                        IMultiView, name=name)
            renderer_type = getattr(renderer, 'type', None) # gard against None
            intrspc = self.introspector
            if (
                renderer_type is not None and
                tmpl_intr is not None and
                intrspc is not None and
                intrspc.get('renderer factories', renderer_type) is not None
                ):
                # allow failure of registered template factories to be deferred
                # until view execution, like other bad renderer factories; if
                # we tried to relate this to an existing renderer factory
                # without checking if it the factory actually existed, we'd end
                # up with a KeyError at startup time, which is inconsistent
                # with how other bad renderer registrations behave (they throw
                # a ValueError at view execution time)
                tmpl_intr.relate('renderer factories', renderer.type)

        if mapper:
            mapper_intr = self.introspectable(
                'view mappers',
                discriminator,
                'view mapper for %s' % view_desc,
                'view mapper'
                )
            mapper_intr['mapper'] = mapper
            mapper_intr.relate('views', discriminator)
            introspectables.append(mapper_intr)
        if route_name:
            view_intr.relate('routes', route_name) # see add_route
        if renderer is not None and renderer.name and '.' in renderer.name:
            # the renderer is a template
            tmpl_intr = self.introspectable(
                'templates',
                discriminator,
                renderer.name,
                'template'
                )
            tmpl_intr.relate('views', discriminator)
            tmpl_intr['name'] = renderer.name
            tmpl_intr['type'] = renderer.type
            tmpl_intr['renderer'] = renderer
            introspectables.append(tmpl_intr)
        if permission is not None:
            # if a permission exists, register a permission introspectable
            perm_intr = self.introspectable(
                'permissions',
                permission,
                permission,
                'permission'
                )
            perm_intr['value'] = permission
            perm_intr.relate('views', discriminator)
            introspectables.append(perm_intr)
        self.action(discriminator, register, introspectables=introspectables)

    @action_method
    def add_view_predicate(self, name, factory, weighs_more_than=None,
                           weighs_less_than=None):
        """
        .. versionadded:: 1.4

        Adds a view predicate factory.  The associated view predicate can
        later be named as a keyword argument to
        :meth:`pyramid.config.Configurator.add_view` in the
        ``predicates`` anonyous keyword argument dictionary.

        ``name`` should be the name of the predicate.  It must be a valid
        Python identifier (it will be used as a keyword argument to
        ``add_view`` by others).

        ``factory`` should be a :term:`predicate factory` or :term:`dotted
        Python name` which refers to a predicate factory.

        See :ref:`view_and_route_predicates` for more information.
        """
        self._add_predicate(
            'view',
            name,
            factory,
            weighs_more_than=weighs_more_than,
            weighs_less_than=weighs_less_than
            )

    def add_default_view_predicates(self):
        p = pyramid.config.predicates
        for (name, factory) in (
            ('xhr', p.XHRPredicate),
            ('request_method', p.RequestMethodPredicate),
            ('path_info', p.PathInfoPredicate),
            ('request_param', p.RequestParamPredicate),
            ('header', p.HeaderPredicate),
            ('accept', p.AcceptPredicate),
            ('containment', p.ContainmentPredicate),
            ('request_type', p.RequestTypePredicate),
            ('match_param', p.MatchParamPredicate),
            ('check_csrf', p.CheckCSRFTokenPredicate),
            ('physical_path', p.PhysicalPathPredicate),
            ('effective_principals', p.EffectivePrincipalsPredicate),
            ('custom', p.CustomPredicate),
            ):
            self.add_view_predicate(name, factory)

    def derive_view(self, view, attr=None, renderer=None):
        """
        Create a :term:`view callable` using the function, instance,
        or class (or :term:`dotted Python name` referring to the same)
        provided as ``view`` object.

        .. warning::

           This method is typically only used by :app:`Pyramid` framework
           extension authors, not by :app:`Pyramid` application developers.

        This is API is useful to framework extenders who create
        pluggable systems which need to register 'proxy' view
        callables for functions, instances, or classes which meet the
        requirements of being a :app:`Pyramid` view callable.  For
        example, a ``some_other_framework`` function in another
        framework may want to allow a user to supply a view callable,
        but he may want to wrap the view callable in his own before
        registering the wrapper as a :app:`Pyramid` view callable.
        Because a :app:`Pyramid` view callable can be any of a
        number of valid objects, the framework extender will not know
        how to call the user-supplied object.  Running it through
        ``derive_view`` normalizes it to a callable which accepts two
        arguments: ``context`` and ``request``.

        For example:

        .. code-block:: python

           def some_other_framework(user_supplied_view):
               config = Configurator(reg)
               proxy_view = config.derive_view(user_supplied_view)
               def my_wrapper(context, request):
                   do_something_that_mutates(request)
                   return proxy_view(context, request)
               config.add_view(my_wrapper)

        The ``view`` object provided should be one of the following:

        - A function or another non-class callable object that accepts
          a :term:`request` as a single positional argument and which
          returns a :term:`response` object.

        - A function or other non-class callable object that accepts
          two positional arguments, ``context, request`` and which
          returns a :term:`response` object.

        - A class which accepts a single positional argument in its
          constructor named ``request``, and which has a ``__call__``
          method that accepts no arguments that returns a
          :term:`response` object.

        - A class which accepts two positional arguments named
          ``context, request``, and which has a ``__call__`` method
          that accepts no arguments that returns a :term:`response`
          object.

        - A :term:`dotted Python name` which refers to any of the
          kinds of objects above.

        This API returns a callable which accepts the arguments
        ``context, request`` and which returns the result of calling
        the provided ``view`` object.

        The ``attr`` keyword argument is most useful when the view
        object is a class.  It names the method that should be used as
        the callable.  If ``attr`` is not provided, the attribute
        effectively defaults to ``__call__``.  See
        :ref:`class_as_view` for more information.

        The ``renderer`` keyword argument should be a renderer
        name. If supplied, it will cause the returned callable to use
        a :term:`renderer` to convert the user-supplied view result to
        a :term:`response` object.  If a ``renderer`` argument is not
        supplied, the user-supplied view must itself return a
        :term:`response` object.  """
        return self._derive_view(view, attr=attr, renderer=renderer)

    # b/w compat
    def _derive_view(self, view, permission=None, predicates=(),
                     attr=None, renderer=None, wrapper_viewname=None,
                     viewname=None, accept=None, order=MAX_ORDER,
                     phash=DEFAULT_PHASH, decorator=None,
                     mapper=None, http_cache=None):
        view = self.maybe_dotted(view)
        mapper = self.maybe_dotted(mapper)
        if isinstance(renderer, string_types):
            renderer = renderers.RendererHelper(
                name=renderer, package=self.package,
                registry = self.registry)
        if renderer is None:
            # use default renderer if one exists
            if self.registry.queryUtility(IRendererFactory) is not None:
                renderer = renderers.RendererHelper(
                    name=None,
                    package=self.package,
                    registry=self.registry)

        deriver = ViewDeriver(registry=self.registry,
                              permission=permission,
                              predicates=predicates,
                              attr=attr,
                              renderer=renderer,
                              wrapper_viewname=wrapper_viewname,
                              viewname=viewname,
                              accept=accept,
                              order=order,
                              phash=phash,
                              package=self.package,
                              mapper=mapper,
                              decorator=decorator,
                              http_cache=http_cache)

        return deriver(view)

    @action_method
    def add_forbidden_view(
        self,
        view=None,
        attr=None,
        renderer=None,
        wrapper=None,
        route_name=None,
        request_type=None,
        request_method=None, 
        request_param=None,
        containment=None,
        xhr=None,
        accept=None,
        header=None,
        path_info=None,
        custom_predicates=(),
        decorator=None,
        mapper=None,
        match_param=None,
        **predicates
        ):
        """ Add a forbidden view to the current configuration state.  The
        view will be called when Pyramid or application code raises a
        :exc:`pyramid.httpexceptions.HTTPForbidden` exception and the set of
        circumstances implied by the predicates provided are matched.  The
        simplest example is:

          .. code-block:: python

            def forbidden(request):
                return Response('Forbidden', status='403 Forbidden')

            config.add_forbidden_view(forbidden)

        All arguments have the same meaning as
        :meth:`pyramid.config.Configurator.add_view` and each predicate
        argument restricts the set of circumstances under which this notfound
        view will be invoked.  Unlike
        :meth:`pyramid.config.Configurator.add_view`, this method will raise
        an exception if passed ``name``, ``permission``, ``context``,
        ``for_``, or ``http_cache`` keyword arguments.  These argument values
        make no sense in the context of a forbidden view.

        .. versionadded:: 1.3
        """
        for arg in ('name', 'permission', 'context', 'for_', 'http_cache'):
            if arg in predicates:
                raise ConfigurationError(
                    '%s may not be used as an argument to add_forbidden_view'
                    % arg
                    )
        
        settings = dict(
            view=view,
            context=HTTPForbidden,
            wrapper=wrapper,
            request_type=request_type,
            request_method=request_method,
            request_param=request_param,
            containment=containment,
            xhr=xhr,
            accept=accept,
            header=header, 
            path_info=path_info,
            custom_predicates=custom_predicates,
            decorator=decorator,
            mapper=mapper,
            match_param=match_param,
            route_name=route_name,
            permission=NO_PERMISSION_REQUIRED,
            attr=attr,
            renderer=renderer,
            )
        settings.update(predicates)
        return self.add_view(**settings)

    set_forbidden_view = add_forbidden_view # deprecated sorta-bw-compat alias
    
    @action_method
    def add_notfound_view(
        self,
        view=None,
        attr=None,
        renderer=None,
        wrapper=None,
        route_name=None,
        request_type=None,
        request_method=None, 
        request_param=None,
        containment=None,
        xhr=None,
        accept=None,
        header=None,
        path_info=None,
        custom_predicates=(),
        decorator=None,
        mapper=None,
        match_param=None,
        append_slash=False,
        **predicates
        ):
        """ Add a default Not Found View to the current configuration state.
        The view will be called when Pyramid or application code raises an
        :exc:`pyramid.httpexceptions.HTTPNotFound` exception (e.g. when a
        view cannot be found for the request).  The simplest example is:

          .. code-block:: python

            def notfound(request):
                return Response('Not Found', status='404 Not Found')

            config.add_notfound_view(notfound)

        All arguments except ``append_slash`` have the same meaning as
        :meth:`pyramid.config.Configurator.add_view` and each predicate
        argument restricts the set of circumstances under which this notfound
        view will be invoked.  Unlike
        :meth:`pyramid.config.Configurator.add_view`, this method will raise
        an exception if passed ``name``, ``permission``, ``context``,
        ``for_``, or ``http_cache`` keyword arguments.  These argument values
        make no sense in the context of a Not Found View.

        If ``append_slash`` is ``True``, when this Not Found View is invoked,
        and the current path info does not end in a slash, the notfound logic
        will attempt to find a :term:`route` that matches the request's path
        info suffixed with a slash.  If such a route exists, Pyramid will
        issue a redirect to the URL implied by the route; if it does not,
        Pyramid will return the result of the view callable provided as
        ``view``, as normal.

        .. versionadded:: 1.3
        """
        for arg in ('name', 'permission', 'context', 'for_', 'http_cache'):
            if arg in predicates:
                raise ConfigurationError(
                    '%s may not be used as an argument to add_notfound_view'
                    % arg
                    )
                    
        settings = dict(
            view=view,
            context=HTTPNotFound,
            wrapper=wrapper,
            request_type=request_type,
            request_method=request_method,
            request_param=request_param,
            containment=containment,
            xhr=xhr,
            accept=accept,
            header=header, 
            path_info=path_info,
            custom_predicates=custom_predicates,
            decorator=decorator,
            mapper=mapper,
            match_param=match_param,
            route_name=route_name,
            permission=NO_PERMISSION_REQUIRED,
            )
        settings.update(predicates)
        if append_slash:
            view = self._derive_view(view, attr=attr, renderer=renderer)
            view = AppendSlashNotFoundViewFactory(view)
            settings['view'] = view
        else:
            settings['attr'] = attr
            settings['renderer'] = renderer
        return self.add_view(**settings)

    set_notfound_view = add_notfound_view # deprecated sorta-bw-compat alias

    @action_method
    def set_view_mapper(self, mapper):
        """
        Setting a :term:`view mapper` makes it possible to make use of
        :term:`view callable` objects which implement different call
        signatures than the ones supported by :app:`Pyramid` as described in
        its narrative documentation.

        The ``mapper`` should argument be an object implementing
        :class:`pyramid.interfaces.IViewMapperFactory` or a :term:`dotted
        Python name` to such an object.  The provided ``mapper`` will become
        the default view mapper to be used by all subsequent :term:`view
        configuration` registrations.

        See also :ref:`using_a_view_mapper`.

        .. note::

           Using the ``default_view_mapper`` argument to the
           :class:`pyramid.config.Configurator` constructor
           can be used to achieve the same purpose.
        """
        mapper = self.maybe_dotted(mapper)
        def register():
            self.registry.registerUtility(mapper, IViewMapperFactory)
        # IViewMapperFactory is looked up as the result of view config
        # in phase 3
        intr = self.introspectable('view mappers',
                                   IViewMapperFactory,
                                   self.object_description(mapper),
                                   'default view mapper')
        intr['mapper'] = mapper
        self.action(IViewMapperFactory, register, order=PHASE1_CONFIG,
                    introspectables=(intr,))

    @action_method
    def add_static_view(self, name, path, **kw):
        """ Add a view used to render static assets such as images
        and CSS files.

        The ``name`` argument is a string representing an
        application-relative local URL prefix.  It may alternately be a full
        URL.

        The ``path`` argument is the path on disk where the static files
        reside.  This can be an absolute path, a package-relative path, or a
        :term:`asset specification`.

        The ``cache_max_age`` keyword argument is input to set the
        ``Expires`` and ``Cache-Control`` headers for static assets served.
        Note that this argument has no effect when the ``name`` is a *url
        prefix*.  By default, this argument is ``None``, meaning that no
        particular Expires or Cache-Control headers are set in the response.

        The ``permission`` keyword argument is used to specify the
        :term:`permission` required by a user to execute the static view.  By
        default, it is the string
        :data:`pyramid.security.NO_PERMISSION_REQUIRED`, a special sentinel
        which indicates that, even if a :term:`default permission` exists for
        the current application, the static view should be renderered to
        completely anonymous users.  This default value is permissive
        because, in most web apps, static assets seldom need protection from
        viewing.  If ``permission`` is specified, the security checking will
        be performed against the default root factory ACL.

        Any other keyword arguments sent to ``add_static_view`` are passed on
        to :meth:`pyramid.config.Configurator.add_route` (e.g. ``factory``,
        perhaps to define a custom factory with a custom ACL for this static
        view).

        *Usage*

        The ``add_static_view`` function is typically used in conjunction
        with the :meth:`pyramid.request.Request.static_url` method.
        ``add_static_view`` adds a view which renders a static asset when
        some URL is visited; :meth:`pyramid.request.Request.static_url`
        generates a URL to that asset.

        The ``name`` argument to ``add_static_view`` is usually a simple URL
        prefix (e.g. ``'images'``).  When this is the case, the
        :meth:`pyramid.request.Request.static_url` API will generate a URL
        which points to a Pyramid view, which will serve up a set of assets
        that live in the package itself. For example:

        .. code-block:: python

           add_static_view('images', 'mypackage:images/')

        Code that registers such a view can generate URLs to the view via
        :meth:`pyramid.request.Request.static_url`:

        .. code-block:: python

           request.static_url('mypackage:images/logo.png')

        When ``add_static_view`` is called with a ``name`` argument that
        represents a URL prefix, as it is above, subsequent calls to
        :meth:`pyramid.request.Request.static_url` with paths that start with
        the ``path`` argument passed to ``add_static_view`` will generate a
        URL something like ``http://<Pyramid app URL>/images/logo.png``,
        which will cause the ``logo.png`` file in the ``images`` subdirectory
        of the ``mypackage`` package to be served.

        ``add_static_view`` can alternately be used with a ``name`` argument
        which is a *URL*, causing static assets to be served from an external
        webserver.  This happens when the ``name`` argument is a fully
        qualified URL (e.g. starts with ``http://`` or similar).  In this
        mode, the ``name`` is used as the prefix of the full URL when
        generating a URL using :meth:`pyramid.request.Request.static_url`.
        Furthermore, if a protocol-relative URL (e.g. ``//example.com/images``)
        is used as the ``name`` argument, the generated URL will use the
        protocol of the request (http or https, respectively).

        For example, if ``add_static_view`` is called like so:

        .. code-block:: python

           add_static_view('http://example.com/images', 'mypackage:images/')

        Subsequently, the URLs generated by
        :meth:`pyramid.request.Request.static_url` for that static view will
        be prefixed with ``http://example.com/images`` (the external webserver
        listening on ``example.com`` must be itself configured to respond
        properly to such a request.):

        .. code-block:: python

           static_url('mypackage:images/logo.png', request)

        See :ref:`static_assets_section` for more information.
        """
        spec = self._make_spec(path)
        info = self.registry.queryUtility(IStaticURLInfo)
        if info is None:
            info = StaticURLInfo()
            self.registry.registerUtility(info, IStaticURLInfo)
        info.add(self, name, spec, **kw)

def isexception(o):
    if IInterface.providedBy(o):
        if IException.isEqualOrExtendedBy(o):
            return True
    return (
        isinstance(o, Exception) or
        (inspect.isclass(o) and (issubclass(o, Exception)))
        )


@implementer(IStaticURLInfo)
class StaticURLInfo(object):

    def _get_registrations(self, registry):
        try:
            reg = registry._static_url_registrations
        except AttributeError:
            reg = registry._static_url_registrations = []
        return reg

    def generate(self, path, request, **kw):
        try:
            registry = request.registry
        except AttributeError: # bw compat (for tests)
            registry = get_current_registry()
        for (url, spec, route_name) in self._get_registrations(registry):
            if path.startswith(spec):
                subpath = path[len(spec):]
                if WIN: # pragma: no cover
                    subpath = subpath.replace('\\', '/') # windows
                if url is None:
                    kw['subpath'] = subpath
                    return request.route_url(route_name, **kw)
                else:
                    parsed = url_parse(url)
                    if not parsed.scheme:
                        # parsed.scheme is readonly, so we have to parse again
                        # to change the scheme, sigh.
                        url = urlparse.urlunparse(url_parse(
                            url, scheme=request.environ['wsgi.url_scheme']))
                    subpath = url_quote(subpath)
                    return urljoin(url, subpath)

        raise ValueError('No static URL definition matching %s' % path)

    def add(self, config, name, spec, **extra):
        # This feature only allows for the serving of a directory and
        # the files contained within, not of a single asset;
        # appending a slash here if the spec doesn't have one is
        # required for proper prefix matching done in ``generate``
        # (``subpath = path[len(spec):]``).
        if os.path.isabs(spec): # FBO windows
            sep = os.sep
        else:
            sep = '/'
        if not spec.endswith(sep):
            spec = spec + sep

        # we also make sure the name ends with a slash, purely as a
        # convenience: a name that is a url is required to end in a
        # slash, so that ``urljoin(name, subpath))`` will work above
        # when the name is a URL, and it doesn't hurt things for it to
        # have a name that ends in a slash if it's used as a route
        # name instead of a URL.
        if not name.endswith('/'):
            # make sure it ends with a slash
            name = name + '/'

        if url_parse(name).netloc:
            # it's a URL
            # url, spec, route_name
            url = name
            route_name = None
        else:
            # it's a view name
            url = None
            cache_max_age = extra.pop('cache_max_age', None)
            # create a view
            view = static_view(spec, cache_max_age=cache_max_age,
                               use_subpath=True)

            # Mutate extra to allow factory, etc to be passed through here.
            # Treat permission specially because we'd like to default to
            # permissiveness (see docs of config.add_static_view).
            permission = extra.pop('permission', None)
            if permission is None:
                permission = NO_PERMISSION_REQUIRED

            context = extra.pop('context', None)
            if context is None:
                context = extra.pop('for_', None)

            renderer = extra.pop('renderer', None)

            # register a route using the computed view, permission, and
            # pattern, plus any extras passed to us via add_static_view
            pattern = "%s*subpath" % name # name already ends with slash
            if config.route_prefix:
                route_name = '__%s/%s' % (config.route_prefix, name)
            else:
                route_name = '__%s' % name
            config.add_route(route_name, pattern, **extra)
            config.add_view(
                route_name=route_name,
                view=view,
                permission=permission,
                context=context,
                renderer=renderer,
                )

        def register():
            registrations = self._get_registrations(config.registry)

            names = [ t[0] for t in  registrations ]

            if name in names:
                idx = names.index(name)
                registrations.pop(idx)

            # url, spec, route_name
            registrations.append((url, spec, route_name))

        intr = config.introspectable('static views',
                                     name,
                                     'static view for %r' % name,
                                     'static view')
        intr['name'] = name
        intr['spec'] = spec

        config.action(None, callable=register, introspectables=(intr,))



```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
[ISSUE]
**Title:** Forbidden and NotFound Views Ignore `view_defaults`, Causing Predicate Mismatches

**Description:**
When configuring forbidden or notfound views using `config.add_forbidden_view` or `config.add_notfound_view`, the `view_defaults` are being ignored. This leads to predicates not functioning as expected, resulting in the views not behaving correctly based on the default configurations.

**Example Buggy Code:**
```python
from pyramid.config import Configurator
from pyramid.httpexceptions import HTTPForbidden, HTTPNotFound
from zope.interface import directlyProvides, implementedBy

class ForbiddenView:
    __view_defaults__ = {'containment': IDummy}

    def __init__(self, request):
        pass

    def __call__(self):
        return 'OK'

config = Configurator(autocommit=True)
config.add_forbidden_view(view=ForbiddenView, renderer='null_renderer')
wrapper = get_view_callable(config, ctx_iface=implementedBy(HTTPForbidden), request_iface=IRequest)

context = DummyContext()
directlyProvides(context, IDummy)
request = make_request(config)
result = wrapper(context, request)  # Expected to return 'OK'

context = DummyContext()
request = make_request(config)
wrapper(context, request)  # Expected to raise PredicateMismatch
```

**Expected Behavior:**
The `view_defaults` should be correctly applied when adding forbidden or notfound views. This ensures that predicates defined in `view_defaults` are respected, allowing the view to behave as intended based on these defaults.

**Actual Behavior:**
The `view_defaults` are ignored due to the way arguments are handled in `config.add_forbidden_view` and `config.add_notfound_view`. As a result, predicates do not function correctly, leading to unexpected behavior such as not raising `PredicateMismatch` when conditions defined in `view_defaults` are not met.

[/ISSUE]
{
    "TestViewsConfigurationMixin.test_add_forbidden_view": "PASSED",
    "TestViewsConfigurationMixin.test_add_forbidden_view_allows_other_predicates": "PASSED",
    "TestViewsConfigurationMixin.test_add_forbidden_view_disallows_context": "PASSED",
    "TestViewsConfigurationMixin.test_add_forbidden_view_disallows_for_": "PASSED",
    "TestViewsConfigurationMixin.test_add_forbidden_view_disallows_http_cache": "PASSED",
    "TestViewsConfigurationMixin.test_add_forbidden_view_disallows_name": "PASSED",
    "TestViewsConfigurationMixin.test_add_forbidden_view_disallows_permission": "PASSED",
    "TestViewsConfigurationMixin.test_add_forbidden_view_with_renderer": "PASSED",
    "TestViewsConfigurationMixin.test_add_forbidden_view_with_view_defaults": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_allows_other_predicates": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_append_slash": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_disallows_context": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_disallows_for_": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_disallows_http_cache": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_disallows_name": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_disallows_permission": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_with_renderer": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_with_view_defaults": "PASSED",
    "TestViewsConfigurationMixin.test_add_static_view_absolute": "PASSED",
    "TestViewsConfigurationMixin.test_add_static_view_package_relative": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_as_instance": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_as_instance_requestonly": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_as_instancemethod": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_as_instancemethod_requestonly": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_as_oldstyle_class": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_as_oldstyle_class_requestonly": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_context_as_class": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_context_as_dottedname": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_context_as_iface": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_context_trumps_for": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_custom_more_preds_first_bests_fewer_preds_last": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_default_phash_overrides_default_phash": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_default_phash_overrides_no_phash": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_exc_default_phash_overrides_default_phash": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_exc_default_phash_overrides_no_phash": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_exc_multiview_replaces_existing_securedview": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_exc_multiview_replaces_existing_view": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_exc_multiview_replaces_multiview": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_exc_mulview_replaces_existing_view_with___accept__": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_exc_same_phash_overrides_existing_single_view": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_exc_with_accept_multiview_replaces_existing_view": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_exception_register_secured_view": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_for__as_dottedname": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_for_as_class": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_for_as_iface": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_mixed_case_replaces_existing_view": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_multiview___discriminator__": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_multiview_call_ordering": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_multiview_context_superclass_then_subclass": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_multiview_exception_superclass_then_subclass": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_multiview_replaces_existing_securedview": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_multiview_replaces_existing_view": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_multiview_replaces_existing_view_with___accept__": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_multiview_replaces_multiview": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_register_secured_view": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_same_phash_overrides_existing_single_view": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_same_predicates": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_view_callable_None_no_renderer": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_view_callable_None_with_renderer": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_view_callable_dottedname": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_accept_match": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_accept_multiview_replaces_existing_view": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_accept_nomatch": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_containment_dottedname": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_containment_false": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_containment_true": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_decorator": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_decorator_tuple": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_default_permission_no_explicit_permission": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_default_renderer": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_function_callable": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_function_callable_requestonly": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_header_badregex": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_header_noval_match": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_header_noval_nomatch": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_header_val_match": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_header_val_missing": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_header_val_nomatch": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_http_cache": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_mapper": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_name": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_name_unicode": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_no_default_permission_no_explicit_permission": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_nonexistant_route_name": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_path_info_badregex": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_path_info_match": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_path_info_nomatch": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_permission": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_request_method_false": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_request_method_get_implies_head": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_request_method_sequence_conflict": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_request_method_sequence_false": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_request_method_sequence_true": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_request_method_true": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_request_param_noval_false": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_request_param_noval_true": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_request_param_val_false": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_request_param_val_true": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_request_type": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_request_type_and_route_name": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_request_type_as_iface": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_request_type_as_noniface": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_route_name": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_route_name_exception": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_tmpl_renderer_factory_introspector_missing": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_tmpl_renderer_factory_no_renderer_factory": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_tmpl_renderer_factory_with_renderer_factory": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_view_config_and_view_defaults_conflicts": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_view_config_and_view_defaults_doesnt_conflict": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_view_defaults": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_view_defaults_viewname_is_dottedname_kwarg": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_xhr_false": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_xhr_true": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_wrapped_view_is_decorated": "PASSED",
    "TestViewsConfigurationMixin.test_add_views_with_accept_multiview_replaces_existing": "PASSED",
    "TestViewsConfigurationMixin.test_derive_view_dottedname": "PASSED",
    "TestViewsConfigurationMixin.test_derive_view_function": "PASSED",
    "TestViewsConfigurationMixin.test_derive_view_with_default_renderer_no_explicit_renderer": "PASSED",
    "TestViewsConfigurationMixin.test_derive_view_with_default_renderer_with_explicit_renderer": "PASSED",
    "TestViewsConfigurationMixin.test_set_view_mapper": "PASSED",
    "TestViewsConfigurationMixin.test_set_view_mapper_dottedname": "PASSED",
    "Test_requestonly.test_defaults": "PASSED",
    "Test_requestonly.test_otherattr": "PASSED",
    "Test_isexception.test_is_IException": "PASSED",
    "Test_isexception.test_is_IException_subinterface": "PASSED",
    "Test_isexception.test_is_exception_class": "PASSED",
    "Test_isexception.test_is_exception_instance": "PASSED",
    "TestMultiView.test___call__": "PASSED",
    "TestMultiView.test___call__intermediate_not_found": "PASSED",
    "TestMultiView.test___call__raise_not_found_isnt_interpreted_as_pred_mismatch": "PASSED",
    "TestMultiView.test___call_permissive_has_call_permissive": "PASSED",
    "TestMultiView.test___call_permissive_has_no_call_permissive": "PASSED",
    "TestMultiView.test__call__not_found": "PASSED",
    "TestMultiView.test__call__with_accept_match": "PASSED",
    "TestMultiView.test__call__with_accept_miss": "PASSED",
    "TestMultiView.test__call_permissive__not_found": "PASSED",
    "TestMultiView.test_add": "PASSED",
    "TestMultiView.test_add_with_phash": "PASSED",
    "TestMultiView.test_add_with_phash_override_accept": "PASSED",
    "TestMultiView.test_add_with_phash_override_accept2": "PASSED",
    "TestMultiView.test_class_implements_ISecuredView": "PASSED",
    "TestMultiView.test_get_views": "PASSED",
    "TestMultiView.test_get_views_best_match_returns_None": "PASSED",
    "TestMultiView.test_get_views_no_self_accepts": "PASSED",
    "TestMultiView.test_get_views_request_has_no_accept": "PASSED",
    "TestMultiView.test_instance_implements_ISecuredView": "PASSED",
    "TestMultiView.test_match_not_found": "PASSED",
    "TestMultiView.test_match_predicate_fails": "PASSED",
    "TestMultiView.test_match_predicate_succeeds": "PASSED",
    "TestMultiView.test_multiple_with_functions_as_views": "PASSED",
    "TestMultiView.test_permitted": "PASSED",
    "TestMultiView.test_permitted_no_match_with__permitted__": "PASSED",
    "TestMultiView.test_permitted_no_views": "PASSED",
    "TestViewDeriver.test_as_function_context_and_request": "PASSED",
    "TestViewDeriver.test_as_function_requestonly": "PASSED",
    "TestViewDeriver.test_as_instance_context_and_request": "PASSED",
    "TestViewDeriver.test_as_instance_context_and_request_attr_and_renderer": "PASSED",
    "TestViewDeriver.test_as_instance_requestonly_attr_and_renderer": "PASSED",
    "TestViewDeriver.test_as_newstyle_class_context_and_request": "PASSED",
    "TestViewDeriver.test_as_newstyle_class_context_and_request_attr_and_renderer": "PASSED",
    "TestViewDeriver.test_as_newstyle_class_requestonly": "PASSED",
    "TestViewDeriver.test_as_newstyle_class_requestonly_attr_and_renderer": "PASSED",
    "TestViewDeriver.test_as_oldstyle_class_context_and_request": "PASSED",
    "TestViewDeriver.test_as_oldstyle_class_requestonly": "PASSED",
    "TestViewDeriver.test_as_oldstyle_cls_context_request_attr_and_renderer": "PASSED",
    "TestViewDeriver.test_as_oldstyle_cls_requestonly_attr_and_renderer": "PASSED",
    "TestViewDeriver.test_attr_wrapped_view_branching_default_phash": "PASSED",
    "TestViewDeriver.test_attr_wrapped_view_branching_nondefault_phash": "PASSED",
    "TestViewDeriver.test_class_with_attr": "PASSED",
    "TestViewDeriver.test_class_without_attr": "PASSED",
    "TestViewDeriver.test_debug_auth_permission_authpol_denied": "PASSED",
    "TestViewDeriver.test_debug_auth_permission_authpol_denied2": "PASSED",
    "TestViewDeriver.test_debug_auth_permission_authpol_overridden": "PASSED",
    "TestViewDeriver.test_debug_auth_permission_authpol_permitted": "PASSED",
    "TestViewDeriver.test_debug_auth_permission_authpol_permitted_no_request": "PASSED",
    "TestViewDeriver.test_function_returns_true_Response_no_renderer": "PASSED",
    "TestViewDeriver.test_function_returns_true_Response_with_renderer": "PASSED",
    "TestViewDeriver.test_http_cached_prevent_http_cache_in_settings": "PASSED",
    "TestViewDeriver.test_http_cached_view_bad_tuple": "PASSED",
    "TestViewDeriver.test_http_cached_view_integer": "PASSED",
    "TestViewDeriver.test_http_cached_view_prevent_auto_set": "PASSED",
    "TestViewDeriver.test_http_cached_view_timedelta": "PASSED",
    "TestViewDeriver.test_http_cached_view_tuple": "PASSED",
    "TestViewDeriver.test_http_cached_view_tuple_seconds_None": "PASSED",
    "TestViewDeriver.test_predicate_mismatch_exception_has_text_in_detail": "PASSED",
    "TestViewDeriver.test_predicate_mismatch_view_has_name": "PASSED",
    "TestViewDeriver.test_predicate_mismatch_view_has_no_name": "PASSED",
    "TestViewDeriver.test_requestonly_function": "PASSED",
    "TestViewDeriver.test_requestonly_function_with_renderer": "PASSED",
    "TestViewDeriver.test_requestonly_function_with_renderer_request_has_view": "PASSED",
    "TestViewDeriver.test_requestonly_function_with_renderer_request_override": "PASSED",
    "TestViewDeriver.test_secured_view_authn_policy_no_authz_policy": "PASSED",
    "TestViewDeriver.test_secured_view_authz_policy_no_authn_policy": "PASSED",
    "TestViewDeriver.test_secured_view_raises_forbidden_no_name": "PASSED",
    "TestViewDeriver.test_secured_view_raises_forbidden_with_name": "PASSED",
    "TestViewDeriver.test_with_debug_authorization_authn_policy_no_authz_policy": "PASSED",
    "TestViewDeriver.test_with_debug_authorization_authz_policy_no_authn_policy": "PASSED",
    "TestViewDeriver.test_with_debug_authorization_no_authpol": "PASSED",
    "TestViewDeriver.test_with_debug_authorization_no_permission": "PASSED",
    "TestViewDeriver.test_with_predicates_all": "PASSED",
    "TestViewDeriver.test_with_predicates_checker": "PASSED",
    "TestViewDeriver.test_with_predicates_notall": "PASSED",
    "TestViewDeriver.test_with_view_mapper_config_specified": "PASSED",
    "TestViewDeriver.test_with_view_mapper_default_mapper_specified": "PASSED",
    "TestViewDeriver.test_with_view_mapper_view_specified": "PASSED",
    "TestViewDeriver.test_with_wrapper_viewname": "PASSED",
    "TestViewDeriver.test_with_wrapper_viewname_notfound": "PASSED",
    "TestDefaultViewMapper.test__view_as_function_with_attr": "PASSED",
    "TestDefaultViewMapper.test_view_as_function_context_and_request": "PASSED",
    "TestDefaultViewMapper.test_view_as_function_requestonly": "PASSED",
    "TestDefaultViewMapper.test_view_as_function_requestonly_with_attr": "PASSED",
    "TestDefaultViewMapper.test_view_as_instance_context_and_request": "PASSED",
    "TestDefaultViewMapper.test_view_as_instance_context_and_request_and_attr": "PASSED",
    "TestDefaultViewMapper.test_view_as_instance_requestonly": "PASSED",
    "TestDefaultViewMapper.test_view_as_instance_requestonly_with_attr": "PASSED",
    "TestDefaultViewMapper.test_view_as_newstyle_class_context_and_request": "PASSED",
    "TestDefaultViewMapper.test_view_as_newstyle_class_context_and_request_with_attr": "PASSED",
    "TestDefaultViewMapper.test_view_as_newstyle_class_requestonly": "PASSED",
    "TestDefaultViewMapper.test_view_as_newstyle_class_requestonly_with_attr": "PASSED",
    "TestDefaultViewMapper.test_view_as_oldstyle_class_context_and_request": "PASSED",
    "TestDefaultViewMapper.test_view_as_oldstyle_class_context_and_request_with_attr": "PASSED",
    "TestDefaultViewMapper.test_view_as_oldstyle_class_requestonly": "PASSED",
    "TestDefaultViewMapper.test_view_as_oldstyle_class_requestonly_with_attr": "PASSED",
    "Test_preserve_view_attrs.test_it_different": "PASSED",
    "Test_preserve_view_attrs.test_it_different_with_existing_original_view": "PASSED",
    "Test_preserve_view_attrs.test_it_same": "PASSED",
    "Test_preserve_view_attrs.test_it_view_is_None": "PASSED",
    "TestStaticURLInfo.test_add_already_exists": "PASSED",
    "TestStaticURLInfo.test_add_url_noendslash": "PASSED",
    "TestStaticURLInfo.test_add_url_noscheme": "PASSED",
    "TestStaticURLInfo.test_add_url_withendslash": "PASSED",
    "TestStaticURLInfo.test_add_viewname": "PASSED",
    "TestStaticURLInfo.test_add_viewname_with_context": "PASSED",
    "TestStaticURLInfo.test_add_viewname_with_for_": "PASSED",
    "TestStaticURLInfo.test_add_viewname_with_permission": "PASSED",
    "TestStaticURLInfo.test_add_viewname_with_renderer": "PASSED",
    "TestStaticURLInfo.test_add_viewname_with_route_prefix": "PASSED",
    "TestStaticURLInfo.test_generate_missing": "PASSED",
    "TestStaticURLInfo.test_generate_quoting": "PASSED",
    "TestStaticURLInfo.test_generate_registration_miss": "PASSED",
    "TestStaticURLInfo.test_generate_registration_no_registry_on_request": "PASSED",
    "TestStaticURLInfo.test_generate_route_url": "PASSED",
    "TestStaticURLInfo.test_generate_slash_in_name1": "PASSED",
    "TestStaticURLInfo.test_generate_slash_in_name2": "PASSED",
    "TestStaticURLInfo.test_generate_url_quoted_remote": "PASSED",
    "TestStaticURLInfo.test_generate_url_unquoted_local": "PASSED",
    "TestStaticURLInfo.test_verifyClass": "PASSED",
    "TestStaticURLInfo.test_verifyObject": "PASSED",
    "Test_view_description.test_with_text": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_object_event_subscriber": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_resource_url_default_resource_iface_means_Interface": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_resource_url_nodefault_resource_iface": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_response_adapter": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_response_adapter_dottednames": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_response_adapter_self": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_subscriber_defaults": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_subscriber_dottednames": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_subscriber_iface_specified": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_subscriber_predicate": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_subscriber_with_default_type_predicates_False": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_subscriber_with_default_type_predicates_True": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_subscriber_with_specific_type_and_predicates_False": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_subscriber_with_specific_type_and_predicates_True": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_traverser_default_iface_means_Interface": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_traverser_introspectables": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_traverser_nondefault_iface": "PASSED",
    "Test_eventonly.test_defaults": "PASSED",
    "TestAssetsConfiguratorMixin.test__override_already_registered": "PASSED",
    "TestAssetsConfiguratorMixin.test__override_not_yet_registered": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_directory_with_directory": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_directory_with_file": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_directory_with_package": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_file_with_directory": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_file_with_file": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_file_with_package": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_package_with_directory": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_package_with_package": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_samename": "PASSED",
    "TestOverrideProvider.test_get_resource_filename_override_returns_value": "PASSED",
    "TestOverrideProvider.test_get_resource_stream_no_overrides": "PASSED",
    "TestOverrideProvider.test_get_resource_stream_override_returns_None": "PASSED",
    "TestOverrideProvider.test_get_resource_stream_override_returns_value": "PASSED",
    "TestOverrideProvider.test_get_resource_string_no_overrides": "PASSED",
    "TestOverrideProvider.test_get_resource_string_override_returns_None": "PASSED",
    "TestOverrideProvider.test_get_resource_string_override_returns_value": "PASSED",
    "TestOverrideProvider.test_has_resource_no_overrides": "PASSED",
    "TestOverrideProvider.test_has_resource_override_returns_None": "PASSED",
    "TestOverrideProvider.test_has_resource_override_returns_True": "PASSED",
    "TestOverrideProvider.test_resource_isdir_no_overrides": "PASSED",
    "TestOverrideProvider.test_resource_isdir_override_returns_False": "PASSED",
    "TestOverrideProvider.test_resource_isdir_override_returns_None": "PASSED",
    "TestOverrideProvider.test_resource_listdir_no_overrides": "PASSED",
    "TestOverrideProvider.test_resource_listdir_override_returns_None": "PASSED",
    "TestOverrideProvider.test_resource_listdir_override_returns_values": "PASSED",
    "TestPackageOverrides.test_class_conforms_to_IPEP302Loader": "PASSED",
    "TestPackageOverrides.test_class_conforms_to_IPackageOverrides": "PASSED",
    "TestPackageOverrides.test_ctor_package_already_has_loader_of_different_type": "PASSED",
    "TestPackageOverrides.test_ctor_package_already_has_loader_of_same_type": "PASSED",
    "TestPackageOverrides.test_ctor_registers_loader_type": "PASSED",
    "TestPackageOverrides.test_ctor_sets_loader": "PASSED",
    "TestPackageOverrides.test_ctor_sets_local_state": "PASSED",
    "TestPackageOverrides.test_get_code_pkg_has___loader__": "PASSED",
    "TestPackageOverrides.test_get_code_pkg_has_no___loader__": "PASSED",
    "TestPackageOverrides.test_get_data_pkg_has___loader__": "PASSED",
    "TestPackageOverrides.test_get_data_pkg_has_no___loader__": "PASSED",
    "TestPackageOverrides.test_get_filename_file_doesnt_exist": "PASSED",
    "TestPackageOverrides.test_get_source_pkg_has___loader__": "PASSED",
    "TestPackageOverrides.test_get_source_pkg_has_no___loader__": "PASSED",
    "TestPackageOverrides.test_get_stream": "PASSED",
    "TestPackageOverrides.test_get_stream_file_doesnt_exist": "PASSED",
    "TestPackageOverrides.test_get_string": "PASSED",
    "TestPackageOverrides.test_get_string_file_doesnt_exist": "PASSED",
    "TestPackageOverrides.test_has_resource": "PASSED",
    "TestPackageOverrides.test_has_resource_file_doesnt_exist": "PASSED",
    "TestPackageOverrides.test_insert_directory": "PASSED",
    "TestPackageOverrides.test_insert_emptystring": "PASSED",
    "TestPackageOverrides.test_insert_file": "PASSED",
    "TestPackageOverrides.test_instance_conforms_to_IPEP302Loader": "PASSED",
    "TestPackageOverrides.test_instance_conforms_to_IPackageOverrides": "PASSED",
    "TestPackageOverrides.test_is_package_pkg_has___loader__": "PASSED",
    "TestPackageOverrides.test_is_package_pkg_has_no___loader__": "PASSED",
    "TestPackageOverrides.test_isdir_doesnt_exist": "PASSED",
    "TestPackageOverrides.test_isdir_false": "PASSED",
    "TestPackageOverrides.test_isdir_true": "PASSED",
    "TestPackageOverrides.test_listdir": "PASSED",
    "TestPackageOverrides.test_listdir_doesnt_exist": "PASSED",
    "TestPackageOverrides.test_search_path": "PASSED",
    "TestDirectoryOverride.test_it_match": "PASSED",
    "TestDirectoryOverride.test_it_no_match": "PASSED",
    "TestFileOverride.test_it_match": "PASSED",
    "TestFileOverride.test_it_no_match": "PASSED",
    "TestFactoriesMixin.test_add_request_method_with_None_callable": "PASSED",
    "TestFactoriesMixin.test_add_request_method_with_None_callable_and_no_name": "PASSED",
    "TestFactoriesMixin.test_add_request_method_with_None_callable_conflict": "PASSED",
    "TestFactoriesMixin.test_add_request_method_with_callable": "PASSED",
    "TestFactoriesMixin.test_add_request_method_with_unnamed_callable": "PASSED",
    "TestFactoriesMixin.test_set_multiple_request_methods_conflict": "PASSED",
    "TestFactoriesMixin.test_set_request_factory": "PASSED",
    "TestFactoriesMixin.test_set_request_factory_dottedname": "PASSED",
    "TestFactoriesMixin.test_set_root_factory": "PASSED",
    "TestFactoriesMixin.test_set_root_factory_as_None": "PASSED",
    "TestFactoriesMixin.test_set_root_factory_dottedname": "PASSED",
    "TestFactoriesMixin.test_set_session_factory": "PASSED",
    "TestFactoriesMixin.test_set_session_factory_dottedname": "PASSED",
    "TestDeprecatedFactoriesMixinMethods.test_set_multiple_request_properties": "PASSED",
    "TestDeprecatedFactoriesMixinMethods.test_set_multiple_request_properties_conflict": "PASSED",
    "TestDeprecatedFactoriesMixinMethods.test_set_request_property_with_callable": "PASSED",
    "TestDeprecatedFactoriesMixinMethods.test_set_request_property_with_property": "PASSED",
    "TestDeprecatedFactoriesMixinMethods.test_set_request_property_with_unnamed_callable": "PASSED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_missing_dir": "PASSED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_no_specs": "PASSED",
    "TestI18NConfiguratorMixin.test_set_locale_negotiator": "PASSED",
    "TestI18NConfiguratorMixin.test_set_locale_negotiator_dottedname": "PASSED",
    "ConfiguratorTests.test___getattr__matches": "PASSED",
    "ConfiguratorTests.test___getattr__matches_no_action_wrap": "PASSED",
    "ConfiguratorTests.test___getattr__missing_when_directives_dont_exist": "PASSED",
    "ConfiguratorTests.test___getattr__missing_when_directives_exist": "PASSED",
    "ConfiguratorTests.test__fix_registry_has_listeners": "PASSED",
    "ConfiguratorTests.test__fix_registry_notify": "PASSED",
    "ConfiguratorTests.test__fix_registry_queryAdapterOrSelf": "PASSED",
    "ConfiguratorTests.test__fix_registry_registerSelfAdapter": "PASSED",
    "ConfiguratorTests.test_absolute_asset_spec_already_absolute": "PASSED",
    "ConfiguratorTests.test_absolute_asset_spec_notastring": "PASSED",
    "ConfiguratorTests.test_absolute_asset_spec_relative": "PASSED",
    "ConfiguratorTests.test_action_autocommit_with_introspectables": "PASSED",
    "ConfiguratorTests.test_action_autocommit_with_introspectables_introspection_off": "PASSED",
    "ConfiguratorTests.test_action_branching_kw_is_None": "PASSED",
    "ConfiguratorTests.test_action_branching_kw_is_not_None": "PASSED",
    "ConfiguratorTests.test_action_branching_nonautocommit_with_config_info": "PASSED",
    "ConfiguratorTests.test_action_branching_nonautocommit_with_introspectables": "PASSED",
    "ConfiguratorTests.test_action_branching_nonautocommit_without_config_info": "PASSED",
    "ConfiguratorTests.test_action_nonautocommit_with_introspectables_introspection_off": "PASSED",
    "ConfiguratorTests.test_autocommit_no_conflicts": "PASSED",
    "ConfiguratorTests.test_begin": "PASSED",
    "ConfiguratorTests.test_begin_with_request": "PASSED",
    "ConfiguratorTests.test_commit_conflict_resolved_with_include": "PASSED",
    "ConfiguratorTests.test_commit_conflict_resolved_with_two_includes_and_local": "PASSED",
    "ConfiguratorTests.test_commit_conflict_simple": "PASSED",
    "ConfiguratorTests.test_commit_conflict_with_two_includes": "PASSED",
    "ConfiguratorTests.test_conflict_set_forbidden_view": "PASSED",
    "ConfiguratorTests.test_conflict_set_notfound_view": "PASSED",
    "ConfiguratorTests.test_ctor_alternate_renderers": "PASSED",
    "ConfiguratorTests.test_ctor_authentication_policy": "PASSED",
    "ConfiguratorTests.test_ctor_authorization_policy_only": "PASSED",
    "ConfiguratorTests.test_ctor_default_permission": "PASSED",
    "ConfiguratorTests.test_ctor_default_renderers": "PASSED",
    "ConfiguratorTests.test_ctor_default_view_mapper": "PASSED",
    "ConfiguratorTests.test_ctor_default_webob_response_adapter_registered": "PASSED",
    "ConfiguratorTests.test_ctor_exceptionresponse_view_None": "PASSED",
    "ConfiguratorTests.test_ctor_exceptionresponse_view_custom": "PASSED",
    "ConfiguratorTests.test_ctor_httpexception_view_default": "PASSED",
    "ConfiguratorTests.test_ctor_no_root_factory": "PASSED",
    "ConfiguratorTests.test_ctor_noreg_custom_settings": "PASSED",
    "ConfiguratorTests.test_ctor_noreg_debug_logger_non_None": "PASSED",
    "ConfiguratorTests.test_ctor_session_factory": "PASSED",
    "ConfiguratorTests.test_ctor_with_introspection": "PASSED",
    "ConfiguratorTests.test_ctor_with_package_registry": "PASSED",
    "ConfiguratorTests.test_ctor_with_root_factory": "PASSED",
    "ConfiguratorTests.test_end": "PASSED",
    "ConfiguratorTests.test_hook_zca": "PASSED",
    "ConfiguratorTests.test_include_with_dotted_name": "PASSED",
    "ConfiguratorTests.test_include_with_missing_source_file": "PASSED",
    "ConfiguratorTests.test_include_with_module_defaults_to_includeme": "PASSED",
    "ConfiguratorTests.test_include_with_module_defaults_to_includeme_missing": "PASSED",
    "ConfiguratorTests.test_include_with_nested_route_prefix": "PASSED",
    "ConfiguratorTests.test_include_with_python_callable": "PASSED",
    "ConfiguratorTests.test_include_with_route_prefix": "PASSED",
    "ConfiguratorTests.test_introspector_decorator": "PASSED",
    "ConfiguratorTests.test_make_wsgi_app": "PASSED",
    "ConfiguratorTests.test_maybe_dotted_notstring_success": "PASSED",
    "ConfiguratorTests.test_maybe_dotted_string_fail": "PASSED",
    "ConfiguratorTests.test_maybe_dotted_string_success": "PASSED",
    "ConfiguratorTests.test_scan_integration": "PASSED",
    "ConfiguratorTests.test_scan_integration_dottedname_package": "PASSED",
    "ConfiguratorTests.test_scan_integration_with_extra_kw": "PASSED",
    "ConfiguratorTests.test_scan_integration_with_ignore": "PASSED",
    "ConfiguratorTests.test_scan_integration_with_onerror": "PASSED",
    "ConfiguratorTests.test_setup_registry_alternate_renderers": "PASSED",
    "ConfiguratorTests.test_setup_registry_authentication_policy": "PASSED",
    "ConfiguratorTests.test_setup_registry_authentication_policy_dottedname": "PASSED",
    "ConfiguratorTests.test_setup_registry_authorization_policy_dottedname": "PASSED",
    "ConfiguratorTests.test_setup_registry_authorization_policy_only": "PASSED",
    "ConfiguratorTests.test_setup_registry_calls_fix_registry": "PASSED",
    "ConfiguratorTests.test_setup_registry_custom_settings": "PASSED",
    "ConfiguratorTests.test_setup_registry_debug_logger_name": "PASSED",
    "ConfiguratorTests.test_setup_registry_debug_logger_non_None": "PASSED",
    "ConfiguratorTests.test_setup_registry_default_permission": "PASSED",
    "ConfiguratorTests.test_setup_registry_dottedname_root_factory": "PASSED",
    "ConfiguratorTests.test_setup_registry_explicit_notfound_trumps_iexceptionresponse": "PASSED",
    "ConfiguratorTests.test_setup_registry_includes": "PASSED",
    "ConfiguratorTests.test_setup_registry_includes_spaces": "PASSED",
    "ConfiguratorTests.test_setup_registry_locale_negotiator": "PASSED",
    "ConfiguratorTests.test_setup_registry_locale_negotiator_dottedname": "PASSED",
    "ConfiguratorTests.test_setup_registry_no_default_root_factory": "PASSED",
    "ConfiguratorTests.test_setup_registry_registers_default_exceptionresponse_views": "PASSED",
    "ConfiguratorTests.test_setup_registry_registers_default_view_predicates": "PASSED",
    "ConfiguratorTests.test_setup_registry_registers_default_webob_iresponse_adapter": "PASSED",
    "ConfiguratorTests.test_setup_registry_request_factory": "PASSED",
    "ConfiguratorTests.test_setup_registry_request_factory_dottedname": "PASSED",
    "ConfiguratorTests.test_setup_registry_tweens": "PASSED",
    "ConfiguratorTests.test_unhook_zca": "PASSED",
    "ConfiguratorTests.test_with_package": "PASSED",
    "ConfiguratorTests.test_with_package_module": "PASSED",
    "ConfiguratorTests.test_with_package_package": "PASSED",
    "TestConfigurator_add_directive.test_directive_persists_across_configurator_creations": "PASSED",
    "TestConfigurator_add_directive.test_extend_action_method_successful": "PASSED",
    "TestConfigurator_add_directive.test_extend_same_name_doesnt_conflict": "PASSED",
    "TestConfigurator__add_predicate.test_factory_as_object": "PASSED",
    "TestActionState.test_action_simple": "PASSED",
    "TestActionState.test_action_with_includepath": "PASSED",
    "TestActionState.test_action_with_includepath_and_info": "PASSED",
    "TestActionState.test_action_with_info": "PASSED",
    "TestActionState.test_action_with_introspectables": "PASSED",
    "TestActionState.test_action_with_order": "PASSED",
    "TestActionState.test_execute_actions_dicts": "PASSED",
    "TestActionState.test_execute_actions_error": "PASSED",
    "TestActionState.test_execute_actions_tuples": "PASSED",
    "TestActionState.test_execute_actions_with_introspectable_no_callable": "PASSED",
    "TestActionState.test_execute_actions_with_introspectables": "PASSED",
    "TestActionState.test_it": "PASSED",
    "TestActionState.test_processSpec": "PASSED",
    "Test_resolveConflicts.test_it_conflict": "PASSED",
    "Test_resolveConflicts.test_it_success_dicts": "PASSED",
    "Test_resolveConflicts.test_it_success_tuples": "PASSED",
    "Test_resolveConflicts.test_it_with_actions_grouped_by_order": "PASSED",
    "TestGlobalRegistriesIntegration.test_global_registries": "PASSED",
    "TestGlobalRegistriesIntegration.test_global_registries_empty": "PASSED",
    "TestXHRPredicate.test___call___false": "PASSED",
    "TestXHRPredicate.test___call___true": "PASSED",
    "TestXHRPredicate.test_phash": "PASSED",
    "TestXHRPredicate.test_text": "PASSED",
    "TestRequestMethodPredicate.test___call___false": "PASSED",
    "TestRequestMethodPredicate.test___call___true_multi": "PASSED",
    "TestRequestMethodPredicate.test___call___true_single": "PASSED",
    "TestRequestMethodPredicate.test_ctor_get_but_no_head": "PASSED",
    "TestRequestMethodPredicate.test_phash": "PASSED",
    "TestRequestMethodPredicate.test_text": "PASSED",
    "TestPathInfoPredicate.test___call___false": "PASSED",
    "TestPathInfoPredicate.test___call___true": "PASSED",
    "TestPathInfoPredicate.test_ctor_compilefail": "PASSED",
    "TestPathInfoPredicate.test_phash": "PASSED",
    "TestPathInfoPredicate.test_text": "PASSED",
    "TestRequestParamPredicate.test___call___false": "PASSED",
    "TestRequestParamPredicate.test___call___false_multi": "PASSED",
    "TestRequestParamPredicate.test___call___true_exists": "PASSED",
    "TestRequestParamPredicate.test___call___true_multi": "PASSED",
    "TestRequestParamPredicate.test___call___true_withval": "PASSED",
    "TestRequestParamPredicate.test_phash_exists": "PASSED",
    "TestRequestParamPredicate.test_phash_withval": "PASSED",
    "TestRequestParamPredicate.test_text_exists": "PASSED",
    "TestRequestParamPredicate.test_text_multi": "PASSED",
    "TestRequestParamPredicate.test_text_withval": "PASSED",
    "TestMatchParamPredicate.test___call___false": "PASSED",
    "TestMatchParamPredicate.test___call___matchdict_is_None": "PASSED",
    "TestMatchParamPredicate.test___call___true_multi": "PASSED",
    "TestMatchParamPredicate.test___call___true_single": "PASSED",
    "TestMatchParamPredicate.test_phash": "PASSED",
    "TestMatchParamPredicate.test_text": "PASSED",
    "TestCustomPredicate.test___call___false": "PASSED",
    "TestCustomPredicate.test___call___true": "PASSED",
    "TestCustomPredicate.test_phash": "PASSED",
    "TestCustomPredicate.test_text_func_has___text__": "PASSED",
    "TestCustomPredicate.test_text_func_repr": "PASSED",
    "TestTraversePredicate.test___call__traverse_has_remainder_already": "PASSED",
    "TestTraversePredicate.test___call__traverse_matches": "PASSED",
    "TestTraversePredicate.test___call__traverse_matches_with_highorder_chars": "PASSED",
    "TestTraversePredicate.test_phash": "PASSED",
    "TestTraversePredicate.test_text": "PASSED",
    "Test_CheckCSRFTokenPredicate.test_it_call_val_False": "PASSED",
    "Test_CheckCSRFTokenPredicate.test_it_call_val_True": "PASSED",
    "Test_CheckCSRFTokenPredicate.test_it_call_val_str": "PASSED",
    "Test_CheckCSRFTokenPredicate.test_phash": "PASSED",
    "Test_CheckCSRFTokenPredicate.test_text": "PASSED",
    "TestHeaderPredicate.test___call___false": "PASSED",
    "TestHeaderPredicate.test___call___false_withregex": "PASSED",
    "TestHeaderPredicate.test___call___true_exists": "PASSED",
    "TestHeaderPredicate.test___call___true_withregex": "PASSED",
    "TestHeaderPredicate.test___call___true_withval": "PASSED",
    "TestHeaderPredicate.test_phash_exists": "PASSED",
    "TestHeaderPredicate.test_phash_withregex": "PASSED",
    "TestHeaderPredicate.test_phash_withval": "PASSED",
    "TestHeaderPredicate.test_text_exists": "PASSED",
    "TestHeaderPredicate.test_text_withregex": "PASSED",
    "TestHeaderPredicate.test_text_withval": "PASSED",
    "Test_PhysicalPathPredicate.test_it_call_False": "PASSED",
    "Test_PhysicalPathPredicate.test_it_call_context_has_no_name": "PASSED",
    "Test_PhysicalPathPredicate.test_it_call_val_list_True": "PASSED",
    "Test_PhysicalPathPredicate.test_it_call_val_str_True": "PASSED",
    "Test_PhysicalPathPredicate.test_it_call_val_tuple_True": "PASSED",
    "Test_PhysicalPathPredicate.test_phash": "PASSED",
    "Test_PhysicalPathPredicate.test_text": "PASSED",
    "Test_EffectivePrincipalsPredicate.test_it_call_authentication_policy_doesnt_provide_superset": "PASSED",
    "Test_EffectivePrincipalsPredicate.test_it_call_authentication_policy_provides_superset": "PASSED",
    "Test_EffectivePrincipalsPredicate.test_it_call_authentication_policy_provides_superset_implicit": "PASSED",
    "Test_EffectivePrincipalsPredicate.test_it_call_no_authentication_policy": "PASSED",
    "Test_EffectivePrincipalsPredicate.test_phash": "PASSED",
    "Test_EffectivePrincipalsPredicate.test_text": "PASSED",
    "Test_EffectivePrincipalsPredicate.test_text_noniter": "PASSED",
    "TestRenderingConfiguratorMixin.test_add_default_renderers": "PASSED",
    "TestRenderingConfiguratorMixin.test_add_renderer": "PASSED",
    "TestRenderingConfiguratorMixin.test_add_renderer_dottedname_factory": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_defaults": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_discriminator": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_no_path_no_pattern": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_no_pattern_with_path": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_no_view_with_view_attr": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_no_view_with_view_context": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_no_view_with_view_permission": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_no_view_with_view_renderer": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_accept": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_custom_predicates": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_factory": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_factory_dottedname": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_header": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_path_info": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_path_info_highorder": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_path_info_regex": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_pregenerator": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_request_method": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_request_param": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_route_prefix": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_static": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_xhr": "PASSED",
    "RoutesConfiguratorMixinTests.test_get_routes_mapper_already_registered": "PASSED",
    "RoutesConfiguratorMixinTests.test_get_routes_mapper_not_yet_registered": "PASSED",
    "ConfiguratorSecurityMethodsTests.test_add_permission": "PASSED",
    "ConfiguratorSecurityMethodsTests.test_set_authentication_policy_no_authz_policy": "PASSED",
    "ConfiguratorSecurityMethodsTests.test_set_authentication_policy_no_authz_policy_autocommit": "PASSED",
    "ConfiguratorSecurityMethodsTests.test_set_authentication_policy_with_authz_policy": "PASSED",
    "ConfiguratorSecurityMethodsTests.test_set_authentication_policy_with_authz_policy_autocommit": "PASSED",
    "ConfiguratorSecurityMethodsTests.test_set_authorization_policy_no_authn_policy": "PASSED",
    "ConfiguratorSecurityMethodsTests.test_set_authorization_policy_no_authn_policy_autocommit": "PASSED",
    "ConfiguratorSecurityMethodsTests.test_set_authorization_policy_with_authn_policy": "PASSED",
    "ConfiguratorSecurityMethodsTests.test_set_authorization_policy_with_authn_policy_autocommit": "PASSED",
    "ConfiguratorSecurityMethodsTests.test_set_default_permission": "PASSED",
    "TestSettingsConfiguratorMixin.test__set_settings_as_None": "PASSED",
    "TestSettingsConfiguratorMixin.test__set_settings_as_dictwithvalues": "PASSED",
    "TestSettingsConfiguratorMixin.test_add_settings_settings_None": "PASSED",
    "TestSettingsConfiguratorMixin.test_add_settings_settings_already_registered": "PASSED",
    "TestSettingsConfiguratorMixin.test_add_settings_settings_not_yet_registered": "PASSED",
    "TestSettingsConfiguratorMixin.test_get_settings_nosettings": "PASSED",
    "TestSettingsConfiguratorMixin.test_get_settings_withsettings": "PASSED",
    "TestSettings.test_debug_all": "PASSED",
    "TestSettings.test_debug_authorization": "PASSED",
    "TestSettings.test_debug_notfound": "PASSED",
    "TestSettings.test_debug_routematch": "PASSED",
    "TestSettings.test_debug_templates": "PASSED",
    "TestSettings.test_default_locale_name": "PASSED",
    "TestSettings.test_getattr_fail": "PASSED",
    "TestSettings.test_getattr_raises_attribute_error": "PASSED",
    "TestSettings.test_getattr_success": "PASSED",
    "TestSettings.test_noargs": "PASSED",
    "TestSettings.test_originals_kept": "PASSED",
    "TestSettings.test_prevent_http_cache": "PASSED",
    "TestSettings.test_reload_all": "PASSED",
    "TestSettings.test_reload_assets": "PASSED",
    "TestSettings.test_reload_resources": "PASSED",
    "TestSettings.test_reload_templates": "PASSED",
    "TestingConfiguratorMixinTests.test_testing_add_renderer": "PASSED",
    "TestingConfiguratorMixinTests.test_testing_add_renderer_explicitrenderer": "PASSED",
    "TestingConfiguratorMixinTests.test_testing_add_renderer_twice": "PASSED",
    "TestingConfiguratorMixinTests.test_testing_add_subscriber_defaults": "PASSED",
    "TestingConfiguratorMixinTests.test_testing_add_subscriber_dottedname": "PASSED",
    "TestingConfiguratorMixinTests.test_testing_add_subscriber_multiple": "PASSED",
    "TestingConfiguratorMixinTests.test_testing_add_subscriber_single": "PASSED",
    "TestingConfiguratorMixinTests.test_testing_add_template": "PASSED",
    "TestingConfiguratorMixinTests.test_testing_resources": "PASSED",
    "TestingConfiguratorMixinTests.test_testing_securitypolicy": "PASSED",
    "TestingConfiguratorMixinTests.test_testing_securitypolicy_forget_result": "PASSED",
    "TestingConfiguratorMixinTests.test_testing_securitypolicy_remember_result": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tween_dottedname": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tween_instance": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tween_name_ingress": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tween_name_main": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tween_over_ingress": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tween_over_ingress_iterable": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tween_under_main": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tween_under_main_iterable": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tween_unsuitable": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tweens_conflict": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tweens_names_distinct": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tweens_names_with_over_nonstringoriter": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tweens_names_with_under_nonstringoriter": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tweens_names_with_underover": "PASSED",
    "TestTweens.test___call___explicit": "PASSED",
    "TestTweens.test___call___implicit": "PASSED",
    "TestTweens.test_add_explicit": "PASSED",
    "TestTweens.test_add_implicit": "PASSED",
    "TestTweens.test_implicit_ordering_1": "PASSED",
    "TestTweens.test_implicit_ordering_2": "PASSED",
    "TestTweens.test_implicit_ordering_3": "PASSED",
    "TestTweens.test_implicit_ordering_4": "PASSED",
    "TestTweens.test_implicit_ordering_5": "PASSED",
    "TestTweens.test_implicit_ordering_conflict_direct": "PASSED",
    "TestTweens.test_implicit_ordering_conflict_indirect": "PASSED",
    "TestTweens.test_implicit_ordering_missing_over_and_under_partials": "PASSED",
    "TestTweens.test_implicit_ordering_missing_over_partial": "PASSED",
    "TestTweens.test_implicit_ordering_missing_over_partial_with_fallback": "PASSED",
    "TestTweens.test_implicit_ordering_missing_under_partial": "PASSED",
    "TestTweens.test_implicit_ordering_missing_under_partial_with_fallback": "PASSED",
    "TestTweens.test_implicit_ordering_with_missing_fallbacks": "PASSED",
    "TestTweens.test_implicit_ordering_with_multiple_matching_fallbacks": "PASSED",
    "TestTweens.test_implicit_ordering_with_partial_fallbacks": "PASSED",
    "TestPredicateList.test_custom_predicates_can_affect_traversal": "PASSED",
    "TestPredicateList.test_different_custom_predicates_with_same_hash": "PASSED",
    "TestPredicateList.test_match_param_from_dict": "PASSED",
    "TestPredicateList.test_match_param_from_dict_fails": "PASSED",
    "TestPredicateList.test_match_param_from_string": "PASSED",
    "TestPredicateList.test_match_param_from_string_fails": "PASSED",
    "TestPredicateList.test_notted": "PASSED",
    "TestPredicateList.test_ordering_importance_and_number": "PASSED",
    "TestPredicateList.test_ordering_importance_of_predicates": "PASSED",
    "TestPredicateList.test_ordering_number_of_predicates": "PASSED",
    "TestPredicateList.test_ordering_xhr_and_request_method_trump_only_containment": "PASSED",
    "TestPredicateList.test_predicate_text_is_correct": "PASSED",
    "TestPredicateList.test_request_method_ordering_hashes_same": "PASSED",
    "TestPredicateList.test_request_method_sequence": "PASSED",
    "TestPredicateList.test_traverse_has_remainder_already": "PASSED",
    "TestPredicateList.test_traverse_matches": "PASSED",
    "TestPredicateList.test_traverse_matches_with_highorder_chars": "PASSED",
    "TestPredicateList.test_unknown_predicate": "PASSED",
    "Test_takes_one_arg.test_function_defaultargs_firstname_not_request": "PASSED",
    "Test_takes_one_arg.test_function_defaultargs_firstname_request": "PASSED",
    "Test_takes_one_arg.test_function_noargs": "PASSED",
    "Test_takes_one_arg.test_function_onearg_named_request": "PASSED",
    "Test_takes_one_arg.test_function_onearg_named_somethingelse": "PASSED",
    "Test_takes_one_arg.test_function_toomanyargs": "PASSED",
    "Test_takes_one_arg.test_function_with_attr_false": "PASSED",
    "Test_takes_one_arg.test_function_with_attr_true": "PASSED",
    "Test_takes_one_arg.test_instance_defaultargs_firstname_not_request": "PASSED",
    "Test_takes_one_arg.test_instance_defaultargs_firstname_request": "PASSED",
    "Test_takes_one_arg.test_instance_defaultargs_onearg_named_request": "PASSED",
    "Test_takes_one_arg.test_instance_defaultargs_onearg_named_somethingelse": "PASSED",
    "Test_takes_one_arg.test_instance_nocall": "PASSED",
    "Test_takes_one_arg.test_instance_toomanyargs": "PASSED",
    "Test_takes_one_arg.test_method_onearg_named_request": "PASSED",
    "Test_takes_one_arg.test_newstyle_class_init_defaultargs_firstname_not_request": "PASSED",
    "Test_takes_one_arg.test_newstyle_class_init_defaultargs_firstname_request": "PASSED",
    "Test_takes_one_arg.test_newstyle_class_init_firstname_request_with_secondname": "PASSED",
    "Test_takes_one_arg.test_newstyle_class_init_noargs": "PASSED",
    "Test_takes_one_arg.test_newstyle_class_init_onearg_named_somethingelse": "PASSED",
    "Test_takes_one_arg.test_oldstyle_class_init_defaultargs_firstname_not_request": "PASSED",
    "Test_takes_one_arg.test_oldstyle_class_init_defaultargs_firstname_request": "PASSED",
    "Test_takes_one_arg.test_oldstyle_class_init_noargs": "PASSED",
    "Test_takes_one_arg.test_oldstyle_class_init_onearg_named_request": "PASSED",
    "Test_takes_one_arg.test_oldstyle_class_init_onearg_named_somethingelse": "PASSED",
    "Test_takes_one_arg.test_oldstyle_class_init_toomanyargs": "PASSED",
    "Test_takes_one_arg.test_oldstyle_class_no_init": "PASSED",
    "Test_takes_one_arg.test_requestonly_newstyle_class_init_onearg_named_request": "PASSED",
    "Test_takes_one_arg.test_requestonly_newstyle_class_init_toomanyargs": "PASSED",
    "Test_takes_one_arg.test_requestonly_newstyle_class_no_init": "PASSED",
    "TestNotted.test_it_with_phash_val": "PASSED",
    "TestNotted.test_it_without_phash_val": "PASSED",
    "TestViewsConfigurationMixin.test_add_static_view_here_no_utility_registered": "FAILED",
    "TestViewDeriver.test_as_instance_requestonly": "FAILED",
    "Test_logging_file_config.test_it": "PASSED",
    "TestParseVars.test_parse_vars_bad": "PASSED",
    "TestParseVars.test_parse_vars_good": "PASSED",
    "TestPCreateCommand.test_known_scaffold_absolute_path": "PASSED",
    "TestPCreateCommand.test_known_scaffold_multiple_rendered": "PASSED",
    "TestPCreateCommand.test_known_scaffold_single_rendered": "PASSED",
    "TestPCreateCommand.test_known_scaffold_with_path_as_project_target_rendered": "PASSED",
    "TestPCreateCommand.test_no_project_name": "PASSED",
    "TestPCreateCommand.test_run_no_scaffold_name": "PASSED",
    "TestPCreateCommand.test_run_show_scaffolds_exist": "PASSED",
    "TestPCreateCommand.test_run_show_scaffolds_none_exist": "PASSED",
    "TestPCreateCommand.test_unknown_scaffold_name": "PASSED",
    "Test_main.test_it": "PASSED",
    "TestPDistReportCommand.test_no_dists": "PASSED",
    "TestPDistReportCommand.test_with_dists": "PASSED",
    "TestPRequestCommand.test_command_has_bad_config_header": "PASSED",
    "TestPRequestCommand.test_command_not_enough_args": "PASSED",
    "TestPRequestCommand.test_command_response_has_no_charset": "PASSED",
    "TestPRoutesCommand.test__get_mapper": "PASSED",
    "TestPRoutesCommand.test_bad_args": "PASSED",
    "TestPRoutesCommand.test_good_args": "PASSED",
    "TestPRoutesCommand.test_no_mapper": "PASSED",
    "TestPRoutesCommand.test_no_routes": "PASSED",
    "TestPRoutesCommand.test_route_with_no_slash_prefix": "PASSED",
    "TestPRoutesCommand.test_single_route_no_route_registered": "PASSED",
    "TestPRoutesCommand.test_single_route_no_views_registered": "PASSED",
    "TestPRoutesCommand.test_single_route_one_view_registered": "PASSED",
    "TestPRoutesCommand.test_single_route_one_view_registered_with_factory": "PASSED",
    "TestPServeCommand.test_get_options_no_command": "PASSED",
    "TestPServeCommand.test_get_options_with_command": "PASSED",
    "TestPServeCommand.test_parse_vars_bad": "PASSED",
    "TestPServeCommand.test_parse_vars_good": "PASSED",
    "TestPServeCommand.test_record_pid_not_verbose": "PASSED",
    "TestPServeCommand.test_record_pid_verbose": "PASSED",
    "TestPServeCommand.test_remove_pid_current_pid_is_not_pid_in_file": "PASSED",
    "TestPServeCommand.test_remove_pid_current_pid_is_not_written_pid": "PASSED",
    "TestPServeCommand.test_remove_pid_file_not_verbose": "PASSED",
    "TestPServeCommand.test_remove_pid_file_stale_pid_write_exception": "PASSED",
    "TestPServeCommand.test_remove_pid_file_unlink_exception": "PASSED",
    "TestPServeCommand.test_remove_pid_file_verbose": "PASSED",
    "TestPServeCommand.test_remove_pid_no_pid_file": "PASSED",
    "TestPServeCommand.test_remove_pid_not_a_number": "PASSED",
    "TestPServeCommand.test_run_no_args": "PASSED",
    "TestPServeCommand.test_run_stop_daemon_bad_pid_file": "PASSED",
    "TestPServeCommand.test_run_stop_daemon_invalid_pid_in_file": "PASSED",
    "TestPServeCommand.test_run_stop_daemon_no_such_pid_file": "PASSED",
    "Test_read_pidfile.test_read_pidfile": "PASSED",
    "Test_read_pidfile.test_read_pidfile_no_pid_file": "PASSED",
    "Test_read_pidfile.test_read_pidfile_not_a_number": "PASSED",
    "TestLazyWriter.test_flush": "PASSED",
    "TestLazyWriter.test_open": "PASSED",
    "TestLazyWriter.test_write": "PASSED",
    "TestLazyWriter.test_writeline": "PASSED",
    "Test__methodwrapper.test___call__fail": "PASSED",
    "Test__methodwrapper.test___call__succeed": "PASSED",
    "TestPShellCommand.test_command_custom_section_override": "PASSED",
    "TestPShellCommand.test_command_loads_bpython_shell": "PASSED",
    "TestPShellCommand.test_command_loads_check_variable_override_order": "PASSED",
    "TestPShellCommand.test_command_loads_custom_items": "PASSED",
    "TestPShellCommand.test_command_loads_default_shell": "PASSED",
    "TestPShellCommand.test_command_loads_default_shell_with_unknown_shell": "PASSED",
    "TestPShellCommand.test_command_loads_ipython_v0_10": "PASSED",
    "TestPShellCommand.test_command_loads_ipython_v0_11": "PASSED",
    "TestPShellCommand.test_command_loads_setup_from_options": "PASSED",
    "TestPShellCommand.test_command_setup": "PASSED",
    "TestPShellCommand.test_make_bpython_shell": "PASSED",
    "TestPShellCommand.test_make_default_shell": "PASSED",
    "TestPShellCommand.test_make_ipython_v0_10_shell": "PASSED",
    "TestPShellCommand.test_make_ipython_v0_11_shell": "PASSED",
    "TestPShellCommand.test_shell_ipython_ordering": "PASSED",
    "TestPShellCommand.test_shell_ordering": "PASSED",
    "TestPTweensCommand.test__get_tweens": "PASSED",
    "TestPTweensCommand.test_command_implicit_and_explicit_tweens": "PASSED",
    "TestPTweensCommand.test_command_implicit_tweens_only": "PASSED",
    "TestPTweensCommand.test_command_no_tweens": "PASSED",
    "TestPViewsCommand.test__find_multi_routes_all_match": "PASSED",
    "TestPViewsCommand.test__find_multi_routes_none_match": "PASSED",
    "TestPViewsCommand.test__find_multi_routes_some_match": "PASSED",
    "TestPViewsCommand.test__find_view_no_match": "PASSED",
    "TestPViewsCommand.test__find_view_no_match_multiview_registered": "PASSED",
    "TestPViewsCommand.test__find_view_route_multiview": "PASSED",
    "TestPViewsCommand.test__find_view_route_multiview_no_view_registered": "PASSED",
    "TestPViewsCommand.test__find_view_route_no_multiview": "PASSED",
    "TestPViewsCommand.test__find_view_traversal": "PASSED",
    "TestPViewsCommand.test__find_view_traversal_multiview": "PASSED",
    "TestPViewsCommand.test_views_command_multi_view_nested": "PASSED",
    "TestPViewsCommand.test_views_command_multiview": "PASSED",
    "TestPViewsCommand.test_views_command_multiview_with_permission": "PASSED",
    "TestPViewsCommand.test_views_command_multiview_with_predicates": "PASSED",
    "TestPViewsCommand.test_views_command_not_found": "PASSED",
    "TestPViewsCommand.test_views_command_not_found_url_starts_without_slash": "PASSED",
    "TestPViewsCommand.test_views_command_single_view_route": "PASSED",
    "TestPViewsCommand.test_views_command_single_view_route_with_route_predicates": "PASSED",
    "TestPViewsCommand.test_views_command_single_view_traversal": "PASSED",
    "TestPViewsCommand.test_views_command_single_view_traversal_with_permission": "PASSED",
    "TestPViewsCommand.test_views_command_single_view_traversal_with_predicates": "PASSED",
    "TestViewsConfigurationMixin.test_add_static_view_package_here_relative": "FAILED",
    "TestViewsConfigurationMixin.test_add_view_custom_predicate_bests_standard_predicate": "FAILED",
    "TestViewsConfigurationMixin.test_add_view_with_custom_predicates_match": "FAILED",
    "TestViewsConfigurationMixin.test_add_view_with_custom_predicates_nomatch": "FAILED",
    "TestViewsConfigurationMixin.test_add_view_with_template_renderer": "FAILED",
    "TestViewsConfigurationMixin.test_add_view_with_template_renderer_no_callable": "FAILED",
    "TestViewDeriver.test_function_returns_non_adaptable": "FAILED",
    "TestViewDeriver.test_function_returns_non_adaptable_dict": "FAILED",
    "TestViewDeriver.test_instance_returns_non_adaptable": "FAILED",
    "TestViewDeriver.test_requestonly_default_method_returns_non_adaptable": "FAILED",
    "TestViewDeriver.test_requestonly_nondefault_method_returns_non_adaptable": "FAILED",
    "Test_view_description.test_without_text": "FAILED",
    "AdaptersConfiguratorMixinTests.test_add_resource_url_adapter_dotted_names": "FAILED",
    "AdaptersConfiguratorMixinTests.test_add_resource_url_adapter_introspectables": "FAILED",
    "AdaptersConfiguratorMixinTests.test_add_traverser_dotted_names": "FAILED",
    "TestOverrideProvider.test_get_resource_filename_no_overrides": "FAILED",
    "TestOverrideProvider.test_get_resource_filename_override_returns_None": "FAILED",
    "TestPackageOverrides.test_get_filename": "FAILED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_abspath": "FAILED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_asset_spec": "FAILED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_asset_spec_existing_translation_dirs": "FAILED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_multiple_specs": "FAILED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_multiple_specs_multiple_calls": "FAILED",
    "ConfiguratorTests.test_ctor_no_registry": "FAILED",
    "ConfiguratorTests.test_ctor_noreg_debug_logger_None_default": "FAILED",
    "ConfiguratorTests.test_scan_integration_conflict": "FAILED",
    "ConfiguratorTests.test_setup_registry_debug_logger_None_default": "FAILED",
    "TestConfigurator_add_directive.test_add_directive_with_custom_callable": "FAILED",
    "TestConfigurator_add_directive.test_add_directive_with_partial": "FAILED",
    "TestConfigurator_add_directive.test_extend_with_dotted_name": "FAILED",
    "TestConfigurator_add_directive.test_extend_with_python_callable": "FAILED",
    "TestConfigurator__add_predicate.test_factory_as_dotted_name": "FAILED",
    "TestPRequestCommand.test_command_display_headers": "FAILED",
    "TestPRequestCommand.test_command_has_content_type_header_var": "FAILED",
    "TestPRequestCommand.test_command_has_good_header_var": "FAILED",
    "TestPRequestCommand.test_command_has_multiple_header_vars": "FAILED",
    "TestPRequestCommand.test_command_method_get": "FAILED",
    "TestPRequestCommand.test_command_method_options": "FAILED",
    "TestPRequestCommand.test_command_method_patch": "FAILED",
    "TestPRequestCommand.test_command_method_post": "FAILED",
    "TestPRequestCommand.test_command_method_propfind": "FAILED",
    "TestPRequestCommand.test_command_method_put": "FAILED",
    "TestPRequestCommand.test_command_path_doesnt_start_with_slash": "FAILED",
    "TestPRequestCommand.test_command_two_args": "FAILED",
    "TestPRequestCommand.test_command_w_basic_auth": "FAILED",
    "TestPRequestCommand.test_command_with_query_string": "FAILED",
    "TestPViewsCommand.test_views_command_single_view_function_traversal": "FAILED"
}
diff --git a/pyramid/config/views.py b/pyramid/config/views.py
index 233bbac12..69f68e422 100644
--- a/pyramid/config/views.py
+++ b/pyramid/config/views.py
@@ -1550,6 +1550,7 @@ class ViewsConfiguratorMixin(object):
 
         return deriver(view)
 
+    @viewdefaults
     @action_method
     def add_forbidden_view(
         self,
@@ -1629,6 +1630,7 @@ class ViewsConfiguratorMixin(object):
 
     set_forbidden_view = add_forbidden_view # deprecated sorta-bw-compat alias
     
+    @viewdefaults
     @action_method
     def add_notfound_view(
         self,

{"pyramid/config/views.py": "import inspect\nimport operator\nimport os\nimport warnings\n\nfrom zope.interface import (\n    Interface,\n    implementedBy,\n    implementer,\n    provider,\n    )\n\nfrom zope.interface.interfaces import IInterface\n\nfrom pyramid.interfaces import (\n    IAuthenticationPolicy,\n    IAuthorizationPolicy,\n    IDebugLogger,\n    IDefaultPermission,\n    IException,\n    IExceptionViewClassifier,\n    IMultiView,\n    IRendererFactory,\n    IRequest,\n    IResponse,\n    IRouteRequest,\n    ISecuredView,\n    IStaticURLInfo,\n    IView,\n    IViewClassifier,\n    IViewMapper,\n    IViewMapperFactory,\n    PHASE1_CONFIG,\n    )\n\nfrom pyramid import renderers\n\nfrom pyramid.compat import (\n    string_types,\n    urlparse,\n    url_quote,\n    WIN,\n    is_bound_method,\n    is_nonstr_iter\n    )\n\nfrom pyramid.exceptions import (\n    ConfigurationError,\n    PredicateMismatch,\n    )\n\nfrom pyramid.httpexceptions import (\n    HTTPForbidden,\n    HTTPNotFound,\n    )\n\nfrom pyramid.registry import (\n    predvalseq,\n    Deferred,\n    )\n\nfrom pyramid.response import Response\n\nfrom pyramid.security import NO_PERMISSION_REQUIRED\nfrom pyramid.static import static_view\nfrom pyramid.threadlocal import get_current_registry\n\nfrom pyramid.view import (\n    render_view_to_response,\n    AppendSlashNotFoundViewFactory,\n    )\n\nfrom pyramid.util import (\n    object_description,\n    viewdefaults,\n    action_method,\n    )\n\nimport pyramid.config.predicates\n\nfrom pyramid.config.util import (\n    DEFAULT_PHASH,\n    MAX_ORDER,\n    takes_one_arg,\n    )\n\nurljoin = urlparse.urljoin\nurl_parse = urlparse.urlparse\n\ndef view_description(view):\n    try:\n        return view.__text__\n    except AttributeError:\n        # custom view mappers might not add __text__\n        return object_description(view)\n\ndef wraps_view(wrapper):\n    def inner(self, view):\n        wrapper_view = wrapper(self, view)\n        return preserve_view_attrs(view, wrapper_view)\n    return inner\n\ndef preserve_view_attrs(view, wrapper):\n    if view is None:\n        return wrapper\n\n    if wrapper is view:\n        return view\n\n    original_view = getattr(view, '__original_view__', None)\n\n    if original_view is None:\n        original_view = view\n\n    wrapper.__wraps__ = view\n    wrapper.__original_view__ = original_view\n    wrapper.__module__ = view.__module__\n    wrapper.__doc__ = view.__doc__\n\n    try:\n        wrapper.__name__ = view.__name__\n    except AttributeError:\n        wrapper.__name__ = repr(view)\n\n    # attrs that may not exist on \"view\", but, if so, must be attached to\n    # \"wrapped view\"\n    for attr in ('__permitted__', '__call_permissive__', '__permission__',\n                 '__predicated__', '__predicates__', '__accept__',\n                 '__order__', '__text__'):\n        try:\n            setattr(wrapper, attr, getattr(view, attr))\n        except AttributeError:\n            pass\n\n    return wrapper\n\nclass ViewDeriver(object):\n    def __init__(self, **kw):\n        self.kw = kw\n        self.registry = kw['registry']\n        self.authn_policy = self.registry.queryUtility(IAuthenticationPolicy)\n        self.authz_policy = self.registry.queryUtility(IAuthorizationPolicy)\n        self.logger = self.registry.queryUtility(IDebugLogger)\n\n    def __call__(self, view):\n        return self.attr_wrapped_view(\n            self.predicated_view(\n                self.authdebug_view(\n                    self.secured_view(\n                        self.owrapped_view(\n                            self.http_cached_view(\n                                self.decorated_view(\n                                    self.rendered_view(\n                                        self.mapped_view(\n                                                view)))))))))\n\n    @wraps_view\n    def mapped_view(self, view):\n        mapper = self.kw.get('mapper')\n        if mapper is None:\n            mapper = getattr(view, '__view_mapper__', None)\n            if mapper is None:\n                mapper = self.registry.queryUtility(IViewMapperFactory)\n                if mapper is None:\n                    mapper = DefaultViewMapper\n\n        mapped_view = mapper(**self.kw)(view)\n        return mapped_view\n\n    @wraps_view\n    def owrapped_view(self, view):\n        wrapper_viewname = self.kw.get('wrapper_viewname')\n        viewname = self.kw.get('viewname')\n        if not wrapper_viewname:\n            return view\n        def _owrapped_view(context, request):\n            response = view(context, request)\n            request.wrapped_response = response\n            request.wrapped_body = response.body\n            request.wrapped_view = view\n            wrapped_response = render_view_to_response(context, request,\n                                                       wrapper_viewname)\n            if wrapped_response is None:\n                raise ValueError(\n                    'No wrapper view named %r found when executing view '\n                    'named %r' % (wrapper_viewname, viewname))\n            return wrapped_response\n        return _owrapped_view\n\n    @wraps_view\n    def http_cached_view(self, view):\n        if self.registry.settings.get('prevent_http_cache', False):\n            return view\n\n        seconds = self.kw.get('http_cache')\n\n        if seconds is None:\n            return view\n\n        options = {}\n\n        if isinstance(seconds, (tuple, list)):\n            try:\n                seconds, options = seconds\n            except ValueError:\n                raise ConfigurationError(\n                    'If http_cache parameter is a tuple or list, it must be '\n                    'in the form (seconds, options); not %s' % (seconds,))\n\n        def wrapper(context, request):\n            response = view(context, request)\n            prevent_caching = getattr(response.cache_control, 'prevent_auto',\n                                      False)\n            if not prevent_caching:\n                response.cache_expires(seconds, **options)\n            return response\n\n        return wrapper\n\n    @wraps_view\n    def secured_view(self, view):\n        permission = self.kw.get('permission')\n        if permission == NO_PERMISSION_REQUIRED:\n            # allow views registered within configurations that have a\n            # default permission to explicitly override the default\n            # permission, replacing it with no permission at all\n            permission = None\n\n        wrapped_view = view\n        if self.authn_policy and self.authz_policy and (permission is not None):\n            def _permitted(context, request):\n                principals = self.authn_policy.effective_principals(request)\n                return self.authz_policy.permits(context, principals,\n                                                 permission)\n            def _secured_view(context, request):\n                result = _permitted(context, request)\n                if result:\n                    return view(context, request)\n                view_name = getattr(view, '__name__', view)\n                msg = getattr(\n                    request, 'authdebug_message',\n                    'Unauthorized: %s failed permission check' % view_name)\n                raise HTTPForbidden(msg, result=result)\n            _secured_view.__call_permissive__ = view\n            _secured_view.__permitted__ = _permitted\n            _secured_view.__permission__ = permission\n            wrapped_view = _secured_view\n\n        return wrapped_view\n\n    @wraps_view\n    def authdebug_view(self, view):\n        wrapped_view = view\n        settings = self.registry.settings\n        permission = self.kw.get('permission')\n        if settings and settings.get('debug_authorization', False):\n            def _authdebug_view(context, request):\n                view_name = getattr(request, 'view_name', None)\n\n                if self.authn_policy and self.authz_policy:\n                    if permission is NO_PERMISSION_REQUIRED:\n                        msg = 'Allowed (NO_PERMISSION_REQUIRED)'\n                    elif permission is None:\n                        msg = 'Allowed (no permission registered)'\n                    else:\n                        principals = self.authn_policy.effective_principals(\n                            request)\n                        msg = str(self.authz_policy.permits(context, principals,\n                                                            permission))\n                else:\n                    msg = 'Allowed (no authorization policy in use)'\n\n                view_name = getattr(request, 'view_name', None)\n                url = getattr(request, 'url', None)\n                msg = ('debug_authorization of url %s (view name %r against '\n                       'context %r): %s' % (url, view_name, context, msg))\n                self.logger and self.logger.debug(msg)\n                if request is not None:\n                    request.authdebug_message = msg\n                return view(context, request)\n\n            wrapped_view = _authdebug_view\n\n        return wrapped_view\n\n    @wraps_view\n    def predicated_view(self, view):\n        preds = self.kw.get('predicates', ())\n        if not preds:\n            return view\n        def predicate_wrapper(context, request):\n            for predicate in preds:\n                if not predicate(context, request):\n                    view_name = getattr(view, '__name__', view)\n                    raise PredicateMismatch(\n                         'predicate mismatch for view %s (%s)' % (\n                         view_name, predicate.text()))\n            return view(context, request)        \n        def checker(context, request):\n            return all((predicate(context, request) for predicate in\n                        preds))\n        predicate_wrapper.__predicated__ = checker\n        predicate_wrapper.__predicates__ = preds\n        return predicate_wrapper\n\n    @wraps_view\n    def attr_wrapped_view(self, view):\n        kw = self.kw\n        accept, order, phash = (kw.get('accept', None),\n                                kw.get('order', MAX_ORDER),\n                                kw.get('phash', DEFAULT_PHASH))\n        # this is a little silly but we don't want to decorate the original\n        # function with attributes that indicate accept, order, and phash,\n        # so we use a wrapper\n        if (\n            (accept is None) and\n            (order == MAX_ORDER) and\n            (phash == DEFAULT_PHASH)\n            ):\n            return view # defaults\n        def attr_view(context, request):\n            return view(context, request)\n        attr_view.__accept__ = accept\n        attr_view.__order__ = order\n        attr_view.__phash__ = phash\n        attr_view.__view_attr__ = self.kw.get('attr')\n        attr_view.__permission__ = self.kw.get('permission')\n        return attr_view\n\n    @wraps_view\n    def rendered_view(self, view):\n        # one way or another this wrapper must produce a Response (unless\n        # the renderer is a NullRendererHelper)\n        renderer = self.kw.get('renderer')\n        if renderer is None:\n            # register a default renderer if you want super-dynamic\n            # rendering.  registering a default renderer will also allow\n            # override_renderer to work if a renderer is left unspecified for\n            # a view registration.\n            return self._response_resolved_view(view)\n        if renderer is renderers.null_renderer:\n            return view\n        return self._rendered_view(view, renderer)\n\n    def _rendered_view(self, view, view_renderer):\n        def rendered_view(context, request):\n            renderer = view_renderer\n            result = view(context, request)\n            if result.__class__ is Response: # potential common case\n                response = result\n            else:\n                registry = self.registry\n                # this must adapt, it can't do a simple interface check\n                # (avoid trying to render webob responses)\n                response = registry.queryAdapterOrSelf(result, IResponse)\n                if response is None:\n                    attrs = getattr(request, '__dict__', {})\n                    if 'override_renderer' in attrs:\n                        # renderer overridden by newrequest event or other\n                        renderer_name = attrs.pop('override_renderer')\n                        renderer = renderers.RendererHelper(\n                            name=renderer_name,\n                            package=self.kw.get('package'),\n                            registry = registry)\n                    if '__view__' in attrs:\n                        view_inst = attrs.pop('__view__')\n                    else:\n                        view_inst = getattr(view, '__original_view__', view)\n                    response = renderer.render_view(request, result, view_inst,\n                                                    context)\n            return response\n\n        return rendered_view\n\n    def _response_resolved_view(self, view):\n        registry = self.registry\n        def viewresult_to_response(context, request):\n            result = view(context, request)\n            if result.__class__ is Response: # common case\n                response = result\n            else:\n                response = registry.queryAdapterOrSelf(result, IResponse)\n                if response is None:\n                    if result is None:\n                        append = (' You may have forgotten to return a value '\n                                  'from the view callable.')\n                    elif isinstance(result, dict):\n                        append = (' You may have forgotten to define a '\n                                  'renderer in the view configuration.')\n                    else:\n                        append = ''\n\n                    msg = ('Could not convert return value of the view '\n                           'callable %s into a response object. '\n                           'The value returned was %r.' + append)\n\n                    raise ValueError(msg % (view_description(view), result))\n\n            return response\n\n        return viewresult_to_response\n\n    @wraps_view\n    def decorated_view(self, view):\n        decorator = self.kw.get('decorator')\n        if decorator is None:\n            return view\n        return decorator(view)\n\n@implementer(IViewMapper)\n@provider(IViewMapperFactory)\nclass DefaultViewMapper(object):\n    def __init__(self, **kw):\n        self.attr = kw.get('attr')\n\n    def __call__(self, view):\n        if inspect.isclass(view):\n            view = self.map_class(view)\n        else:\n            view = self.map_nonclass(view)\n        return view\n\n    def map_class(self, view):\n        ronly = requestonly(view, self.attr)\n        if ronly:\n            mapped_view = self.map_class_requestonly(view)\n        else:\n            mapped_view = self.map_class_native(view)\n        mapped_view.__text__ = 'method %s of %s' % (\n            self.attr or '__call__', object_description(view))\n        return mapped_view\n\n    def map_nonclass(self, view):\n        # We do more work here than appears necessary to avoid wrapping the\n        # view unless it actually requires wrapping (to avoid function call\n        # overhead).\n        mapped_view = view\n        ronly = requestonly(view, self.attr)\n        if ronly:\n            mapped_view = self.map_nonclass_requestonly(view)\n        elif self.attr:\n            mapped_view = self.map_nonclass_attr(view)\n        if inspect.isroutine(mapped_view):\n            # This branch will be true if the view is a function or a method.\n            # We potentially mutate an unwrapped object here if it's a\n            # function.  We do this to avoid function call overhead of\n            # injecting another wrapper.  However, we must wrap if the\n            # function is a bound method because we can't set attributes on a\n            # bound method.\n            if is_bound_method(view):\n                _mapped_view = mapped_view\n                def mapped_view(context, request):\n                    return _mapped_view(context, request)\n            if self.attr is not None:\n                mapped_view.__text__ = 'attr %s of %s' % (\n                    self.attr, object_description(view))\n            else:\n                mapped_view.__text__ = object_description(view)\n        return mapped_view\n\n    def map_class_requestonly(self, view):\n        # its a class that has an __init__ which only accepts request\n        attr = self.attr\n        def _class_requestonly_view(context, request):\n            inst = view(request)\n            request.__view__ = inst\n            if attr is None:\n                response = inst()\n            else:\n                response = getattr(inst, attr)()\n            return response\n        return _class_requestonly_view\n\n    def map_class_native(self, view):\n        # its a class that has an __init__ which accepts both context and\n        # request\n        attr = self.attr\n        def _class_view(context, request):\n            inst = view(context, request)\n            request.__view__ = inst\n            if attr is None:\n                response = inst()\n            else:\n                response = getattr(inst, attr)()\n            return response\n        return _class_view\n\n    def map_nonclass_requestonly(self, view):\n        # its a function that has a __call__ which accepts only a single\n        # request argument\n        attr = self.attr\n        def _requestonly_view(context, request):\n            if attr is None:\n                response = view(request)\n            else:\n                response = getattr(view, attr)(request)\n            return response\n        return _requestonly_view\n\n    def map_nonclass_attr(self, view):\n        # its a function that has a __call__ which accepts both context and\n        # request, but still has an attr\n        def _attr_view(context, request):\n            response = getattr(view, self.attr)(context, request)\n            return response\n        return _attr_view\n\ndef requestonly(view, attr=None):\n    return takes_one_arg(view, attr=attr, argname='request')\n\n@implementer(IMultiView)\nclass MultiView(object):\n\n    def __init__(self, name):\n        self.name = name\n        self.media_views = {}\n        self.views = []\n        self.accepts = []\n\n    def __discriminator__(self, context, request):\n        # used by introspection systems like so:\n        # view = adapters.lookup(....)\n        # view.__discriminator__(context, request) -> view's discriminator\n        # so that superdynamic systems can feed the discriminator to\n        # the introspection system to get info about it\n        view = self.match(context, request)\n        return view.__discriminator__(context, request)\n\n    def add(self, view, order, accept=None, phash=None):\n        if phash is not None:\n            for i, (s, v, h) in enumerate(list(self.views)):\n                if phash == h:\n                    self.views[i] = (order, view, phash)\n                    return\n\n        if accept is None or '*' in accept:\n            self.views.append((order, view, phash))\n            self.views.sort(key=operator.itemgetter(0))\n        else:\n            subset = self.media_views.setdefault(accept, [])\n            for i, (s, v, h) in enumerate(list(subset)):\n                if phash == h:\n                    subset[i] = (order, view, phash)\n                    return\n            else:\n                subset.append((order, view, phash))\n                subset.sort(key=operator.itemgetter(0))\n            accepts = set(self.accepts)\n            accepts.add(accept)\n            self.accepts = list(accepts) # dedupe\n\n    def get_views(self, request):\n        if self.accepts and hasattr(request, 'accept'):\n            accepts = self.accepts[:]\n            views = []\n            while accepts:\n                match = request.accept.best_match(accepts)\n                if match is None:\n                    break\n                subset = self.media_views[match]\n                views.extend(subset)\n                accepts.remove(match)\n            views.extend(self.views)\n            return views\n        return self.views\n\n    def match(self, context, request):\n        for order, view, phash in self.get_views(request):\n            if not hasattr(view, '__predicated__'):\n                return view\n            if view.__predicated__(context, request):\n                return view\n        raise PredicateMismatch(self.name)\n\n    def __permitted__(self, context, request):\n        view = self.match(context, request)\n        if hasattr(view, '__permitted__'):\n            return view.__permitted__(context, request)\n        return True\n\n    def __call_permissive__(self, context, request):\n        view = self.match(context, request)\n        view = getattr(view, '__call_permissive__', view)\n        return view(context, request)\n\n    def __call__(self, context, request):\n        for order, view, phash in self.get_views(request):\n            try:\n                return view(context, request)\n            except PredicateMismatch:\n                continue\n        raise PredicateMismatch(self.name)\n\nclass ViewsConfiguratorMixin(object):\n    @viewdefaults\n    @action_method\n    def add_view(\n        self,\n        view=None,\n        name=\"\",\n        for_=None,\n        permission=None,\n        request_type=None,\n        route_name=None,\n        request_method=None,\n        request_param=None,\n        containment=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        context=None,\n        decorator=None,\n        mapper=None,\n        http_cache=None,\n        match_param=None,\n        check_csrf=None,\n        **predicates):\n        \"\"\" Add a :term:`view configuration` to the current\n        configuration state.  Arguments to ``add_view`` are broken\n        down below into *predicate* arguments and *non-predicate*\n        arguments.  Predicate arguments narrow the circumstances in\n        which the view callable will be invoked when a request is\n        presented to :app:`Pyramid`; non-predicate arguments are\n        informational.\n\n        Non-Predicate Arguments\n\n        view\n\n          A :term:`view callable` or a :term:`dotted Python name`\n          which refers to a view callable.  This argument is required\n          unless a ``renderer`` argument also exists.  If a\n          ``renderer`` argument is passed, and a ``view`` argument is\n          not provided, the view callable defaults to a callable that\n          returns an empty dictionary (see\n          :ref:`views_which_use_a_renderer`).\n\n        permission\n\n          A :term:`permission` that the user must possess in order to invoke\n          the :term:`view callable`.  See :ref:`view_security_section` for\n          more information about view security and permissions.  This is\n          often a string like ``view`` or ``edit``.\n\n          If ``permission`` is omitted, a *default* permission may be used\n          for this view registration if one was named as the\n          :class:`pyramid.config.Configurator` constructor's\n          ``default_permission`` argument, or if\n          :meth:`pyramid.config.Configurator.set_default_permission` was used\n          prior to this view registration.  Pass the value\n          :data:`pyramid.security.NO_PERMISSION_REQUIRED` as the permission\n          argument to explicitly indicate that the view should always be\n          executable by entirely anonymous users, regardless of the default\n          permission, bypassing any :term:`authorization policy` that may be\n          in effect.\n\n        attr\n\n          This knob is most useful when the view definition is a class.\n\n          The view machinery defaults to using the ``__call__`` method\n          of the :term:`view callable` (or the function itself, if the\n          view callable is a function) to obtain a response.  The\n          ``attr`` value allows you to vary the method attribute used\n          to obtain the response.  For example, if your view was a\n          class, and the class has a method named ``index`` and you\n          wanted to use this method instead of the class' ``__call__``\n          method to return the response, you'd say ``attr=\"index\"`` in the\n          view configuration for the view.\n\n        renderer\n\n          This is either a single string term (e.g. ``json``) or a\n          string implying a path or :term:`asset specification`\n          (e.g. ``templates/views.pt``) naming a :term:`renderer`\n          implementation.  If the ``renderer`` value does not contain\n          a dot ``.``, the specified string will be used to look up a\n          renderer implementation, and that renderer implementation\n          will be used to construct a response from the view return\n          value.  If the ``renderer`` value contains a dot (``.``),\n          the specified term will be treated as a path, and the\n          filename extension of the last element in the path will be\n          used to look up the renderer implementation, which will be\n          passed the full path.  The renderer implementation will be\n          used to construct a :term:`response` from the view return\n          value.\n\n          Note that if the view itself returns a :term:`response` (see\n          :ref:`the_response`), the specified renderer implementation\n          is never called.\n\n          When the renderer is a path, although a path is usually just\n          a simple relative pathname (e.g. ``templates/foo.pt``,\n          implying that a template named \"foo.pt\" is in the\n          \"templates\" directory relative to the directory of the\n          current :term:`package` of the Configurator), a path can be\n          absolute, starting with a slash on UNIX or a drive letter\n          prefix on Windows.  The path can alternately be a\n          :term:`asset specification` in the form\n          ``some.dotted.package_name:relative/path``, making it\n          possible to address template assets which live in a\n          separate package.\n\n          The ``renderer`` attribute is optional.  If it is not\n          defined, the \"null\" renderer is assumed (no rendering is\n          performed and the value is passed back to the upstream\n          :app:`Pyramid` machinery unmodified).\n\n        http_cache\n\n          .. versionadded:: 1.1\n\n          When you supply an ``http_cache`` value to a view configuration,\n          the ``Expires`` and ``Cache-Control`` headers of a response\n          generated by the associated view callable are modified.  The value\n          for ``http_cache`` may be one of the following:\n\n          - A nonzero integer.  If it's a nonzero integer, it's treated as a\n            number of seconds.  This number of seconds will be used to\n            compute the ``Expires`` header and the ``Cache-Control:\n            max-age`` parameter of responses to requests which call this view.\n            For example: ``http_cache=3600`` instructs the requesting browser\n            to 'cache this response for an hour, please'.\n\n          - A ``datetime.timedelta`` instance.  If it's a\n            ``datetime.timedelta`` instance, it will be converted into a\n            number of seconds, and that number of seconds will be used to\n            compute the ``Expires`` header and the ``Cache-Control:\n            max-age`` parameter of responses to requests which call this view.\n            For example: ``http_cache=datetime.timedelta(days=1)`` instructs\n            the requesting browser to 'cache this response for a day, please'.\n\n          - Zero (``0``).  If the value is zero, the ``Cache-Control`` and\n            ``Expires`` headers present in all responses from this view will\n            be composed such that client browser cache (and any intermediate\n            caches) are instructed to never cache the response.\n\n          - A two-tuple.  If it's a two tuple (e.g. ``http_cache=(1,\n            {'public':True})``), the first value in the tuple may be a\n            nonzero integer or a ``datetime.timedelta`` instance; in either\n            case this value will be used as the number of seconds to cache\n            the response.  The second value in the tuple must be a\n            dictionary.  The values present in the dictionary will be used as\n            input to the ``Cache-Control`` response header.  For example:\n            ``http_cache=(3600, {'public':True})`` means 'cache for an hour,\n            and add ``public`` to the Cache-Control header of the response'.\n            All keys and values supported by the\n            ``webob.cachecontrol.CacheControl`` interface may be added to the\n            dictionary.  Supplying ``{'public':True}`` is equivalent to\n            calling ``response.cache_control.public = True``.\n\n          Providing a non-tuple value as ``http_cache`` is equivalent to\n          calling ``response.cache_expires(value)`` within your view's body.\n\n          Providing a two-tuple value as ``http_cache`` is equivalent to\n          calling ``response.cache_expires(value[0], **value[1])`` within your\n          view's body.\n\n          If you wish to avoid influencing, the ``Expires`` header, and\n          instead wish to only influence ``Cache-Control`` headers, pass a\n          tuple as ``http_cache`` with the first element of ``None``, e.g.:\n          ``(None, {'public':True})``.\n\n          If you wish to prevent a view that uses ``http_cache`` in its\n          configuration from having its caching response headers changed by\n          this machinery, set ``response.cache_control.prevent_auto = True``\n          before returning the response from the view.  This effectively\n          disables any HTTP caching done by ``http_cache`` for that response.\n\n        wrapper\n\n          The :term:`view name` of a different :term:`view\n          configuration` which will receive the response body of this\n          view as the ``request.wrapped_body`` attribute of its own\n          :term:`request`, and the :term:`response` returned by this\n          view as the ``request.wrapped_response`` attribute of its\n          own request.  Using a wrapper makes it possible to \"chain\"\n          views together to form a composite response.  The response\n          of the outermost wrapper view will be returned to the user.\n          The wrapper view will be found as any view is found: see\n          :ref:`view_lookup`.  The \"best\" wrapper view will be found\n          based on the lookup ordering: \"under the hood\" this wrapper\n          view is looked up via\n          ``pyramid.view.render_view_to_response(context, request,\n          'wrapper_viewname')``. The context and request of a wrapper\n          view is the same context and request of the inner view.  If\n          this attribute is unspecified, no view wrapping is done.\n\n        decorator\n\n          A :term:`dotted Python name` to function (or the function itself,\n          or an iterable of the aforementioned) which will be used to\n          decorate the registered :term:`view callable`.  The decorator\n          function(s) will be called with the view callable as a single\n          argument.  The view callable it is passed will accept\n          ``(context, request)``.  The decorator(s) must return a\n          replacement view callable which also accepts ``(context,\n          request)``.\n\n          If decorator is an iterable, the callables will be combined and\n          used in the order provided as a decorator.\n          For example::\n\n            @view_config(...,\n                decorator=(decorator2,\n                           decorator1))\n            def myview(request):\n                ....\n\n          Is similar to doing::\n\n            @view_config(...)\n            @decorator2\n            @decorator1\n            def myview(request):\n                ...\n\n          Except with the existing benefits of ``decorator=`` (having a common\n          decorator syntax for all view calling conventions and not having to\n          think about preserving function attributes such as ``__name__`` and\n          ``__module__`` within decorator logic).\n\n          .. versionchanged:: 1.4a4\n             Passing an iterable.\n\n        mapper\n\n          A Python object or :term:`dotted Python name` which refers to a\n          :term:`view mapper`, or ``None``.  By default it is ``None``, which\n          indicates that the view should use the default view mapper.  This\n          plug-point is useful for Pyramid extension developers, but it's not\n          very useful for 'civilians' who are just developing stock Pyramid\n          applications. Pay no attention to the man behind the curtain.\n\n        Predicate Arguments\n\n        name\n\n          The :term:`view name`.  Read :ref:`traversal_chapter` to\n          understand the concept of a view name.\n\n        context\n\n          An object or a :term:`dotted Python name` referring to an\n          interface or class object that the :term:`context` must be\n          an instance of, *or* the :term:`interface` that the\n          :term:`context` must provide in order for this view to be\n          found and called.  This predicate is true when the\n          :term:`context` is an instance of the represented class or\n          if the :term:`context` provides the represented interface;\n          it is otherwise false.  This argument may also be provided\n          to ``add_view`` as ``for_`` (an older, still-supported\n          spelling).\n\n        route_name\n\n          This value must match the ``name`` of a :term:`route\n          configuration` declaration (see :ref:`urldispatch_chapter`)\n          that must match before this view will be called.\n\n        request_type\n\n          This value should be an :term:`interface` that the\n          :term:`request` must provide in order for this view to be\n          found and called.  This value exists only for backwards\n          compatibility purposes.\n\n        request_method\n\n          This value can be one of the strings ``GET``, ``POST``, ``PUT``,\n          ``DELETE``, or ``HEAD`` representing an HTTP ``REQUEST_METHOD``, or\n          a tuple containing one or more of these strings.  A view\n          declaration with this argument ensures that the view will only be\n          called when the request's ``method`` attribute (aka the\n          ``REQUEST_METHOD`` of the WSGI environment) string matches a\n          supplied value.  Note that use of ``GET`` also implies that the\n          view will respond to ``HEAD`` as of Pyramid 1.4.\n\n          .. versionchanged:: 1.2\n             The ability to pass a tuple of items as ``request_method``.\n             Previous versions allowed only a string.\n\n        request_param\n\n          This value can be any string or any sequence of strings.  A view \n          declaration with this argument ensures that the view will only be \n          called when the :term:`request` has a key in the ``request.params``\n          dictionary (an HTTP ``GET`` or ``POST`` variable) that has a\n          name which matches the supplied value (if the value is a string)\n          or values (if the value is a tuple).  If any value\n          supplied has a ``=`` sign in it,\n          e.g. ``request_param=\"foo=123\"``, then the key (``foo``)\n          must both exist in the ``request.params`` dictionary, *and*\n          the value must match the right hand side of the expression\n          (``123``) for the view to \"match\" the current request.\n\n        match_param\n\n          .. versionadded:: 1.2\n\n          This value can be a string of the format \"key=value\" or a tuple\n          containing one or more of these strings.\n\n          A view declaration with this argument ensures that the view will\n          only be called when the :term:`request` has key/value pairs in its\n          :term:`matchdict` that equal those supplied in the predicate.\n          e.g. ``match_param=\"action=edit\" would require the ``action``\n          parameter in the :term:`matchdict` match the right hand side of\n          the expression (``edit``) for the view to \"match\" the current\n          request.\n\n          If the ``match_param`` is a tuple, every key/value pair must match\n          for the predicate to pass.\n\n        containment\n\n          This value should be a Python class or :term:`interface` (or a\n          :term:`dotted Python name`) that an object in the\n          :term:`lineage` of the context must provide in order for this view\n          to be found and called.  The nodes in your object graph must be\n          \"location-aware\" to use this feature.  See\n          :ref:`location_aware` for more information about\n          location-awareness.\n\n        xhr\n\n          This value should be either ``True`` or ``False``.  If this\n          value is specified and is ``True``, the :term:`request`\n          must possess an ``HTTP_X_REQUESTED_WITH`` (aka\n          ``X-Requested-With``) header that has the value\n          ``XMLHttpRequest`` for this view to be found and called.\n          This is useful for detecting AJAX requests issued from\n          jQuery, Prototype and other Javascript libraries.\n\n        accept\n\n          The value of this argument represents a match query for one\n          or more mimetypes in the ``Accept`` HTTP request header.  If\n          this value is specified, it must be in one of the following\n          forms: a mimetype match token in the form ``text/plain``, a\n          wildcard mimetype match token in the form ``text/*`` or a\n          match-all wildcard mimetype match token in the form ``*/*``.\n          If any of the forms matches the ``Accept`` header of the\n          request, this predicate will be true.\n\n        header\n\n          This value represents an HTTP header name or a header\n          name/value pair.  If the value contains a ``:`` (colon), it\n          will be considered a name/value pair\n          (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``).  The\n          value portion should be a regular expression.  If the value\n          does not contain a colon, the entire value will be\n          considered to be the header name\n          (e.g. ``If-Modified-Since``).  If the value evaluates to a\n          header name only without a value, the header specified by\n          the name must be present in the request for this predicate\n          to be true.  If the value evaluates to a header name/value\n          pair, the header specified by the name must be present in\n          the request *and* the regular expression specified as the\n          value must match the header value.  Whether or not the value\n          represents a header name or a header name/value pair, the\n          case of the header name is not significant.\n\n        path_info\n\n          This value represents a regular expression pattern that will\n          be tested against the ``PATH_INFO`` WSGI environment\n          variable.  If the regex matches, this predicate will be\n          ``True``.\n\n        check_csrf\n\n          If specified, this value should be one of ``None``, ``True``,\n          ``False``, or a string representing the 'check name'.  If the value\n          is ``True`` or a string, CSRF checking will be performed.  If the\n          value is ``False`` or ``None``, CSRF checking will not be performed.\n\n          If the value provided is a string, that string will be used as the\n          'check name'.  If the value provided is ``True``, ``csrf_token`` will\n          be used as the check name.\n\n          If CSRF checking is performed, the checked value will be the value\n          of ``request.params[check_name]``.  This value will be compared\n          against the value of ``request.session.get_csrf_token()``, and the\n          check will pass if these two values are the same.  If the check\n          passes, the associated view will be permitted to execute.  If the\n          check fails, the associated view will not be permitted to execute.\n\n          Note that using this feature requires a :term:`session factory` to\n          have been configured.\n         \n          .. versionadded:: 1.4a2\n\n        physical_path\n\n          If specified, this value should be a string or a tuple representing\n          the :term:`physical path` of the context found via traversal for this\n          predicate to match as true.  For example: ``physical_path='/'`` or\n          ``physical_path='/a/b/c'`` or ``physical_path=('', 'a', 'b', 'c')``.\n          This is not a path prefix match or a regex, it's a whole-path match.\n          It's useful when you want to always potentially show a view when some\n          object is traversed to, but you can't be sure about what kind of\n          object it will be, so you can't use the ``context`` predicate.  The\n          individual path elements inbetween slash characters or in tuple\n          elements should be the Unicode representation of the name of the\n          resource and should not be encoded in any way.\n\n          .. versionadded:: 1.4a3\n\n        effective_principals\n\n          If specified, this value should be a :term:`principal` identifier or\n          a sequence of principal identifiers.  If the\n          :func:`pyramid.security.effective_principals` method indicates that\n          every principal named in the argument list is present in the current\n          request, this predicate will return True; otherwise it will return\n          False.  For example:\n          ``effective_principals=pyramid.security.Authenticated`` or\n          ``effective_principals=('fred', 'group:admins')``.\n\n          .. versionadded:: 1.4a4\n\n        custom_predicates\n\n          .. deprecated:: 1.5\n\n          This value should be a sequence of references to custom predicate\n          callables.  Use custom predicates when no set of predefined\n          predicates do what you need.  Custom predicates can be combined with\n          predefined predicates as necessary.  Each custom predicate callable\n          should accept two arguments: ``context`` and ``request`` and should\n          return either ``True`` or ``False`` after doing arbitrary evaluation\n          of the context and/or the request.  The ``predicates`` argument to\n          this method and the ability to register third-party view predicates\n          via :meth:`pyramid.config.Configurator.add_view_predicate` obsoletes\n          this argument, but it is kept around for backwards compatibility.\n\n        predicates\n\n          Pass a key/value pair here to use a third-party predicate\n          registered via\n          :meth:`pyramid.config.Configurator.add_view_predicate`.  More than\n          one key/value pair can be used at the same time.  See\n          :ref:`view_and_route_predicates` for more information about\n          third-party predicates.\n\n          .. versionadded: 1.4a1\n\n        \"\"\"\n        if custom_predicates:\n            warnings.warn(\n                ('The \"custom_predicates\" argument to Configurator.add_view '\n                 'is deprecated as of Pyramid 1.5.  Use '\n                 '\"config.add_view_predicate\" and use the registered '\n                 'view predicate as a predicate argument to add_view instead. '\n                 'See \"Adding A Third Party View, Route, or Subscriber '\n                 'Predicate\" in the \"Hooks\" chapter of the documentation '\n                 'for more information.'),\n                DeprecationWarning,\n                stacklevel=4\n                )\n        \n        view = self.maybe_dotted(view)\n        context = self.maybe_dotted(context)\n        for_ = self.maybe_dotted(for_)\n        containment = self.maybe_dotted(containment)\n        mapper = self.maybe_dotted(mapper)\n\n        def combine(*decorators):\n            def decorated(view_callable):\n                # reversed() is allows a more natural ordering in the api\n                for decorator in reversed(decorators):\n                    view_callable = decorator(view_callable)\n                return view_callable\n            return decorated\n\n        if is_nonstr_iter(decorator):\n            decorator = combine(*map(self.maybe_dotted, decorator))\n        else:\n            decorator = self.maybe_dotted(decorator)\n\n        if not view:\n            if renderer:\n                def view(context, request):\n                    return {}\n            else:\n                raise ConfigurationError('\"view\" was not specified and '\n                                         'no \"renderer\" specified')\n\n        if request_type is not None:\n            request_type = self.maybe_dotted(request_type)\n            if not IInterface.providedBy(request_type):\n                raise ConfigurationError(\n                    'request_type must be an interface, not %s' % request_type)\n\n        if context is None:\n            context = for_\n\n        r_context = context\n        if r_context is None:\n            r_context = Interface\n        if not IInterface.providedBy(r_context):\n            r_context = implementedBy(r_context)\n\n        if isinstance(renderer, string_types):\n            renderer = renderers.RendererHelper(\n                name=renderer, package=self.package,\n                registry = self.registry)\n\n        if accept is not None:\n            accept = accept.lower()\n\n        introspectables = []\n        pvals = predicates.copy()\n        pvals.update(\n            dict(\n                xhr=xhr,\n                request_method=request_method,\n                path_info=path_info,\n                request_param=request_param,\n                header=header,\n                accept=accept,\n                containment=containment,\n                request_type=request_type,\n                match_param=match_param,\n                check_csrf=check_csrf,\n                custom=predvalseq(custom_predicates),\n                )\n            )\n\n        def discrim_func():\n            # We need to defer the discriminator until we know what the phash\n            # is.  It can't be computed any sooner because thirdparty\n            # predicates may not yet exist when add_view is called.\n            order, preds, phash = predlist.make(self, **pvals)\n            view_intr.update({'phash':phash, 'order':order, 'predicates':preds})\n            return ('view', context, name, route_name, phash)\n\n        discriminator = Deferred(discrim_func)\n\n        if inspect.isclass(view) and attr:\n            view_desc = 'method %r of %s' % (\n                attr, self.object_description(view))\n        else:\n            view_desc = self.object_description(view)\n\n        tmpl_intr = None\n            \n        view_intr = self.introspectable('views',\n                                        discriminator,\n                                        view_desc,\n                                        'view')\n        view_intr.update(\n            dict(name=name,\n                 context=context,\n                 containment=containment,\n                 request_param=request_param,\n                 request_methods=request_method,\n                 route_name=route_name,\n                 attr=attr,\n                 xhr=xhr,\n                 accept=accept,\n                 header=header,\n                 path_info=path_info,\n                 match_param=match_param,\n                 check_csrf=check_csrf,\n                 callable=view,\n                 mapper=mapper,\n                 decorator=decorator,\n                 )\n            )\n        view_intr.update(**predicates)\n        introspectables.append(view_intr)\n        predlist = self.get_predlist('view')\n\n        def register(permission=permission, renderer=renderer):\n            # the discrim_func above is guaranteed to have been called already\n            order = view_intr['order']\n            preds = view_intr['predicates']\n            phash = view_intr['phash']\n            request_iface = IRequest\n            if route_name is not None:\n                request_iface = self.registry.queryUtility(IRouteRequest,\n                                                           name=route_name)\n                if request_iface is None:\n                    # route configuration should have already happened in\n                    # phase 2\n                    raise ConfigurationError(\n                        'No route named %s found for view registration' %\n                        route_name)\n\n            if renderer is None:\n                # use default renderer if one exists (reg'd in phase 1)\n                if self.registry.queryUtility(IRendererFactory) is not None:\n                    renderer = renderers.RendererHelper(\n                        name=None,\n                        package=self.package,\n                        registry=self.registry\n                        )\n\n            if permission is None:\n                # intent: will be None if no default permission is registered\n                # (reg'd in phase 1)\n                permission = self.registry.queryUtility(IDefaultPermission)\n\n            # added by discrim_func above during conflict resolving\n            preds = view_intr['predicates']\n            order = view_intr['order']\n            phash = view_intr['phash']\n\n            # __no_permission_required__ handled by _secure_view\n            deriver = ViewDeriver(\n                registry=self.registry,\n                permission=permission,\n                predicates=preds,\n                attr=attr,\n                renderer=renderer,\n                wrapper_viewname=wrapper,\n                viewname=name,\n                accept=accept,\n                order=order,\n                phash=phash,\n                package=self.package,\n                mapper=mapper,\n                decorator=decorator,\n                http_cache=http_cache,\n                )\n            derived_view = deriver(view)\n            derived_view.__discriminator__ = lambda *arg: discriminator\n            # __discriminator__ is used by superdynamic systems\n            # that require it for introspection after manual view lookup;\n            # see also MultiView.__discriminator__\n            view_intr['derived_callable'] = derived_view\n\n            registered = self.registry.adapters.registered\n\n            # A multiviews is a set of views which are registered for\n            # exactly the same context type/request type/name triad.  Each\n            # consituent view in a multiview differs only by the\n            # predicates which it possesses.\n\n            # To find a previously registered view for a context\n            # type/request type/name triad, we need to use the\n            # ``registered`` method of the adapter registry rather than\n            # ``lookup``.  ``registered`` ignores interface inheritance\n            # for the required and provided arguments, returning only a\n            # view registered previously with the *exact* triad we pass\n            # in.\n\n            # We need to do this three times, because we use three\n            # different interfaces as the ``provided`` interface while\n            # doing registrations, and ``registered`` performs exact\n            # matches on all the arguments it receives.\n\n            old_view = None\n\n            for view_type in (IView, ISecuredView, IMultiView):\n                old_view = registered((IViewClassifier, request_iface,\n                                       r_context), view_type, name)\n                if old_view is not None:\n                    break\n\n            isexc = isexception(context)\n\n            def regclosure():\n                if hasattr(derived_view, '__call_permissive__'):\n                    view_iface = ISecuredView\n                else:\n                    view_iface = IView\n                self.registry.registerAdapter(\n                    derived_view,\n                    (IViewClassifier, request_iface, context), view_iface, name\n                    )\n                if isexc:\n                    self.registry.registerAdapter(\n                        derived_view,\n                        (IExceptionViewClassifier, request_iface, context),\n                        view_iface, name)\n\n            is_multiview = IMultiView.providedBy(old_view)\n            old_phash = getattr(old_view, '__phash__', DEFAULT_PHASH)\n\n            if old_view is None:\n                # - No component was yet registered for any of our I*View\n                #   interfaces exactly; this is the first view for this\n                #   triad.\n                regclosure()\n\n            elif (not is_multiview) and (old_phash == phash):\n                # - A single view component was previously registered with\n                #   the same predicate hash as this view; this registration\n                #   is therefore an override.\n                regclosure()\n\n            else:\n                # - A view or multiview was already registered for this\n                #   triad, and the new view is not an override.\n\n                # XXX we could try to be more efficient here and register\n                # a non-secured view for a multiview if none of the\n                # multiview's consituent views have a permission\n                # associated with them, but this code is getting pretty\n                # rough already\n                if is_multiview:\n                    multiview = old_view\n                else:\n                    multiview = MultiView(name)\n                    old_accept = getattr(old_view, '__accept__', None)\n                    old_order = getattr(old_view, '__order__', MAX_ORDER)\n                    multiview.add(old_view, old_order, old_accept, old_phash)\n                multiview.add(derived_view, order, accept, phash)\n                for view_type in (IView, ISecuredView):\n                    # unregister any existing views\n                    self.registry.adapters.unregister(\n                        (IViewClassifier, request_iface, r_context),\n                        view_type, name=name)\n                    if isexc:\n                        self.registry.adapters.unregister(\n                            (IExceptionViewClassifier, request_iface,\n                             r_context), view_type, name=name)\n                self.registry.registerAdapter(\n                    multiview,\n                    (IViewClassifier, request_iface, context),\n                    IMultiView, name=name)\n                if isexc:\n                    self.registry.registerAdapter(\n                        multiview,\n                        (IExceptionViewClassifier, request_iface, context),\n                        IMultiView, name=name)\n            renderer_type = getattr(renderer, 'type', None) # gard against None\n            intrspc = self.introspector\n            if (\n                renderer_type is not None and\n                tmpl_intr is not None and\n                intrspc is not None and\n                intrspc.get('renderer factories', renderer_type) is not None\n                ):\n                # allow failure of registered template factories to be deferred\n                # until view execution, like other bad renderer factories; if\n                # we tried to relate this to an existing renderer factory\n                # without checking if it the factory actually existed, we'd end\n                # up with a KeyError at startup time, which is inconsistent\n                # with how other bad renderer registrations behave (they throw\n                # a ValueError at view execution time)\n                tmpl_intr.relate('renderer factories', renderer.type)\n\n        if mapper:\n            mapper_intr = self.introspectable(\n                'view mappers',\n                discriminator,\n                'view mapper for %s' % view_desc,\n                'view mapper'\n                )\n            mapper_intr['mapper'] = mapper\n            mapper_intr.relate('views', discriminator)\n            introspectables.append(mapper_intr)\n        if route_name:\n            view_intr.relate('routes', route_name) # see add_route\n        if renderer is not None and renderer.name and '.' in renderer.name:\n            # the renderer is a template\n            tmpl_intr = self.introspectable(\n                'templates',\n                discriminator,\n                renderer.name,\n                'template'\n                )\n            tmpl_intr.relate('views', discriminator)\n            tmpl_intr['name'] = renderer.name\n            tmpl_intr['type'] = renderer.type\n            tmpl_intr['renderer'] = renderer\n            introspectables.append(tmpl_intr)\n        if permission is not None:\n            # if a permission exists, register a permission introspectable\n            perm_intr = self.introspectable(\n                'permissions',\n                permission,\n                permission,\n                'permission'\n                )\n            perm_intr['value'] = permission\n            perm_intr.relate('views', discriminator)\n            introspectables.append(perm_intr)\n        self.action(discriminator, register, introspectables=introspectables)\n\n    @action_method\n    def add_view_predicate(self, name, factory, weighs_more_than=None,\n                           weighs_less_than=None):\n        \"\"\"\n        .. versionadded:: 1.4\n\n        Adds a view predicate factory.  The associated view predicate can\n        later be named as a keyword argument to\n        :meth:`pyramid.config.Configurator.add_view` in the\n        ``predicates`` anonyous keyword argument dictionary.\n\n        ``name`` should be the name of the predicate.  It must be a valid\n        Python identifier (it will be used as a keyword argument to\n        ``add_view`` by others).\n\n        ``factory`` should be a :term:`predicate factory` or :term:`dotted\n        Python name` which refers to a predicate factory.\n\n        See :ref:`view_and_route_predicates` for more information.\n        \"\"\"\n        self._add_predicate(\n            'view',\n            name,\n            factory,\n            weighs_more_than=weighs_more_than,\n            weighs_less_than=weighs_less_than\n            )\n\n    def add_default_view_predicates(self):\n        p = pyramid.config.predicates\n        for (name, factory) in (\n            ('xhr', p.XHRPredicate),\n            ('request_method', p.RequestMethodPredicate),\n            ('path_info', p.PathInfoPredicate),\n            ('request_param', p.RequestParamPredicate),\n            ('header', p.HeaderPredicate),\n            ('accept', p.AcceptPredicate),\n            ('containment', p.ContainmentPredicate),\n            ('request_type', p.RequestTypePredicate),\n            ('match_param', p.MatchParamPredicate),\n            ('check_csrf', p.CheckCSRFTokenPredicate),\n            ('physical_path', p.PhysicalPathPredicate),\n            ('effective_principals', p.EffectivePrincipalsPredicate),\n            ('custom', p.CustomPredicate),\n            ):\n            self.add_view_predicate(name, factory)\n\n    def derive_view(self, view, attr=None, renderer=None):\n        \"\"\"\n        Create a :term:`view callable` using the function, instance,\n        or class (or :term:`dotted Python name` referring to the same)\n        provided as ``view`` object.\n\n        .. warning::\n\n           This method is typically only used by :app:`Pyramid` framework\n           extension authors, not by :app:`Pyramid` application developers.\n\n        This is API is useful to framework extenders who create\n        pluggable systems which need to register 'proxy' view\n        callables for functions, instances, or classes which meet the\n        requirements of being a :app:`Pyramid` view callable.  For\n        example, a ``some_other_framework`` function in another\n        framework may want to allow a user to supply a view callable,\n        but he may want to wrap the view callable in his own before\n        registering the wrapper as a :app:`Pyramid` view callable.\n        Because a :app:`Pyramid` view callable can be any of a\n        number of valid objects, the framework extender will not know\n        how to call the user-supplied object.  Running it through\n        ``derive_view`` normalizes it to a callable which accepts two\n        arguments: ``context`` and ``request``.\n\n        For example:\n\n        .. code-block:: python\n\n           def some_other_framework(user_supplied_view):\n               config = Configurator(reg)\n               proxy_view = config.derive_view(user_supplied_view)\n               def my_wrapper(context, request):\n                   do_something_that_mutates(request)\n                   return proxy_view(context, request)\n               config.add_view(my_wrapper)\n\n        The ``view`` object provided should be one of the following:\n\n        - A function or another non-class callable object that accepts\n          a :term:`request` as a single positional argument and which\n          returns a :term:`response` object.\n\n        - A function or other non-class callable object that accepts\n          two positional arguments, ``context, request`` and which\n          returns a :term:`response` object.\n\n        - A class which accepts a single positional argument in its\n          constructor named ``request``, and which has a ``__call__``\n          method that accepts no arguments that returns a\n          :term:`response` object.\n\n        - A class which accepts two positional arguments named\n          ``context, request``, and which has a ``__call__`` method\n          that accepts no arguments that returns a :term:`response`\n          object.\n\n        - A :term:`dotted Python name` which refers to any of the\n          kinds of objects above.\n\n        This API returns a callable which accepts the arguments\n        ``context, request`` and which returns the result of calling\n        the provided ``view`` object.\n\n        The ``attr`` keyword argument is most useful when the view\n        object is a class.  It names the method that should be used as\n        the callable.  If ``attr`` is not provided, the attribute\n        effectively defaults to ``__call__``.  See\n        :ref:`class_as_view` for more information.\n\n        The ``renderer`` keyword argument should be a renderer\n        name. If supplied, it will cause the returned callable to use\n        a :term:`renderer` to convert the user-supplied view result to\n        a :term:`response` object.  If a ``renderer`` argument is not\n        supplied, the user-supplied view must itself return a\n        :term:`response` object.  \"\"\"\n        return self._derive_view(view, attr=attr, renderer=renderer)\n\n    # b/w compat\n    def _derive_view(self, view, permission=None, predicates=(),\n                     attr=None, renderer=None, wrapper_viewname=None,\n                     viewname=None, accept=None, order=MAX_ORDER,\n                     phash=DEFAULT_PHASH, decorator=None,\n                     mapper=None, http_cache=None):\n        view = self.maybe_dotted(view)\n        mapper = self.maybe_dotted(mapper)\n        if isinstance(renderer, string_types):\n            renderer = renderers.RendererHelper(\n                name=renderer, package=self.package,\n                registry = self.registry)\n        if renderer is None:\n            # use default renderer if one exists\n            if self.registry.queryUtility(IRendererFactory) is not None:\n                renderer = renderers.RendererHelper(\n                    name=None,\n                    package=self.package,\n                    registry=self.registry)\n\n        deriver = ViewDeriver(registry=self.registry,\n                              permission=permission,\n                              predicates=predicates,\n                              attr=attr,\n                              renderer=renderer,\n                              wrapper_viewname=wrapper_viewname,\n                              viewname=viewname,\n                              accept=accept,\n                              order=order,\n                              phash=phash,\n                              package=self.package,\n                              mapper=mapper,\n                              decorator=decorator,\n                              http_cache=http_cache)\n\n        return deriver(view)\n\n    @action_method\n    def add_forbidden_view(\n        self,\n        view=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        route_name=None,\n        request_type=None,\n        request_method=None, \n        request_param=None,\n        containment=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        decorator=None,\n        mapper=None,\n        match_param=None,\n        **predicates\n        ):\n        \"\"\" Add a forbidden view to the current configuration state.  The\n        view will be called when Pyramid or application code raises a\n        :exc:`pyramid.httpexceptions.HTTPForbidden` exception and the set of\n        circumstances implied by the predicates provided are matched.  The\n        simplest example is:\n\n          .. code-block:: python\n\n            def forbidden(request):\n                return Response('Forbidden', status='403 Forbidden')\n\n            config.add_forbidden_view(forbidden)\n\n        All arguments have the same meaning as\n        :meth:`pyramid.config.Configurator.add_view` and each predicate\n        argument restricts the set of circumstances under which this notfound\n        view will be invoked.  Unlike\n        :meth:`pyramid.config.Configurator.add_view`, this method will raise\n        an exception if passed ``name``, ``permission``, ``context``,\n        ``for_``, or ``http_cache`` keyword arguments.  These argument values\n        make no sense in the context of a forbidden view.\n\n        .. versionadded:: 1.3\n        \"\"\"\n        for arg in ('name', 'permission', 'context', 'for_', 'http_cache'):\n            if arg in predicates:\n                raise ConfigurationError(\n                    '%s may not be used as an argument to add_forbidden_view'\n                    % arg\n                    )\n        \n        settings = dict(\n            view=view,\n            context=HTTPForbidden,\n            wrapper=wrapper,\n            request_type=request_type,\n            request_method=request_method,\n            request_param=request_param,\n            containment=containment,\n            xhr=xhr,\n            accept=accept,\n            header=header, \n            path_info=path_info,\n            custom_predicates=custom_predicates,\n            decorator=decorator,\n            mapper=mapper,\n            match_param=match_param,\n            route_name=route_name,\n            permission=NO_PERMISSION_REQUIRED,\n            attr=attr,\n            renderer=renderer,\n            )\n        settings.update(predicates)\n        return self.add_view(**settings)\n\n    set_forbidden_view = add_forbidden_view # deprecated sorta-bw-compat alias\n    \n    @action_method\n    def add_notfound_view(\n        self,\n        view=None,\n        attr=None,\n        renderer=None,\n        wrapper=None,\n        route_name=None,\n        request_type=None,\n        request_method=None, \n        request_param=None,\n        containment=None,\n        xhr=None,\n        accept=None,\n        header=None,\n        path_info=None,\n        custom_predicates=(),\n        decorator=None,\n        mapper=None,\n        match_param=None,\n        append_slash=False,\n        **predicates\n        ):\n        \"\"\" Add a default Not Found View to the current configuration state.\n        The view will be called when Pyramid or application code raises an\n        :exc:`pyramid.httpexceptions.HTTPNotFound` exception (e.g. when a\n        view cannot be found for the request).  The simplest example is:\n\n          .. code-block:: python\n\n            def notfound(request):\n                return Response('Not Found', status='404 Not Found')\n\n            config.add_notfound_view(notfound)\n\n        All arguments except ``append_slash`` have the same meaning as\n        :meth:`pyramid.config.Configurator.add_view` and each predicate\n        argument restricts the set of circumstances under which this notfound\n        view will be invoked.  Unlike\n        :meth:`pyramid.config.Configurator.add_view`, this method will raise\n        an exception if passed ``name``, ``permission``, ``context``,\n        ``for_``, or ``http_cache`` keyword arguments.  These argument values\n        make no sense in the context of a Not Found View.\n\n        If ``append_slash`` is ``True``, when this Not Found View is invoked,\n        and the current path info does not end in a slash, the notfound logic\n        will attempt to find a :term:`route` that matches the request's path\n        info suffixed with a slash.  If such a route exists, Pyramid will\n        issue a redirect to the URL implied by the route; if it does not,\n        Pyramid will return the result of the view callable provided as\n        ``view``, as normal.\n\n        .. versionadded:: 1.3\n        \"\"\"\n        for arg in ('name', 'permission', 'context', 'for_', 'http_cache'):\n            if arg in predicates:\n                raise ConfigurationError(\n                    '%s may not be used as an argument to add_notfound_view'\n                    % arg\n                    )\n                    \n        settings = dict(\n            view=view,\n            context=HTTPNotFound,\n            wrapper=wrapper,\n            request_type=request_type,\n            request_method=request_method,\n            request_param=request_param,\n            containment=containment,\n            xhr=xhr,\n            accept=accept,\n            header=header, \n            path_info=path_info,\n            custom_predicates=custom_predicates,\n            decorator=decorator,\n            mapper=mapper,\n            match_param=match_param,\n            route_name=route_name,\n            permission=NO_PERMISSION_REQUIRED,\n            )\n        settings.update(predicates)\n        if append_slash:\n            view = self._derive_view(view, attr=attr, renderer=renderer)\n            view = AppendSlashNotFoundViewFactory(view)\n            settings['view'] = view\n        else:\n            settings['attr'] = attr\n            settings['renderer'] = renderer\n        return self.add_view(**settings)\n\n    set_notfound_view = add_notfound_view # deprecated sorta-bw-compat alias\n\n    @action_method\n    def set_view_mapper(self, mapper):\n        \"\"\"\n        Setting a :term:`view mapper` makes it possible to make use of\n        :term:`view callable` objects which implement different call\n        signatures than the ones supported by :app:`Pyramid` as described in\n        its narrative documentation.\n\n        The ``mapper`` should argument be an object implementing\n        :class:`pyramid.interfaces.IViewMapperFactory` or a :term:`dotted\n        Python name` to such an object.  The provided ``mapper`` will become\n        the default view mapper to be used by all subsequent :term:`view\n        configuration` registrations.\n\n        See also :ref:`using_a_view_mapper`.\n\n        .. note::\n\n           Using the ``default_view_mapper`` argument to the\n           :class:`pyramid.config.Configurator` constructor\n           can be used to achieve the same purpose.\n        \"\"\"\n        mapper = self.maybe_dotted(mapper)\n        def register():\n            self.registry.registerUtility(mapper, IViewMapperFactory)\n        # IViewMapperFactory is looked up as the result of view config\n        # in phase 3\n        intr = self.introspectable('view mappers',\n                                   IViewMapperFactory,\n                                   self.object_description(mapper),\n                                   'default view mapper')\n        intr['mapper'] = mapper\n        self.action(IViewMapperFactory, register, order=PHASE1_CONFIG,\n                    introspectables=(intr,))\n\n    @action_method\n    def add_static_view(self, name, path, **kw):\n        \"\"\" Add a view used to render static assets such as images\n        and CSS files.\n\n        The ``name`` argument is a string representing an\n        application-relative local URL prefix.  It may alternately be a full\n        URL.\n\n        The ``path`` argument is the path on disk where the static files\n        reside.  This can be an absolute path, a package-relative path, or a\n        :term:`asset specification`.\n\n        The ``cache_max_age`` keyword argument is input to set the\n        ``Expires`` and ``Cache-Control`` headers for static assets served.\n        Note that this argument has no effect when the ``name`` is a *url\n        prefix*.  By default, this argument is ``None``, meaning that no\n        particular Expires or Cache-Control headers are set in the response.\n\n        The ``permission`` keyword argument is used to specify the\n        :term:`permission` required by a user to execute the static view.  By\n        default, it is the string\n        :data:`pyramid.security.NO_PERMISSION_REQUIRED`, a special sentinel\n        which indicates that, even if a :term:`default permission` exists for\n        the current application, the static view should be renderered to\n        completely anonymous users.  This default value is permissive\n        because, in most web apps, static assets seldom need protection from\n        viewing.  If ``permission`` is specified, the security checking will\n        be performed against the default root factory ACL.\n\n        Any other keyword arguments sent to ``add_static_view`` are passed on\n        to :meth:`pyramid.config.Configurator.add_route` (e.g. ``factory``,\n        perhaps to define a custom factory with a custom ACL for this static\n        view).\n\n        *Usage*\n\n        The ``add_static_view`` function is typically used in conjunction\n        with the :meth:`pyramid.request.Request.static_url` method.\n        ``add_static_view`` adds a view which renders a static asset when\n        some URL is visited; :meth:`pyramid.request.Request.static_url`\n        generates a URL to that asset.\n\n        The ``name`` argument to ``add_static_view`` is usually a simple URL\n        prefix (e.g. ``'images'``).  When this is the case, the\n        :meth:`pyramid.request.Request.static_url` API will generate a URL\n        which points to a Pyramid view, which will serve up a set of assets\n        that live in the package itself. For example:\n\n        .. code-block:: python\n\n           add_static_view('images', 'mypackage:images/')\n\n        Code that registers such a view can generate URLs to the view via\n        :meth:`pyramid.request.Request.static_url`:\n\n        .. code-block:: python\n\n           request.static_url('mypackage:images/logo.png')\n\n        When ``add_static_view`` is called with a ``name`` argument that\n        represents a URL prefix, as it is above, subsequent calls to\n        :meth:`pyramid.request.Request.static_url` with paths that start with\n        the ``path`` argument passed to ``add_static_view`` will generate a\n        URL something like ``http://<Pyramid app URL>/images/logo.png``,\n        which will cause the ``logo.png`` file in the ``images`` subdirectory\n        of the ``mypackage`` package to be served.\n\n        ``add_static_view`` can alternately be used with a ``name`` argument\n        which is a *URL*, causing static assets to be served from an external\n        webserver.  This happens when the ``name`` argument is a fully\n        qualified URL (e.g. starts with ``http://`` or similar).  In this\n        mode, the ``name`` is used as the prefix of the full URL when\n        generating a URL using :meth:`pyramid.request.Request.static_url`.\n        Furthermore, if a protocol-relative URL (e.g. ``//example.com/images``)\n        is used as the ``name`` argument, the generated URL will use the\n        protocol of the request (http or https, respectively).\n\n        For example, if ``add_static_view`` is called like so:\n\n        .. code-block:: python\n\n           add_static_view('http://example.com/images', 'mypackage:images/')\n\n        Subsequently, the URLs generated by\n        :meth:`pyramid.request.Request.static_url` for that static view will\n        be prefixed with ``http://example.com/images`` (the external webserver\n        listening on ``example.com`` must be itself configured to respond\n        properly to such a request.):\n\n        .. code-block:: python\n\n           static_url('mypackage:images/logo.png', request)\n\n        See :ref:`static_assets_section` for more information.\n        \"\"\"\n        spec = self._make_spec(path)\n        info = self.registry.queryUtility(IStaticURLInfo)\n        if info is None:\n            info = StaticURLInfo()\n            self.registry.registerUtility(info, IStaticURLInfo)\n        info.add(self, name, spec, **kw)\n\ndef isexception(o):\n    if IInterface.providedBy(o):\n        if IException.isEqualOrExtendedBy(o):\n            return True\n    return (\n        isinstance(o, Exception) or\n        (inspect.isclass(o) and (issubclass(o, Exception)))\n        )\n\n\n@implementer(IStaticURLInfo)\nclass StaticURLInfo(object):\n\n    def _get_registrations(self, registry):\n        try:\n            reg = registry._static_url_registrations\n        except AttributeError:\n            reg = registry._static_url_registrations = []\n        return reg\n\n    def generate(self, path, request, **kw):\n        try:\n            registry = request.registry\n        except AttributeError: # bw compat (for tests)\n            registry = get_current_registry()\n        for (url, spec, route_name) in self._get_registrations(registry):\n            if path.startswith(spec):\n                subpath = path[len(spec):]\n                if WIN: # pragma: no cover\n                    subpath = subpath.replace('\\\\', '/') # windows\n                if url is None:\n                    kw['subpath'] = subpath\n                    return request.route_url(route_name, **kw)\n                else:\n                    parsed = url_parse(url)\n                    if not parsed.scheme:\n                        # parsed.scheme is readonly, so we have to parse again\n                        # to change the scheme, sigh.\n                        url = urlparse.urlunparse(url_parse(\n                            url, scheme=request.environ['wsgi.url_scheme']))\n                    subpath = url_quote(subpath)\n                    return urljoin(url, subpath)\n\n        raise ValueError('No static URL definition matching %s' % path)\n\n    def add(self, config, name, spec, **extra):\n        # This feature only allows for the serving of a directory and\n        # the files contained within, not of a single asset;\n        # appending a slash here if the spec doesn't have one is\n        # required for proper prefix matching done in ``generate``\n        # (``subpath = path[len(spec):]``).\n        if os.path.isabs(spec): # FBO windows\n            sep = os.sep\n        else:\n            sep = '/'\n        if not spec.endswith(sep):\n            spec = spec + sep\n\n        # we also make sure the name ends with a slash, purely as a\n        # convenience: a name that is a url is required to end in a\n        # slash, so that ``urljoin(name, subpath))`` will work above\n        # when the name is a URL, and it doesn't hurt things for it to\n        # have a name that ends in a slash if it's used as a route\n        # name instead of a URL.\n        if not name.endswith('/'):\n            # make sure it ends with a slash\n            name = name + '/'\n\n        if url_parse(name).netloc:\n            # it's a URL\n            # url, spec, route_name\n            url = name\n            route_name = None\n        else:\n            # it's a view name\n            url = None\n            cache_max_age = extra.pop('cache_max_age', None)\n            # create a view\n            view = static_view(spec, cache_max_age=cache_max_age,\n                               use_subpath=True)\n\n            # Mutate extra to allow factory, etc to be passed through here.\n            # Treat permission specially because we'd like to default to\n            # permissiveness (see docs of config.add_static_view).\n            permission = extra.pop('permission', None)\n            if permission is None:\n                permission = NO_PERMISSION_REQUIRED\n\n            context = extra.pop('context', None)\n            if context is None:\n                context = extra.pop('for_', None)\n\n            renderer = extra.pop('renderer', None)\n\n            # register a route using the computed view, permission, and\n            # pattern, plus any extras passed to us via add_static_view\n            pattern = \"%s*subpath\" % name # name already ends with slash\n            if config.route_prefix:\n                route_name = '__%s/%s' % (config.route_prefix, name)\n            else:\n                route_name = '__%s' % name\n            config.add_route(route_name, pattern, **extra)\n            config.add_view(\n                route_name=route_name,\n                view=view,\n                permission=permission,\n                context=context,\n                renderer=renderer,\n                )\n\n        def register():\n            registrations = self._get_registrations(config.registry)\n\n            names = [ t[0] for t in  registrations ]\n\n            if name in names:\n                idx = names.index(name)\n                registrations.pop(idx)\n\n            # url, spec, route_name\n            registrations.append((url, spec, route_name))\n\n        intr = config.introspectable('static views',\n                                     name,\n                                     'static view for %r' % name,\n                                     'static view')\n        intr['name'] = name\n        intr['spec'] = spec\n\n        config.action(None, callable=register, introspectables=(intr,))\n\n\n"}
A user will ask you to solve a task. You should first draft your thinking process (inner monologue). Then, generate the solution.

Your response format must follow the template below:
<think>
Your thoughts or/and draft, like working through an exercise on scratch paper. Be as casual and as long as you want until you are confident to generate a correct solution.
</think>
<solution>
Final solution presented to the user.
</solution>
system
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title:** Forbidden and NotFound Views Ignore `view_defaults`, Causing Predicate Mismatches

**Description:**
When configuring forbidden or notfound views using `config.add_forbidden_view` or `config.add_notfound_view`, the `view_defaults` are being ignored. This leads to predicates not functioning as expected, resulting in the views not behaving correctly based on the default configurations.

**Example Buggy Code:**
```python
from pyramid.config import Configurator
from pyramid.httpexceptions import HTTPForbidden, HTTPNotFound
from zope.interface import directlyProvides, implementedBy

class ForbiddenView:
    __view_defaults__ = {'containment': IDummy}

    def __init__(self, request):
        pass

    def __call__(self):
        return 'OK'

config = Configurator(autocommit=True)
config.add_forbidden_view(view=ForbiddenView, renderer='null_renderer')
wrapper = get_view_callable(config, ctx_iface=implementedBy(HTTPForbidden), request_iface=IRequest)

context = DummyContext()
directlyProvides(context, IDummy)
request = make_request(config)
result = wrapper(context, request)  # Expected to return 'OK'

context = DummyContext()
request = make_request(config)
wrapper(context, request)  # Expected to raise PredicateMismatch
```

**Expected Behavior:**
The `view_defaults` should be correctly applied when adding forbidden or notfound views. This ensures that predicates defined in `view_defaults` are respected, allowing the view to behave as intended based on these defaults.

**Actual Behavior:**
The `view_defaults` are ignored due to the way arguments are handled in `config.add_forbidden_view` and `config.add_notfound_view`. As a result, predicates do not function correctly, leading to unexpected behavior such as not raising `PredicateMismatch` when conditions defined in `view_defaults` are not met.

[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### pyramid/config/views.py
import inspect
import operator
import os
import warnings

from zope.interface import (
    Interface,
    implementedBy,
    implementer,
    provider,
    )

from zope.interface.interfaces import IInterface

from pyramid.interfaces import (
    IAuthenticationPolicy,
    IAuthorizationPolicy,
    IDebugLogger,
    IDefaultPermission,
    IException,
    IExceptionViewClassifier,
    IMultiView,
    IRendererFactory,
    IRequest,
    IResponse,
    IRouteRequest,
    ISecuredView,
    IStaticURLInfo,
    IView,
    IViewClassifier,
    IViewMapper,
    IViewMapperFactory,
    PHASE1_CONFIG,
    )

from pyramid import renderers

from pyramid.compat import (
    string_types,
    urlparse,
    url_quote,
    WIN,
    is_bound_method,
    is_nonstr_iter
    )

from pyramid.exceptions import (
    ConfigurationError,
    PredicateMismatch,
    )

from pyramid.httpexceptions import (
    HTTPForbidden,
    HTTPNotFound,
    )

from pyramid.registry import (
    predvalseq,
    Deferred,
    )

from pyramid.response import Response

from pyramid.security import NO_PERMISSION_REQUIRED
from pyramid.static import static_view
from pyramid.threadlocal import get_current_registry

from pyramid.view import (
    render_view_to_response,
    AppendSlashNotFoundViewFactory,
    )

from pyramid.util import (
    object_description,
    viewdefaults,
    action_method,
    )

import pyramid.config.predicates

from pyramid.config.util import (
    DEFAULT_PHASH,
    MAX_ORDER,
    takes_one_arg,
    )

urljoin = urlparse.urljoin
url_parse = urlparse.urlparse

def view_description(view):
    try:
        return view.__text__
    except AttributeError:
        # custom view mappers might not add __text__
        return object_description(view)

def wraps_view(wrapper):
    def inner(self, view):
        wrapper_view = wrapper(self, view)
        return preserve_view_attrs(view, wrapper_view)
    return inner

def preserve_view_attrs(view, wrapper):
    if view is None:
        return wrapper

    if wrapper is view:
        return view

    original_view = getattr(view, '__original_view__', None)

    if original_view is None:
        original_view = view

    wrapper.__wraps__ = view
    wrapper.__original_view__ = original_view
    wrapper.__module__ = view.__module__
    wrapper.__doc__ = view.__doc__

    try:
        wrapper.__name__ = view.__name__
    except AttributeError:
        wrapper.__name__ = repr(view)

    # attrs that may not exist on "view", but, if so, must be attached to
    # "wrapped view"
    for attr in ('__permitted__', '__call_permissive__', '__permission__',
                 '__predicated__', '__predicates__', '__accept__',
                 '__order__', '__text__'):
        try:
            setattr(wrapper, attr, getattr(view, attr))
        except AttributeError:
            pass

    return wrapper

class ViewDeriver(object):
    def __init__(self, **kw):
        self.kw = kw
        self.registry = kw['registry']
        self.authn_policy = self.registry.queryUtility(IAuthenticationPolicy)
        self.authz_policy = self.registry.queryUtility(IAuthorizationPolicy)
        self.logger = self.registry.queryUtility(IDebugLogger)

    def __call__(self, view):
        return self.attr_wrapped_view(
            self.predicated_view(
                self.authdebug_view(
                    self.secured_view(
                        self.owrapped_view(
                            self.http_cached_view(
                                self.decorated_view(
                                    self.rendered_view(
                                        self.mapped_view(
                                                view)))))))))

    @wraps_view
    def mapped_view(self, view):
        mapper = self.kw.get('mapper')
        if mapper is None:
            mapper = getattr(view, '__view_mapper__', None)
            if mapper is None:
                mapper = self.registry.queryUtility(IViewMapperFactory)
                if mapper is None:
                    mapper = DefaultViewMapper

        mapped_view = mapper(**self.kw)(view)
        return mapped_view

    @wraps_view
    def owrapped_view(self, view):
        wrapper_viewname = self.kw.get('wrapper_viewname')
        viewname = self.kw.get('viewname')
        if not wrapper_viewname:
            return view
        def _owrapped_view(context, request):
            response = view(context, request)
            request.wrapped_response = response
            request.wrapped_body = response.body
            request.wrapped_view = view
            wrapped_response = render_view_to_response(context, request,
                                                       wrapper_viewname)
            if wrapped_response is None:
                raise ValueError(
                    'No wrapper view named %r found when executing view '
                    'named %r' % (wrapper_viewname, viewname))
            return wrapped_response
        return _owrapped_view

    @wraps_view
    def http_cached_view(self, view):
        if self.registry.settings.get('prevent_http_cache', False):
            return view

        seconds = self.kw.get('http_cache')

        if seconds is None:
            return view

        options = {}

        if isinstance(seconds, (tuple, list)):
            try:
                seconds, options = seconds
            except ValueError:
                raise ConfigurationError(
                    'If http_cache parameter is a tuple or list, it must be '
                    'in the form (seconds, options); not %s' % (seconds,))

        def wrapper(context, request):
            response = view(context, request)
            prevent_caching = getattr(response.cache_control, 'prevent_auto',
                                      False)
            if not prevent_caching:
                response.cache_expires(seconds, **options)
            return response

        return wrapper

    @wraps_view
    def secured_view(self, view):
        permission = self.kw.get('permission')
        if permission == NO_PERMISSION_REQUIRED:
            # allow views registered within configurations that have a
            # default permission to explicitly override the default
            # permission, replacing it with no permission at all
            permission = None

        wrapped_view = view
        if self.authn_policy and self.authz_policy and (permission is not None):
            def _permitted(context, request):
                principals = self.authn_policy.effective_principals(request)
                return self.authz_policy.permits(context, principals,
                                                 permission)
            def _secured_view(context, request):
                result = _permitted(context, request)
                if result:
                    return view(context, request)
                view_name = getattr(view, '__name__', view)
                msg = getattr(
                    request, 'authdebug_message',
                    'Unauthorized: %s failed permission check' % view_name)
                raise HTTPForbidden(msg, result=result)
            _secured_view.__call_permissive__ = view
            _secured_view.__permitted__ = _permitted
            _secured_view.__permission__ = permission
            wrapped_view = _secured_view

        return wrapped_view

    @wraps_view
    def authdebug_view(self, view):
        wrapped_view = view
        settings = self.registry.settings
        permission = self.kw.get('permission')
        if settings and settings.get('debug_authorization', False):
            def _authdebug_view(context, request):
                view_name = getattr(request, 'view_name', None)

                if self.authn_policy and self.authz_policy:
                    if permission is NO_PERMISSION_REQUIRED:
                        msg = 'Allowed (NO_PERMISSION_REQUIRED)'
                    elif permission is None:
                        msg = 'Allowed (no permission registered)'
                    else:
                        principals = self.authn_policy.effective_principals(
                            request)
                        msg = str(self.authz_policy.permits(context, principals,
                                                            permission))
                else:
                    msg = 'Allowed (no authorization policy in use)'

                view_name = getattr(request, 'view_name', None)
                url = getattr(request, 'url', None)
                msg = ('debug_authorization of url %s (view name %r against '
                       'context %r): %s' % (url, view_name, context, msg))
                self.logger and self.logger.debug(msg)
                if request is not None:
                    request.authdebug_message = msg
                return view(context, request)

            wrapped_view = _authdebug_view

        return wrapped_view

    @wraps_view
    def predicated_view(self, view):
        preds = self.kw.get('predicates', ())
        if not preds:
            return view
        def predicate_wrapper(context, request):
            for predicate in preds:
                if not predicate(context, request):
                    view_name = getattr(view, '__name__', view)
                    raise PredicateMismatch(
                         'predicate mismatch for view %s (%s)' % (
                         view_name, predicate.text()))
            return view(context, request)        
        def checker(context, request):
            return all((predicate(context, request) for predicate in
                        preds))
        predicate_wrapper.__predicated__ = checker
        predicate_wrapper.__predicates__ = preds
        return predicate_wrapper

    @wraps_view
    def attr_wrapped_view(self, view):
        kw = self.kw
        accept, order, phash = (kw.get('accept', None),
                                kw.get('order', MAX_ORDER),
                                kw.get('phash', DEFAULT_PHASH))
        # this is a little silly but we don't want to decorate the original
        # function with attributes that indicate accept, order, and phash,
        # so we use a wrapper
        if (
            (accept is None) and
            (order == MAX_ORDER) and
            (phash == DEFAULT_PHASH)
            ):
            return view # defaults
        def attr_view(context, request):
            return view(context, request)
        attr_view.__accept__ = accept
        attr_view.__order__ = order
        attr_view.__phash__ = phash
        attr_view.__view_attr__ = self.kw.get('attr')
        attr_view.__permission__ = self.kw.get('permission')
        return attr_view

    @wraps_view
    def rendered_view(self, view):
        # one way or another this wrapper must produce a Response (unless
        # the renderer is a NullRendererHelper)
        renderer = self.kw.get('renderer')
        if renderer is None:
            # register a default renderer if you want super-dynamic
            # rendering.  registering a default renderer will also allow
            # override_renderer to work if a renderer is left unspecified for
            # a view registration.
            return self._response_resolved_view(view)
        if renderer is renderers.null_renderer:
            return view
        return self._rendered_view(view, renderer)

    def _rendered_view(self, view, view_renderer):
        def rendered_view(context, request):
            renderer = view_renderer
            result = view(context, request)
            if result.__class__ is Response: # potential common case
                response = result
            else:
                registry = self.registry
                # this must adapt, it can't do a simple interface check
                # (avoid trying to render webob responses)
                response = registry.queryAdapterOrSelf(result, IResponse)
                if response is None:
                    attrs = getattr(request, '__dict__', {})
                    if 'override_renderer' in attrs:
                        # renderer overridden by newrequest event or other
                        renderer_name = attrs.pop('override_renderer')
                        renderer = renderers.RendererHelper(
                            name=renderer_name,
                            package=self.kw.get('package'),
                            registry = registry)
                    if '__view__' in attrs:
                        view_inst = attrs.pop('__view__')
                    else:
                        view_inst = getattr(view, '__original_view__', view)
                    response = renderer.render_view(request, result, view_inst,
                                                    context)
            return response

        return rendered_view

    def _response_resolved_view(self, view):
        registry = self.registry
        def viewresult_to_response(context, request):
            result = view(context, request)
            if result.__class__ is Response: # common case
                response = result
            else:
                response = registry.queryAdapterOrSelf(result, IResponse)
                if response is None:
                    if result is None:
                        append = (' You may have forgotten to return a value '
                                  'from the view callable.')
                    elif isinstance(result, dict):
                        append = (' You may have forgotten to define a '
                                  'renderer in the view configuration.')
                    else:
                        append = ''

                    msg = ('Could not convert return value of the view '
                           'callable %s into a response object. '
                           'The value returned was %r.' + append)

                    raise ValueError(msg % (view_description(view), result))

            return response

        return viewresult_to_response

    @wraps_view
    def decorated_view(self, view):
        decorator = self.kw.get('decorator')
        if decorator is None:
            return view
        return decorator(view)

@implementer(IViewMapper)
@provider(IViewMapperFactory)
class DefaultViewMapper(object):
    def __init__(self, **kw):
        self.attr = kw.get('attr')

    def __call__(self, view):
        if inspect.isclass(view):
            view = self.map_class(view)
        else:
            view = self.map_nonclass(view)
        return view

    def map_class(self, view):
        ronly = requestonly(view, self.attr)
        if ronly:
            mapped_view = self.map_class_requestonly(view)
        else:
            mapped_view = self.map_class_native(view)
        mapped_view.__text__ = 'method %s of %s' % (
            self.attr or '__call__', object_description(view))
        return mapped_view

    def map_nonclass(self, view):
        # We do more work here than appears necessary to avoid wrapping the
        # view unless it actually requires wrapping (to avoid function call
        # overhead).
        mapped_view = view
        ronly = requestonly(view, self.attr)
        if ronly:
            mapped_view = self.map_nonclass_requestonly(view)
        elif self.attr:
            mapped_view = self.map_nonclass_attr(view)
        if inspect.isroutine(mapped_view):
            # This branch will be true if the view is a function or a method.
            # We potentially mutate an unwrapped object here if it's a
            # function.  We do this to avoid function call overhead of
            # injecting another wrapper.  However, we must wrap if the
            # function is a bound method because we can't set attributes on a
            # bound method.
            if is_bound_method(view):
                _mapped_view = mapped_view
                def mapped_view(context, request):
                    return _mapped_view(context, request)
            if self.attr is not None:
                mapped_view.__text__ = 'attr %s of %s' % (
                    self.attr, object_description(view))
            else:
                mapped_view.__text__ = object_description(view)
        return mapped_view

    def map_class_requestonly(self, view):
        # its a class that has an __init__ which only accepts request
        attr = self.attr
        def _class_requestonly_view(context, request):
            inst = view(request)
            request.__view__ = inst
            if attr is None:
                response = inst()
            else:
                response = getattr(inst, attr)()
            return response
        return _class_requestonly_view

    def map_class_native(self, view):
        # its a class that has an __init__ which accepts both context and
        # request
        attr = self.attr
        def _class_view(context, request):
            inst = view(context, request)
            request.__view__ = inst
            if attr is None:
                response = inst()
            else:
                response = getattr(inst, attr)()
            return response
        return _class_view

    def map_nonclass_requestonly(self, view):
        # its a function that has a __call__ which accepts only a single
        # request argument
        attr = self.attr
        def _requestonly_view(context, request):
            if attr is None:
                response = view(request)
            else:
                response = getattr(view, attr)(request)
            return response
        return _requestonly_view

    def map_nonclass_attr(self, view):
        # its a function that has a __call__ which accepts both context and
        # request, but still has an attr
        def _attr_view(context, request):
            response = getattr(view, self.attr)(context, request)
            return response
        return _attr_view

def requestonly(view, attr=None):
    return takes_one_arg(view, attr=attr, argname='request')

@implementer(IMultiView)
class MultiView(object):

    def __init__(self, name):
        self.name = name
        self.media_views = {}
        self.views = []
        self.accepts = []

    def __discriminator__(self, context, request):
        # used by introspection systems like so:
        # view = adapters.lookup(....)
        # view.__discriminator__(context, request) -> view's discriminator
        # so that superdynamic systems can feed the discriminator to
        # the introspection system to get info about it
        view = self.match(context, request)
        return view.__discriminator__(context, request)

    def add(self, view, order, accept=None, phash=None):
        if phash is not None:
            for i, (s, v, h) in enumerate(list(self.views)):
                if phash == h:
                    self.views[i] = (order, view, phash)
                    return

        if accept is None or '*' in accept:
            self.views.append((order, view, phash))
            self.views.sort(key=operator.itemgetter(0))
        else:
            subset = self.media_views.setdefault(accept, [])
            for i, (s, v, h) in enumerate(list(subset)):
                if phash == h:
                    subset[i] = (order, view, phash)
                    return
            else:
                subset.append((order, view, phash))
                subset.sort(key=operator.itemgetter(0))
            accepts = set(self.accepts)
            accepts.add(accept)
            self.accepts = list(accepts) # dedupe

    def get_views(self, request):
        if self.accepts and hasattr(request, 'accept'):
            accepts = self.accepts[:]
            views = []
            while accepts:
                match = request.accept.best_match(accepts)
                if match is None:
                    break
                subset = self.media_views[match]
                views.extend(subset)
                accepts.remove(match)
            views.extend(self.views)
            return views
        return self.views

    def match(self, context, request):
        for order, view, phash in self.get_views(request):
            if not hasattr(view, '__predicated__'):
                return view
            if view.__predicated__(context, request):
                return view
        raise PredicateMismatch(self.name)

    def __permitted__(self, context, request):
        view = self.match(context, request)
        if hasattr(view, '__permitted__'):
            return view.__permitted__(context, request)
        return True

    def __call_permissive__(self, context, request):
        view = self.match(context, request)
        view = getattr(view, '__call_permissive__', view)
        return view(context, request)

    def __call__(self, context, request):
        for order, view, phash in self.get_views(request):
            try:
                return view(context, request)
            except PredicateMismatch:
                continue
        raise PredicateMismatch(self.name)

class ViewsConfiguratorMixin(object):
    @viewdefaults
    @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,
        renderer=None,
        wrapper=None,
        xhr=None,
        accept=None,
        header=None,
        path_info=None,
        custom_predicates=(),
        context=None,
        decorator=None,
        mapper=None,
        http_cache=None,
        match_param=None,
        check_csrf=None,
        **predicates):
        """ Add a :term:`view configuration` to the current
        configuration state.  Arguments to ``add_view`` are broken
        down below into *predicate* arguments and *non-predicate*
        arguments.  Predicate arguments narrow the circumstances in
        which the view callable will be invoked when a request is
        presented to :app:`Pyramid`; non-predicate arguments are
        informational.

        Non-Predicate Arguments

        view

          A :term:`view callable` or a :term:`dotted Python name`
          which refers to a view callable.  This argument is required
          unless a ``renderer`` argument also exists.  If a
          ``renderer`` argument is passed, and a ``view`` argument is
          not provided, the view callable defaults to a callable that
          returns an empty dictionary (see
          :ref:`views_which_use_a_renderer`).

        permission

          A :term:`permission` that the user must possess in order to invoke
          the :term:`view callable`.  See :ref:`view_security_section` for
          more information about view security and permissions.  This is
          often a string like ``view`` or ``edit``.

          If ``permission`` is omitted, a *default* permission may be used
          for this view registration if one was named as the
          :class:`pyramid.config.Configurator` constructor's
          ``default_permission`` argument, or if
          :meth:`pyramid.config.Configurator.set_default_permission` was used
          prior to this view registration.  Pass the value
          :data:`pyramid.security.NO_PERMISSION_REQUIRED` as the permission
          argument to explicitly indicate that the view should always be
          executable by entirely anonymous users, regardless of the default
          permission, bypassing any :term:`authorization policy` that may be
          in effect.

        attr

          This knob is most useful when the view definition is a class.

          The view machinery defaults to using the ``__call__`` method
          of the :term:`view callable` (or the function itself, if the
          view callable is a function) to obtain a response.  The
          ``attr`` value allows you to vary the method attribute used
          to obtain the response.  For example, if your view was a
          class, and the class has a method named ``index`` and you
          wanted to use this method instead of the class' ``__call__``
          method to return the response, you'd say ``attr="index"`` in the
          view configuration for the view.

        renderer

          This is either a single string term (e.g. ``json``) or a
          string implying a path or :term:`asset specification`
          (e.g. ``templates/views.pt``) naming a :term:`renderer`
          implementation.  If the ``renderer`` value does not contain
          a dot ``.``, the specified string will be used to look up a
          renderer implementation, and that renderer implementation
          will be used to construct a response from the view return
          value.  If the ``renderer`` value contains a dot (``.``),
          the specified term will be treated as a path, and the
          filename extension of the last element in the path will be
          used to look up the renderer implementation, which will be
          passed the full path.  The renderer implementation will be
          used to construct a :term:`response` from the view return
          value.

          Note that if the view itself returns a :term:`response` (see
          :ref:`the_response`), the specified renderer implementation
          is never called.

          When the renderer is a path, although a path is usually just
          a simple relative pathname (e.g. ``templates/foo.pt``,
          implying that a template named "foo.pt" is in the
          "templates" directory relative to the directory of the
          current :term:`package` of the Configurator), a path can be
          absolute, starting with a slash on UNIX or a drive letter
          prefix on Windows.  The path can alternately be a
          :term:`asset specification` in the form
          ``some.dotted.package_name:relative/path``, making it
          possible to address template assets which live in a
          separate package.

          The ``renderer`` attribute is optional.  If it is not
          defined, the "null" renderer is assumed (no rendering is
          performed and the value is passed back to the upstream
          :app:`Pyramid` machinery unmodified).

        http_cache

          .. versionadded:: 1.1

          When you supply an ``http_cache`` value to a view configuration,
          the ``Expires`` and ``Cache-Control`` headers of a response
          generated by the associated view callable are modified.  The value
          for ``http_cache`` may be one of the following:

          - A nonzero integer.  If it's a nonzero integer, it's treated as a
            number of seconds.  This number of seconds will be used to
            compute the ``Expires`` header and the ``Cache-Control:
            max-age`` parameter of responses to requests which call this view.
            For example: ``http_cache=3600`` instructs the requesting browser
            to 'cache this response for an hour, please'.

          - A ``datetime.timedelta`` instance.  If it's a
            ``datetime.timedelta`` instance, it will be converted into a
            number of seconds, and that number of seconds will be used to
            compute the ``Expires`` header and the ``Cache-Control:
            max-age`` parameter of responses to requests which call this view.
            For example: ``http_cache=datetime.timedelta(days=1)`` instructs
            the requesting browser to 'cache this response for a day, please'.

          - Zero (``0``).  If the value is zero, the ``Cache-Control`` and
            ``Expires`` headers present in all responses from this view will
            be composed such that client browser cache (and any intermediate
            caches) are instructed to never cache the response.

          - A two-tuple.  If it's a two tuple (e.g. ``http_cache=(1,
            {'public':True})``), the first value in the tuple may be a
            nonzero integer or a ``datetime.timedelta`` instance; in either
            case this value will be used as the number of seconds to cache
            the response.  The second value in the tuple must be a
            dictionary.  The values present in the dictionary will be used as
            input to the ``Cache-Control`` response header.  For example:
            ``http_cache=(3600, {'public':True})`` means 'cache for an hour,
            and add ``public`` to the Cache-Control header of the response'.
            All keys and values supported by the
            ``webob.cachecontrol.CacheControl`` interface may be added to the
            dictionary.  Supplying ``{'public':True}`` is equivalent to
            calling ``response.cache_control.public = True``.

          Providing a non-tuple value as ``http_cache`` is equivalent to
          calling ``response.cache_expires(value)`` within your view's body.

          Providing a two-tuple value as ``http_cache`` is equivalent to
          calling ``response.cache_expires(value[0], **value[1])`` within your
          view's body.

          If you wish to avoid influencing, the ``Expires`` header, and
          instead wish to only influence ``Cache-Control`` headers, pass a
          tuple as ``http_cache`` with the first element of ``None``, e.g.:
          ``(None, {'public':True})``.

          If you wish to prevent a view that uses ``http_cache`` in its
          configuration from having its caching response headers changed by
          this machinery, set ``response.cache_control.prevent_auto = True``
          before returning the response from the view.  This effectively
          disables any HTTP caching done by ``http_cache`` for that response.

        wrapper

          The :term:`view name` of a different :term:`view
          configuration` which will receive the response body of this
          view as the ``request.wrapped_body`` attribute of its own
          :term:`request`, and the :term:`response` returned by this
          view as the ``request.wrapped_response`` attribute of its
          own request.  Using a wrapper makes it possible to "chain"
          views together to form a composite response.  The response
          of the outermost wrapper view will be returned to the user.
          The wrapper view will be found as any view is found: see
          :ref:`view_lookup`.  The "best" wrapper view will be found
          based on the lookup ordering: "under the hood" this wrapper
          view is looked up via
          ``pyramid.view.render_view_to_response(context, request,
          'wrapper_viewname')``. The context and request of a wrapper
          view is the same context and request of the inner view.  If
          this attribute is unspecified, no view wrapping is done.

        decorator

          A :term:`dotted Python name` to function (or the function itself,
          or an iterable of the aforementioned) which will be used to
          decorate the registered :term:`view callable`.  The decorator
          function(s) will be called with the view callable as a single
          argument.  The view callable it is passed will accept
          ``(context, request)``.  The decorator(s) must return a
          replacement view callable which also accepts ``(context,
          request)``.

          If decorator is an iterable, the callables will be combined and
          used in the order provided as a decorator.
          For example::

            @view_config(...,
                decorator=(decorator2,
                           decorator1))
            def myview(request):
                ....

          Is similar to doing::

            @view_config(...)
            @decorator2
            @decorator1
            def myview(request):
                ...

          Except with the existing benefits of ``decorator=`` (having a common
          decorator syntax for all view calling conventions and not having to
          think about preserving function attributes such as ``__name__`` and
          ``__module__`` within decorator logic).

          .. versionchanged:: 1.4a4
             Passing an iterable.

        mapper

          A Python object or :term:`dotted Python name` which refers to a
          :term:`view mapper`, or ``None``.  By default it is ``None``, which
          indicates that the view should use the default view mapper.  This
          plug-point is useful for Pyramid extension developers, but it's not
          very useful for 'civilians' who are just developing stock Pyramid
          applications. Pay no attention to the man behind the curtain.

        Predicate Arguments

        name

          The :term:`view name`.  Read :ref:`traversal_chapter` to
          understand the concept of a view name.

        context

          An object or a :term:`dotted Python name` referring to an
          interface or class object that the :term:`context` must be
          an instance of, *or* the :term:`interface` that the
          :term:`context` must provide in order for this view to be
          found and called.  This predicate is true when the
          :term:`context` is an instance of the represented class or
          if the :term:`context` provides the represented interface;
          it is otherwise false.  This argument may also be provided
          to ``add_view`` as ``for_`` (an older, still-supported
          spelling).

        route_name

          This value must match the ``name`` of a :term:`route
          configuration` declaration (see :ref:`urldispatch_chapter`)
          that must match before this view will be called.

        request_type

          This value should be an :term:`interface` that the
          :term:`request` must provide in order for this view to be
          found and called.  This value exists only for backwards
          compatibility purposes.

        request_method

          This value can be one of the strings ``GET``, ``POST``, ``PUT``,
          ``DELETE``, or ``HEAD`` representing an HTTP ``REQUEST_METHOD``, or
          a tuple containing one or more of these strings.  A view
          declaration with this argument ensures that the view will only be
          called when the request's ``method`` attribute (aka the
          ``REQUEST_METHOD`` of the WSGI environment) string matches a
          supplied value.  Note that use of ``GET`` also implies that the
          view will respond to ``HEAD`` as of Pyramid 1.4.

          .. versionchanged:: 1.2
             The ability to pass a tuple of items as ``request_method``.
             Previous versions allowed only a string.

        request_param

          This value can be any string or any sequence of strings.  A view 
          declaration with this argument ensures that the view will only be 
          called when the :term:`request` has a key in the ``request.params``
          dictionary (an HTTP ``GET`` or ``POST`` variable) that has a
          name which matches the supplied value (if the value is a string)
          or values (if the value is a tuple).  If any value
          supplied has a ``=`` sign in it,
          e.g. ``request_param="foo=123"``, then the key (``foo``)
          must both exist in the ``request.params`` dictionary, *and*
          the value must match the right hand side of the expression
          (``123``) for the view to "match" the current request.

        match_param

          .. versionadded:: 1.2

          This value can be a string of the format "key=value" or a tuple
          containing one or more of these strings.

          A view declaration with this argument ensures that the view will
          only be called when the :term:`request` has key/value pairs in its
          :term:`matchdict` that equal those supplied in the predicate.
          e.g. ``match_param="action=edit" would require the ``action``
          parameter in the :term:`matchdict` match the right hand side of
          the expression (``edit``) for the view to "match" the current
          request.

          If the ``match_param`` is a tuple, every key/value pair must match
          for the predicate to pass.

        containment

          This value should be a Python class or :term:`interface` (or a
          :term:`dotted Python name`) that an object in the
          :term:`lineage` of the context must provide in order for this view
          to be found and called.  The nodes in your object graph must be
          "location-aware" to use this feature.  See
          :ref:`location_aware` for more information about
          location-awareness.

        xhr

          This value should be either ``True`` or ``False``.  If this
          value is specified and is ``True``, the :term:`request`
          must possess an ``HTTP_X_REQUESTED_WITH`` (aka
          ``X-Requested-With``) header that has the value
          ``XMLHttpRequest`` for this view to be found and called.
          This is useful for detecting AJAX requests issued from
          jQuery, Prototype and other Javascript libraries.

        accept

          The value of this argument represents a match query for one
          or more mimetypes in the ``Accept`` HTTP request header.  If
          this value is specified, it must be in one of the following
          forms: a mimetype match token in the form ``text/plain``, a
          wildcard mimetype match token in the form ``text/*`` or a
          match-all wildcard mimetype match token in the form ``*/*``.
          If any of the forms matches the ``Accept`` header of the
          request, this predicate will be true.

        header

          This value represents an HTTP header name or a header
          name/value pair.  If the value contains a ``:`` (colon), it
          will be considered a name/value pair
          (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``).  The
          value portion should be a regular expression.  If the value
          does not contain a colon, the entire value will be
          considered to be the header name
          (e.g. ``If-Modified-Since``).  If the value evaluates to a
          header name only without a value, the header specified by
          the name must be present in the request for this predicate
          to be true.  If the value evaluates to a header name/value
          pair, the header specified by the name must be present in
          the request *and* the regular expression specified as the
          value must match the header value.  Whether or not the value
          represents a header name or a header name/value pair, the
          case of the header name is not significant.

        path_info

          This value represents a regular expression pattern that will
          be tested against the ``PATH_INFO`` WSGI environment
          variable.  If the regex matches, this predicate will be
          ``True``.

        check_csrf

          If specified, this value should be one of ``None``, ``True``,
          ``False``, or a string representing the 'check name'.  If the value
          is ``True`` or a string, CSRF checking will be performed.  If the
          value is ``False`` or ``None``, CSRF checking will not be performed.

          If the value provided is a string, that string will be used as the
          'check name'.  If the value provided is ``True``, ``csrf_token`` will
          be used as the check name.

          If CSRF checking is performed, the checked value will be the value
          of ``request.params[check_name]``.  This value will be compared
          against the value of ``request.session.get_csrf_token()``, and the
          check will pass if these two values are the same.  If the check
          passes, the associated view will be permitted to execute.  If the
          check fails, the associated view will not be permitted to execute.

          Note that using this feature requires a :term:`session factory` to
          have been configured.
         
          .. versionadded:: 1.4a2

        physical_path

          If specified, this value should be a string or a tuple representing
          the :term:`physical path` of the context found via traversal for this
          predicate to match as true.  For example: ``physical_path='/'`` or
          ``physical_path='/a/b/c'`` or ``physical_path=('', 'a', 'b', 'c')``.
          This is not a path prefix match or a regex, it's a whole-path match.
          It's useful when you want to always potentially show a view when some
          object is traversed to, but you can't be sure about what kind of
          object it will be, so you can't use the ``context`` predicate.  The
          individual path elements inbetween slash characters or in tuple
          elements should be the Unicode representation of the name of the
          resource and should not be encoded in any way.

          .. versionadded:: 1.4a3

        effective_principals

          If specified, this value should be a :term:`principal` identifier or
          a sequence of principal identifiers.  If the
          :func:`pyramid.security.effective_principals` method indicates that
          every principal named in the argument list is present in the current
          request, this predicate will return True; otherwise it will return
          False.  For example:
          ``effective_principals=pyramid.security.Authenticated`` or
          ``effective_principals=('fred', 'group:admins')``.

          .. versionadded:: 1.4a4

        custom_predicates

          .. deprecated:: 1.5

          This value should be a sequence of references to custom predicate
          callables.  Use custom predicates when no set of predefined
          predicates do what you need.  Custom predicates can be combined with
          predefined predicates as necessary.  Each custom predicate callable
          should accept two arguments: ``context`` and ``request`` and should
          return either ``True`` or ``False`` after doing arbitrary evaluation
          of the context and/or the request.  The ``predicates`` argument to
          this method and the ability to register third-party view predicates
          via :meth:`pyramid.config.Configurator.add_view_predicate` obsoletes
          this argument, but it is kept around for backwards compatibility.

        predicates

          Pass a key/value pair here to use a third-party predicate
          registered via
          :meth:`pyramid.config.Configurator.add_view_predicate`.  More than
          one key/value pair can be used at the same time.  See
          :ref:`view_and_route_predicates` for more information about
          third-party predicates.

          .. versionadded: 1.4a1

        """
        if custom_predicates:
            warnings.warn(
                ('The "custom_predicates" argument to Configurator.add_view '
                 'is deprecated as of Pyramid 1.5.  Use '
                 '"config.add_view_predicate" and use the registered '
                 'view predicate as a predicate argument to add_view instead. '
                 'See "Adding A Third Party View, Route, or Subscriber '
                 'Predicate" in the "Hooks" chapter of the documentation '
                 'for more information.'),
                DeprecationWarning,
                stacklevel=4
                )
        
        view = self.maybe_dotted(view)
        context = self.maybe_dotted(context)
        for_ = self.maybe_dotted(for_)
        containment = self.maybe_dotted(containment)
        mapper = self.maybe_dotted(mapper)

        def combine(*decorators):
            def decorated(view_callable):
                # reversed() is allows a more natural ordering in the api
                for decorator in reversed(decorators):
                    view_callable = decorator(view_callable)
                return view_callable
            return decorated

        if is_nonstr_iter(decorator):
            decorator = combine(*map(self.maybe_dotted, decorator))
        else:
            decorator = self.maybe_dotted(decorator)

        if not view:
            if renderer:
                def view(context, request):
                    return {}
            else:
                raise ConfigurationError('"view" was not specified and '
                                         'no "renderer" specified')

        if request_type is not None:
            request_type = self.maybe_dotted(request_type)
            if not IInterface.providedBy(request_type):
                raise ConfigurationError(
                    'request_type must be an interface, not %s' % request_type)

        if context is None:
            context = for_

        r_context = context
        if r_context is None:
            r_context = Interface
        if not IInterface.providedBy(r_context):
            r_context = implementedBy(r_context)

        if isinstance(renderer, string_types):
            renderer = renderers.RendererHelper(
                name=renderer, package=self.package,
                registry = self.registry)

        if accept is not None:
            accept = accept.lower()

        introspectables = []
        pvals = predicates.copy()
        pvals.update(
            dict(
                xhr=xhr,
                request_method=request_method,
                path_info=path_info,
                request_param=request_param,
                header=header,
                accept=accept,
                containment=containment,
                request_type=request_type,
                match_param=match_param,
                check_csrf=check_csrf,
                custom=predvalseq(custom_predicates),
                )
            )

        def discrim_func():
            # We need to defer the discriminator until we know what the phash
            # is.  It can't be computed any sooner because thirdparty
            # predicates may not yet exist when add_view is called.
            order, preds, phash = predlist.make(self, **pvals)
            view_intr.update({'phash':phash, 'order':order, 'predicates':preds})
            return ('view', context, name, route_name, phash)

        discriminator = Deferred(discrim_func)

        if inspect.isclass(view) and attr:
            view_desc = 'method %r of %s' % (
                attr, self.object_description(view))
        else:
            view_desc = self.object_description(view)

        tmpl_intr = None
            
        view_intr = self.introspectable('views',
                                        discriminator,
                                        view_desc,
                                        'view')
        view_intr.update(
            dict(name=name,
                 context=context,
                 containment=containment,
                 request_param=request_param,
                 request_methods=request_method,
                 route_name=route_name,
                 attr=attr,
                 xhr=xhr,
                 accept=accept,
                 header=header,
                 path_info=path_info,
                 match_param=match_param,
                 check_csrf=check_csrf,
                 callable=view,
                 mapper=mapper,
                 decorator=decorator,
                 )
            )
        view_intr.update(**predicates)
        introspectables.append(view_intr)
        predlist = self.get_predlist('view')

        def register(permission=permission, renderer=renderer):
            # the discrim_func above is guaranteed to have been called already
            order = view_intr['order']
            preds = view_intr['predicates']
            phash = view_intr['phash']
            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 (reg'd in phase 1)
                if self.registry.queryUtility(IRendererFactory) is not None:
                    renderer = renderers.RendererHelper(
                        name=None,
                        package=self.package,
                        registry=self.registry
                        )

            if permission is None:
                # intent: will be None if no default permission is registered
                # (reg'd in phase 1)
                permission = self.registry.queryUtility(IDefaultPermission)

            # added by discrim_func above during conflict resolving
            preds = view_intr['predicates']
            order = view_intr['order']
            phash = view_intr['phash']

            # __no_permission_required__ handled by _secure_view
            deriver = ViewDeriver(
                registry=self.registry,
                permission=permission,
                predicates=preds,
                attr=attr,
                renderer=renderer,
                wrapper_viewname=wrapper,
                viewname=name,
                accept=accept,
                order=order,
                phash=phash,
                package=self.package,
                mapper=mapper,
                decorator=decorator,
                http_cache=http_cache,
                )
            derived_view = deriver(view)
            derived_view.__discriminator__ = lambda *arg: discriminator
            # __discriminator__ is used by superdynamic systems
            # that require it for introspection after manual view lookup;
            # see also MultiView.__discriminator__
            view_intr['derived_callable'] = derived_view

            registered = self.registry.adapters.registered

            # A multiviews is a set of views which are registered for
            # exactly the same context type/request type/name triad.  Each
            # consituent view in a multiview differs only by the
            # predicates which it possesses.

            # To find a previously registered view for a context
            # type/request type/name triad, we need to use the
            # ``registered`` method of the adapter registry rather than
            # ``lookup``.  ``registered`` ignores interface inheritance
            # for the required and provided arguments, returning only a
            # view registered previously with the *exact* triad we pass
            # in.

            # We need to do this three times, because we use three
            # different interfaces as the ``provided`` interface while
            # doing registrations, and ``registered`` performs exact
            # matches on all the arguments it receives.

            old_view = None

            for view_type in (IView, ISecuredView, IMultiView):
                old_view = registered((IViewClassifier, request_iface,
                                       r_context), view_type, name)
                if old_view is not None:
                    break

            isexc = isexception(context)

            def regclosure():
                if hasattr(derived_view, '__call_permissive__'):
                    view_iface = ISecuredView
                else:
                    view_iface = IView
                self.registry.registerAdapter(
                    derived_view,
                    (IViewClassifier, request_iface, context), view_iface, name
                    )
                if isexc:
                    self.registry.registerAdapter(
                        derived_view,
                        (IExceptionViewClassifier, request_iface, context),
                        view_iface, name)

            is_multiview = IMultiView.providedBy(old_view)
            old_phash = getattr(old_view, '__phash__', DEFAULT_PHASH)

            if old_view is None:
                # - No component was yet registered for any of our I*View
                #   interfaces exactly; this is the first view for this
                #   triad.
                regclosure()

            elif (not is_multiview) and (old_phash == phash):
                # - A single view component was previously registered with
                #   the same predicate hash as this view; this registration
                #   is therefore an override.
                regclosure()

            else:
                # - A view or multiview was already registered for this
                #   triad, and the new view is not an override.

                # XXX we could try to be more efficient here and register
                # a non-secured view for a multiview if none of the
                # multiview's consituent views have a permission
                # associated with them, but this code is getting pretty
                # rough already
                if is_multiview:
                    multiview = old_view
                else:
                    multiview = MultiView(name)
                    old_accept = getattr(old_view, '__accept__', None)
                    old_order = getattr(old_view, '__order__', MAX_ORDER)
                    multiview.add(old_view, old_order, old_accept, old_phash)
                multiview.add(derived_view, order, accept, phash)
                for view_type in (IView, ISecuredView):
                    # unregister any existing views
                    self.registry.adapters.unregister(
                        (IViewClassifier, request_iface, r_context),
                        view_type, name=name)
                    if isexc:
                        self.registry.adapters.unregister(
                            (IExceptionViewClassifier, request_iface,
                             r_context), view_type, name=name)
                self.registry.registerAdapter(
                    multiview,
                    (IViewClassifier, request_iface, context),
                    IMultiView, name=name)
                if isexc:
                    self.registry.registerAdapter(
                        multiview,
                        (IExceptionViewClassifier, request_iface, context),
                        IMultiView, name=name)
            renderer_type = getattr(renderer, 'type', None) # gard against None
            intrspc = self.introspector
            if (
                renderer_type is not None and
                tmpl_intr is not None and
                intrspc is not None and
                intrspc.get('renderer factories', renderer_type) is not None
                ):
                # allow failure of registered template factories to be deferred
                # until view execution, like other bad renderer factories; if
                # we tried to relate this to an existing renderer factory
                # without checking if it the factory actually existed, we'd end
                # up with a KeyError at startup time, which is inconsistent
                # with how other bad renderer registrations behave (they throw
                # a ValueError at view execution time)
                tmpl_intr.relate('renderer factories', renderer.type)

        if mapper:
            mapper_intr = self.introspectable(
                'view mappers',
                discriminator,
                'view mapper for %s' % view_desc,
                'view mapper'
                )
            mapper_intr['mapper'] = mapper
            mapper_intr.relate('views', discriminator)
            introspectables.append(mapper_intr)
        if route_name:
            view_intr.relate('routes', route_name) # see add_route
        if renderer is not None and renderer.name and '.' in renderer.name:
            # the renderer is a template
            tmpl_intr = self.introspectable(
                'templates',
                discriminator,
                renderer.name,
                'template'
                )
            tmpl_intr.relate('views', discriminator)
            tmpl_intr['name'] = renderer.name
            tmpl_intr['type'] = renderer.type
            tmpl_intr['renderer'] = renderer
            introspectables.append(tmpl_intr)
        if permission is not None:
            # if a permission exists, register a permission introspectable
            perm_intr = self.introspectable(
                'permissions',
                permission,
                permission,
                'permission'
                )
            perm_intr['value'] = permission
            perm_intr.relate('views', discriminator)
            introspectables.append(perm_intr)
        self.action(discriminator, register, introspectables=introspectables)

    @action_method
    def add_view_predicate(self, name, factory, weighs_more_than=None,
                           weighs_less_than=None):
        """
        .. versionadded:: 1.4

        Adds a view predicate factory.  The associated view predicate can
        later be named as a keyword argument to
        :meth:`pyramid.config.Configurator.add_view` in the
        ``predicates`` anonyous keyword argument dictionary.

        ``name`` should be the name of the predicate.  It must be a valid
        Python identifier (it will be used as a keyword argument to
        ``add_view`` by others).

        ``factory`` should be a :term:`predicate factory` or :term:`dotted
        Python name` which refers to a predicate factory.

        See :ref:`view_and_route_predicates` for more information.
        """
        self._add_predicate(
            'view',
            name,
            factory,
            weighs_more_than=weighs_more_than,
            weighs_less_than=weighs_less_than
            )

    def add_default_view_predicates(self):
        p = pyramid.config.predicates
        for (name, factory) in (
            ('xhr', p.XHRPredicate),
            ('request_method', p.RequestMethodPredicate),
            ('path_info', p.PathInfoPredicate),
            ('request_param', p.RequestParamPredicate),
            ('header', p.HeaderPredicate),
            ('accept', p.AcceptPredicate),
            ('containment', p.ContainmentPredicate),
            ('request_type', p.RequestTypePredicate),
            ('match_param', p.MatchParamPredicate),
            ('check_csrf', p.CheckCSRFTokenPredicate),
            ('physical_path', p.PhysicalPathPredicate),
            ('effective_principals', p.EffectivePrincipalsPredicate),
            ('custom', p.CustomPredicate),
            ):
            self.add_view_predicate(name, factory)

    def derive_view(self, view, attr=None, renderer=None):
        """
        Create a :term:`view callable` using the function, instance,
        or class (or :term:`dotted Python name` referring to the same)
        provided as ``view`` object.

        .. warning::

           This method is typically only used by :app:`Pyramid` framework
           extension authors, not by :app:`Pyramid` application developers.

        This is API is useful to framework extenders who create
        pluggable systems which need to register 'proxy' view
        callables for functions, instances, or classes which meet the
        requirements of being a :app:`Pyramid` view callable.  For
        example, a ``some_other_framework`` function in another
        framework may want to allow a user to supply a view callable,
        but he may want to wrap the view callable in his own before
        registering the wrapper as a :app:`Pyramid` view callable.
        Because a :app:`Pyramid` view callable can be any of a
        number of valid objects, the framework extender will not know
        how to call the user-supplied object.  Running it through
        ``derive_view`` normalizes it to a callable which accepts two
        arguments: ``context`` and ``request``.

        For example:

        .. code-block:: python

           def some_other_framework(user_supplied_view):
               config = Configurator(reg)
               proxy_view = config.derive_view(user_supplied_view)
               def my_wrapper(context, request):
                   do_something_that_mutates(request)
                   return proxy_view(context, request)
               config.add_view(my_wrapper)

        The ``view`` object provided should be one of the following:

        - A function or another non-class callable object that accepts
          a :term:`request` as a single positional argument and which
          returns a :term:`response` object.

        - A function or other non-class callable object that accepts
          two positional arguments, ``context, request`` and which
          returns a :term:`response` object.

        - A class which accepts a single positional argument in its
          constructor named ``request``, and which has a ``__call__``
          method that accepts no arguments that returns a
          :term:`response` object.

        - A class which accepts two positional arguments named
          ``context, request``, and which has a ``__call__`` method
          that accepts no arguments that returns a :term:`response`
          object.

        - A :term:`dotted Python name` which refers to any of the
          kinds of objects above.

        This API returns a callable which accepts the arguments
        ``context, request`` and which returns the result of calling
        the provided ``view`` object.

        The ``attr`` keyword argument is most useful when the view
        object is a class.  It names the method that should be used as
        the callable.  If ``attr`` is not provided, the attribute
        effectively defaults to ``__call__``.  See
        :ref:`class_as_view` for more information.

        The ``renderer`` keyword argument should be a renderer
        name. If supplied, it will cause the returned callable to use
        a :term:`renderer` to convert the user-supplied view result to
        a :term:`response` object.  If a ``renderer`` argument is not
        supplied, the user-supplied view must itself return a
        :term:`response` object.  """
        return self._derive_view(view, attr=attr, renderer=renderer)

    # b/w compat
    def _derive_view(self, view, permission=None, predicates=(),
                     attr=None, renderer=None, wrapper_viewname=None,
                     viewname=None, accept=None, order=MAX_ORDER,
                     phash=DEFAULT_PHASH, decorator=None,
                     mapper=None, http_cache=None):
        view = self.maybe_dotted(view)
        mapper = self.maybe_dotted(mapper)
        if isinstance(renderer, string_types):
            renderer = renderers.RendererHelper(
                name=renderer, package=self.package,
                registry = self.registry)
        if renderer is None:
            # use default renderer if one exists
            if self.registry.queryUtility(IRendererFactory) is not None:
                renderer = renderers.RendererHelper(
                    name=None,
                    package=self.package,
                    registry=self.registry)

        deriver = ViewDeriver(registry=self.registry,
                              permission=permission,
                              predicates=predicates,
                              attr=attr,
                              renderer=renderer,
                              wrapper_viewname=wrapper_viewname,
                              viewname=viewname,
                              accept=accept,
                              order=order,
                              phash=phash,
                              package=self.package,
                              mapper=mapper,
                              decorator=decorator,
                              http_cache=http_cache)

        return deriver(view)

    @action_method
    def add_forbidden_view(
        self,
        view=None,
        attr=None,
        renderer=None,
        wrapper=None,
        route_name=None,
        request_type=None,
        request_method=None, 
        request_param=None,
        containment=None,
        xhr=None,
        accept=None,
        header=None,
        path_info=None,
        custom_predicates=(),
        decorator=None,
        mapper=None,
        match_param=None,
        **predicates
        ):
        """ Add a forbidden view to the current configuration state.  The
        view will be called when Pyramid or application code raises a
        :exc:`pyramid.httpexceptions.HTTPForbidden` exception and the set of
        circumstances implied by the predicates provided are matched.  The
        simplest example is:

          .. code-block:: python

            def forbidden(request):
                return Response('Forbidden', status='403 Forbidden')

            config.add_forbidden_view(forbidden)

        All arguments have the same meaning as
        :meth:`pyramid.config.Configurator.add_view` and each predicate
        argument restricts the set of circumstances under which this notfound
        view will be invoked.  Unlike
        :meth:`pyramid.config.Configurator.add_view`, this method will raise
        an exception if passed ``name``, ``permission``, ``context``,
        ``for_``, or ``http_cache`` keyword arguments.  These argument values
        make no sense in the context of a forbidden view.

        .. versionadded:: 1.3
        """
        for arg in ('name', 'permission', 'context', 'for_', 'http_cache'):
            if arg in predicates:
                raise ConfigurationError(
                    '%s may not be used as an argument to add_forbidden_view'
                    % arg
                    )
        
        settings = dict(
            view=view,
            context=HTTPForbidden,
            wrapper=wrapper,
            request_type=request_type,
            request_method=request_method,
            request_param=request_param,
            containment=containment,
            xhr=xhr,
            accept=accept,
            header=header, 
            path_info=path_info,
            custom_predicates=custom_predicates,
            decorator=decorator,
            mapper=mapper,
            match_param=match_param,
            route_name=route_name,
            permission=NO_PERMISSION_REQUIRED,
            attr=attr,
            renderer=renderer,
            )
        settings.update(predicates)
        return self.add_view(**settings)

    set_forbidden_view = add_forbidden_view # deprecated sorta-bw-compat alias
    
    @action_method
    def add_notfound_view(
        self,
        view=None,
        attr=None,
        renderer=None,
        wrapper=None,
        route_name=None,
        request_type=None,
        request_method=None, 
        request_param=None,
        containment=None,
        xhr=None,
        accept=None,
        header=None,
        path_info=None,
        custom_predicates=(),
        decorator=None,
        mapper=None,
        match_param=None,
        append_slash=False,
        **predicates
        ):
        """ Add a default Not Found View to the current configuration state.
        The view will be called when Pyramid or application code raises an
        :exc:`pyramid.httpexceptions.HTTPNotFound` exception (e.g. when a
        view cannot be found for the request).  The simplest example is:

          .. code-block:: python

            def notfound(request):
                return Response('Not Found', status='404 Not Found')

            config.add_notfound_view(notfound)

        All arguments except ``append_slash`` have the same meaning as
        :meth:`pyramid.config.Configurator.add_view` and each predicate
        argument restricts the set of circumstances under which this notfound
        view will be invoked.  Unlike
        :meth:`pyramid.config.Configurator.add_view`, this method will raise
        an exception if passed ``name``, ``permission``, ``context``,
        ``for_``, or ``http_cache`` keyword arguments.  These argument values
        make no sense in the context of a Not Found View.

        If ``append_slash`` is ``True``, when this Not Found View is invoked,
        and the current path info does not end in a slash, the notfound logic
        will attempt to find a :term:`route` that matches the request's path
        info suffixed with a slash.  If such a route exists, Pyramid will
        issue a redirect to the URL implied by the route; if it does not,
        Pyramid will return the result of the view callable provided as
        ``view``, as normal.

        .. versionadded:: 1.3
        """
        for arg in ('name', 'permission', 'context', 'for_', 'http_cache'):
            if arg in predicates:
                raise ConfigurationError(
                    '%s may not be used as an argument to add_notfound_view'
                    % arg
                    )
                    
        settings = dict(
            view=view,
            context=HTTPNotFound,
            wrapper=wrapper,
            request_type=request_type,
            request_method=request_method,
            request_param=request_param,
            containment=containment,
            xhr=xhr,
            accept=accept,
            header=header, 
            path_info=path_info,
            custom_predicates=custom_predicates,
            decorator=decorator,
            mapper=mapper,
            match_param=match_param,
            route_name=route_name,
            permission=NO_PERMISSION_REQUIRED,
            )
        settings.update(predicates)
        if append_slash:
            view = self._derive_view(view, attr=attr, renderer=renderer)
            view = AppendSlashNotFoundViewFactory(view)
            settings['view'] = view
        else:
            settings['attr'] = attr
            settings['renderer'] = renderer
        return self.add_view(**settings)

    set_notfound_view = add_notfound_view # deprecated sorta-bw-compat alias

    @action_method
    def set_view_mapper(self, mapper):
        """
        Setting a :term:`view mapper` makes it possible to make use of
        :term:`view callable` objects which implement different call
        signatures than the ones supported by :app:`Pyramid` as described in
        its narrative documentation.

        The ``mapper`` should argument be an object implementing
        :class:`pyramid.interfaces.IViewMapperFactory` or a :term:`dotted
        Python name` to such an object.  The provided ``mapper`` will become
        the default view mapper to be used by all subsequent :term:`view
        configuration` registrations.

        See also :ref:`using_a_view_mapper`.

        .. note::

           Using the ``default_view_mapper`` argument to the
           :class:`pyramid.config.Configurator` constructor
           can be used to achieve the same purpose.
        """
        mapper = self.maybe_dotted(mapper)
        def register():
            self.registry.registerUtility(mapper, IViewMapperFactory)
        # IViewMapperFactory is looked up as the result of view config
        # in phase 3
        intr = self.introspectable('view mappers',
                                   IViewMapperFactory,
                                   self.object_description(mapper),
                                   'default view mapper')
        intr['mapper'] = mapper
        self.action(IViewMapperFactory, register, order=PHASE1_CONFIG,
                    introspectables=(intr,))

    @action_method
    def add_static_view(self, name, path, **kw):
        """ Add a view used to render static assets such as images
        and CSS files.

        The ``name`` argument is a string representing an
        application-relative local URL prefix.  It may alternately be a full
        URL.

        The ``path`` argument is the path on disk where the static files
        reside.  This can be an absolute path, a package-relative path, or a
        :term:`asset specification`.

        The ``cache_max_age`` keyword argument is input to set the
        ``Expires`` and ``Cache-Control`` headers for static assets served.
        Note that this argument has no effect when the ``name`` is a *url
        prefix*.  By default, this argument is ``None``, meaning that no
        particular Expires or Cache-Control headers are set in the response.

        The ``permission`` keyword argument is used to specify the
        :term:`permission` required by a user to execute the static view.  By
        default, it is the string
        :data:`pyramid.security.NO_PERMISSION_REQUIRED`, a special sentinel
        which indicates that, even if a :term:`default permission` exists for
        the current application, the static view should be renderered to
        completely anonymous users.  This default value is permissive
        because, in most web apps, static assets seldom need protection from
        viewing.  If ``permission`` is specified, the security checking will
        be performed against the default root factory ACL.

        Any other keyword arguments sent to ``add_static_view`` are passed on
        to :meth:`pyramid.config.Configurator.add_route` (e.g. ``factory``,
        perhaps to define a custom factory with a custom ACL for this static
        view).

        *Usage*

        The ``add_static_view`` function is typically used in conjunction
        with the :meth:`pyramid.request.Request.static_url` method.
        ``add_static_view`` adds a view which renders a static asset when
        some URL is visited; :meth:`pyramid.request.Request.static_url`
        generates a URL to that asset.

        The ``name`` argument to ``add_static_view`` is usually a simple URL
        prefix (e.g. ``'images'``).  When this is the case, the
        :meth:`pyramid.request.Request.static_url` API will generate a URL
        which points to a Pyramid view, which will serve up a set of assets
        that live in the package itself. For example:

        .. code-block:: python

           add_static_view('images', 'mypackage:images/')

        Code that registers such a view can generate URLs to the view via
        :meth:`pyramid.request.Request.static_url`:

        .. code-block:: python

           request.static_url('mypackage:images/logo.png')

        When ``add_static_view`` is called with a ``name`` argument that
        represents a URL prefix, as it is above, subsequent calls to
        :meth:`pyramid.request.Request.static_url` with paths that start with
        the ``path`` argument passed to ``add_static_view`` will generate a
        URL something like ``http://<Pyramid app URL>/images/logo.png``,
        which will cause the ``logo.png`` file in the ``images`` subdirectory
        of the ``mypackage`` package to be served.

        ``add_static_view`` can alternately be used with a ``name`` argument
        which is a *URL*, causing static assets to be served from an external
        webserver.  This happens when the ``name`` argument is a fully
        qualified URL (e.g. starts with ``http://`` or similar).  In this
        mode, the ``name`` is used as the prefix of the full URL when
        generating a URL using :meth:`pyramid.request.Request.static_url`.
        Furthermore, if a protocol-relative URL (e.g. ``//example.com/images``)
        is used as the ``name`` argument, the generated URL will use the
        protocol of the request (http or https, respectively).

        For example, if ``add_static_view`` is called like so:

        .. code-block:: python

           add_static_view('http://example.com/images', 'mypackage:images/')

        Subsequently, the URLs generated by
        :meth:`pyramid.request.Request.static_url` for that static view will
        be prefixed with ``http://example.com/images`` (the external webserver
        listening on ``example.com`` must be itself configured to respond
        properly to such a request.):

        .. code-block:: python

           static_url('mypackage:images/logo.png', request)

        See :ref:`static_assets_section` for more information.
        """
        spec = self._make_spec(path)
        info = self.registry.queryUtility(IStaticURLInfo)
        if info is None:
            info = StaticURLInfo()
            self.registry.registerUtility(info, IStaticURLInfo)
        info.add(self, name, spec, **kw)

def isexception(o):
    if IInterface.providedBy(o):
        if IException.isEqualOrExtendedBy(o):
            return True
    return (
        isinstance(o, Exception) or
        (inspect.isclass(o) and (issubclass(o, Exception)))
        )


@implementer(IStaticURLInfo)
class StaticURLInfo(object):

    def _get_registrations(self, registry):
        try:
            reg = registry._static_url_registrations
        except AttributeError:
            reg = registry._static_url_registrations = []
        return reg

    def generate(self, path, request, **kw):
        try:
            registry = request.registry
        except AttributeError: # bw compat (for tests)
            registry = get_current_registry()
        for (url, spec, route_name) in self._get_registrations(registry):
            if path.startswith(spec):
                subpath = path[len(spec):]
                if WIN: # pragma: no cover
                    subpath = subpath.replace('\\', '/') # windows
                if url is None:
                    kw['subpath'] = subpath
                    return request.route_url(route_name, **kw)
                else:
                    parsed = url_parse(url)
                    if not parsed.scheme:
                        # parsed.scheme is readonly, so we have to parse again
                        # to change the scheme, sigh.
                        url = urlparse.urlunparse(url_parse(
                            url, scheme=request.environ['wsgi.url_scheme']))
                    subpath = url_quote(subpath)
                    return urljoin(url, subpath)

        raise ValueError('No static URL definition matching %s' % path)

    def add(self, config, name, spec, **extra):
        # This feature only allows for the serving of a directory and
        # the files contained within, not of a single asset;
        # appending a slash here if the spec doesn't have one is
        # required for proper prefix matching done in ``generate``
        # (``subpath = path[len(spec):]``).
        if os.path.isabs(spec): # FBO windows
            sep = os.sep
        else:
            sep = '/'
        if not spec.endswith(sep):
            spec = spec + sep

        # we also make sure the name ends with a slash, purely as a
        # convenience: a name that is a url is required to end in a
        # slash, so that ``urljoin(name, subpath))`` will work above
        # when the name is a URL, and it doesn't hurt things for it to
        # have a name that ends in a slash if it's used as a route
        # name instead of a URL.
        if not name.endswith('/'):
            # make sure it ends with a slash
            name = name + '/'

        if url_parse(name).netloc:
            # it's a URL
            # url, spec, route_name
            url = name
            route_name = None
        else:
            # it's a view name
            url = None
            cache_max_age = extra.pop('cache_max_age', None)
            # create a view
            view = static_view(spec, cache_max_age=cache_max_age,
                               use_subpath=True)

            # Mutate extra to allow factory, etc to be passed through here.
            # Treat permission specially because we'd like to default to
            # permissiveness (see docs of config.add_static_view).
            permission = extra.pop('permission', None)
            if permission is None:
                permission = NO_PERMISSION_REQUIRED

            context = extra.pop('context', None)
            if context is None:
                context = extra.pop('for_', None)

            renderer = extra.pop('renderer', None)

            # register a route using the computed view, permission, and
            # pattern, plus any extras passed to us via add_static_view
            pattern = "%s*subpath" % name # name already ends with slash
            if config.route_prefix:
                route_name = '__%s/%s' % (config.route_prefix, name)
            else:
                route_name = '__%s' % name
            config.add_route(route_name, pattern, **extra)
            config.add_view(
                route_name=route_name,
                view=view,
                permission=permission,
                context=context,
                renderer=renderer,
                )

        def register():
            registrations = self._get_registrations(config.registry)

            names = [ t[0] for t in  registrations ]

            if name in names:
                idx = names.index(name)
                registrations.pop(idx)

            # url, spec, route_name
            registrations.append((url, spec, route_name))

        intr = config.introspectable('static views',
                                     name,
                                     'static view for %r' % name,
                                     'static view')
        intr['name'] = name
        intr['spec'] = spec

        config.action(None, callable=register, introspectables=(intr,))



```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
user